You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Anthony Schexnaildre <ap...@gmail.com> on 2007/09/09 10:37:36 UTC

Component parent null after replace

I am trying to create a link that will replace one panel with another  
on the page. This seems as though it should be an easy task but after  
many attempts and searching the net for examples I have yet to get it  
working so the replacement can happen more than one without the  
component becoming orphaned. On the second replace attempt i get the  
following exception. Anyone have the solution?

Thank you,

Anthony


java.lang.IllegalStateException: This method can only be called on a  
component that has already been added to its parent.
      at org.apache.wicket.Component.replaceWith(Component.java:2266)
      at com.pinwise.pinbase.web.components.links.SecurePanelLink 
$4.onClick(SecurePanelLink.java:142)
      at org.apache.wicket.markup.html.link.Link.onLinkClicked 
(Link.java:222)
      at java.lang.reflect.Method.invoke(Method.java:585)
      at org.apache.wicket.RequestListenerInterface.invoke 
(RequestListenerInterface.java:186)


=====================================

=====================================

	public UserPanel(String id) {
		super(id);

		
		UserFormPanel userFormPanel = new UserFormPanel("userFormPanel");
		add( userFormPanel );
		
		List<IColumn> columns = new ArrayList<IColumn>();
		final Model m = new Model(userFormPanel);
         columns.add(new PropertyColumn(new Model("Actions"), "id")
         {
			public void populateItem(Item cellItem, String componentId, final  
IModel model)
             {
				EditActionPanel panel = new EditActionPanel(componentId, model);
				panel.add( SecurePanelLink.createSecurePanelLink( "edit", m,  
UserFormPanel.class, model ) );
               cellItem.add( panel );
             }
         });

         columns.add(new PropertyColumn(new Model("Username"),  
"username", "username"));
         columns.add(new PropertyColumn(new Model("First Name"),  
"firstName", "firstName"));
         columns.add(new PropertyColumn(new Model("Last Name"),  
"lastName", "lastName"));

         add(new DefaultDataTable("table", columns, new  
SortableUserDataProvider(), 10));
	}


====================================
SecurePanelLink
====================================
public class SecurePanelLink extends Link implements ISecureComponent {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	protected IPanelLink panelLink;
	
	/**
	 * @param id
	 * @param c
	 */
	public SecurePanelLink(String id, final Class c)
	{
		super(id);
		// Ensure that c is a subclass of Panel
		if (!Panel.class.isAssignableFrom(c))
		{
			throw new IllegalArgumentException("Class " + c + " is not a  
subclass of Panel");
		}

		this.panelLink = createIPanelLink( id, c );
		setSecurityCheck(new LinkSecurityCheck(this, c));
	}
	
	public SecurePanelLink(String id, final Class c, Model existingPanel)
	{
		super(id);
		// Ensure that c is a subclass of Panel
		if (!Panel.class.isAssignableFrom(c))
		{
			throw new IllegalArgumentException("Class " + c + " is not a  
subclass of Panel");
		}

		this.panelLink = createIPanelLink( id, c );
		setSecurityCheck(new LinkSecurityCheck(this, c));
	}
	
	private IPanelLink createIPanelLink( String id, final Class c ) {
		return new IPanelLink()
		{
			private static final long serialVersionUID = 1L;

			public Panel getPanel( String id )
			{
				// Create panel using panel factory
				return getPanelFactory().newPanel(id, c );
			}
			
			public Panel getPanel( String id, IModel model)
			{
				// Create panel using panel factory
				return getPanelFactory().newPanel(id, c, model);
			}
			
			public Panel getPanel( Panel panel, IModel model)
			{
				// Create panel using panel factory
				return getPanelFactory().newPanel(panel.getId(), c, model);
			}

			public Class getPanelIdentity()
			{
				return c;
			}
		};
	}
	
	/**
	 *
	 */
	public static SecurePanelLink createSecurePanelLink( String id,  
Class clazz ) {
		return new SecurePanelLink( id, clazz ) {
			/**
			 *
			 */
			private static final long serialVersionUID = 1L;

			public void onClick() {
				Panel panel = ((Panel)findParent(Panel.class));
				panel.replaceWith( panelLink.getPanel( panel.getId() ) );
			}
		};
	}
	
	/**
	 *
	 */
	public static SecurePanelLink createSecurePanelLink( String id,  
Class newPanel, final IModel model ) {
		return new SecurePanelLink( id, newPanel ) {
			/**
			 *
			 */
			private static final long serialVersionUID = 1L;

			public void onClick() {
				Panel panel = ((Panel)findParent(Panel.class));
				panel.replaceWith( panelLink.getPanel( panel.getId(), model ) );
			}
		};
	}
	
	/**
	 *
	 */
	public static SecurePanelLink createSecurePanelLink( String id,  
final Model existingPanel, Class newPanel, final IModel model ) {
		return new SecurePanelLink( id, newPanel, existingPanel ) {
			/**
			 *
			 */
			private static final long serialVersionUID = 1L;
			

			public void onClick() {
				Panel p = (Panel)existingPanel.getObject();
				Panel panel = panelLink.getPanel((Panel)existingPanel.getObject 
(), model );
				panel.setOutputMarkupId(true);
				p.getParent().replace( panel );
				p=panel;
			}
		};
	}

Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Maurice Marrink <ma...@gmail.com>.
I realize i did not give any directions about how to use this class
but i was hoping the javadoc would speak for itself. Anyway the
getReplacementFor is a factory method for creating the panel that will
replace the current panel. Looking at your original class i think it
should do something like

protected MarkupContainer getReplacementFor(Component current, String id,
			Class replacementClass)
{
return getPanelFactory().newPanel(id, replacementClass,current.getModel());
//not sure where getPanelFactory is accessible from, but you get the drift.
}

This will cause a onetime replacement of the panel, any next click
will just replace the panel again with a new instance of the same
class.
If you do not want any further clicks on the link you could do a
setVisible(false); to hide the link.
Or if you want the link to alternate between these two panels (or any
number really) you could do this
protected MarkupContainer getReplacementFor(Component current, String id,
			Class replacementClass)
{
setReplacementClass(current.getClass());
return getPanelFactory().newPanel(id, replacementClass,current.getModel());
}

Note that in this last example you need to grant permission for all
the panelclasses you want to alternate between or the link will
disappear.

Also the link does not care about permissions for the currently
showing panel, the panel itself should do that, but only about the
panel you are going to replace it with.

I hope this clarifies things enough.

Keep me posted.

Maurice


On 9/12/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
> Sitting down with the SecureContainerLink now. I may be slow but I am
> a little confused by it's intended use. I am not sure what the
> implementation of getReplacementFor(.....) is meant to look like.
>
> -Anthony
>
> On Sep 11, 2007, at 11:24 PM, Maurice Marrink wrote:
>
> > Ok, i just finished a SecureContainerLink that should do what your
> > SecurePanelLink does, but it is a bit less complex. I haven't checked
> > it in yet or tested it for that matter but hope to hear from you if
> > this is what you meant. If so i will make it a part of wasp.
> >
> > Maurice
> >
> > /*
> >  * 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.security.components.markup.html.links;
> >
> > import org.apache.wicket.Component;
> > import org.apache.wicket.MarkupContainer;
> > import org.apache.wicket.WicketRuntimeException;
> > import org.apache.wicket.markup.html.link.Link;
> > import org.apache.wicket.model.IModel;
> > import org.apache.wicket.security.actions.AbstractWaspAction;
> > import org.apache.wicket.security.checks.ISecurityCheck;
> > import org.apache.wicket.security.checks.LinkSecurityCheck;
> > import org.apache.wicket.security.components.ISecureComponent;
> > import org.apache.wicket.security.components.SecureComponentHelper;
> >
> > /**
> >  * A secure link to handle panel replacements or any other type of
> >  * {@link MarkupContainer}s. It is also usable as a link to switch
> > between 2 or
> >  * more panels. Security is enforced on the replacing class.
> >  *
> >  * @author marrink
> >  */
> > public abstract class SecureContainerLink extends Link implements
> > ISecureComponent
> > {
> >       /**
> >        *
> >        */
> >       private static final long serialVersionUID = 1L;
> >
> >       private Class replacementClass;
> >       private MarkupContainer containerParent;
> >       private String containerId;
> >
> >       /**
> >        * Constructs a new replacement link.
> >        *
> >        * @param id
> >        *            id of the link
> >        * @param replacementPanel
> >        *            the class of the container replacing the component
> > on the
> >        *            supplied parent
> >        * @param parentOfReplaceablePanel
> >        *            the parent component where the replacement needs to
> > take place
> >        * @param panelId
> >        *            the id of the component to be replaced
> >        */
> >       public SecureContainerLink(String id, Class replacementPanel,
> >                       MarkupContainer parentOfReplaceablePanel, String panelId)
> >       {
> >               this(id, null, replacementPanel, parentOfReplaceablePanel, panelId);
> >
> >       }
> >
> >       /**
> >        * Constructs a new replacement link.
> >        *
> >        * @param id
> >        *            id of the link
> >        * @param object
> >        *            model of the link
> >        * @param replacementPanel
> >        *            the class of the container replacing the component
> > on the
> >        *            supplied parent
> >        * @param parentOfReplaceablePanel
> >        *            the parent component where the replacement needs to
> > take place
> >        * @param panelId
> >        *            the id of the component to be replaced
> >        */
> >       public SecureContainerLink(String id, IModel object, Class
> > replacementPanel,
> >                       MarkupContainer parentOfReplaceablePanel, String panelId)
> >       {
> >               super(id, object);
> >               setReplacementClass(replacementPanel);
> >               if (parentOfReplaceablePanel == null)
> >                       throw new WicketRuntimeException("Parent required for replacing
> > components.");
> >               containerParent = parentOfReplaceablePanel;
> >               if (panelId == null)
> >                       throw new WicketRuntimeException("Id required from component to be
> > replaced.");
> >               containerId = panelId;
> >       }
> >
> >       /**
> >        * Performs the replacement, only if an actual replacement was
> > constructed.
> >        *
> >        * @see org.apache.wicket.markup.html.link.Link#onClick()
> >        * @see #getReplacementFor(Component, String, Class)
> >        * @throws WicketRuntimeException
> >        *             if a problem occurs in replacing the container.
> >        */
> >       public final void onClick()
> >       {
> >               Component replaceMe = containerParent.get(containerId);
> >               if (replaceMe == null)
> >                       throw new WicketRuntimeException("unable to find child with id: " +
> > containerId
> >                                       + " on parent: " + containerParent);
> >               Class myReplacementClass = getReplacementClass();
> >               MarkupContainer replacement = getReplacementFor(replaceMe,
> > containerId, myReplacementClass);
> >               if (replacement == null)
> >                       return; // do nothing
> >               if (!containerId.equals(replacement.getId()))
> >                       throw new WicketRuntimeException("The replacement does not have the
> > specified id: "
> >                                       + containerId + ", but id: " + replacement.getId());
> >               if (myReplacementClass.isAssignableFrom(replacement.getClass()))
> >                       containerParent.replace(replacement);
> >               else
> >                       throw new WicketRuntimeException("The replacement for " +
> > containerId + " on "
> >                                       + containerParent + " is not assignable from " +
> > myReplacementClass);
> >
> >       }
> >
> >       /**
> >        * Creates a replacement for a component. although the component
> > to be
> >        * replaced does not need to be a {@link MarkupContainer} it
> > typically is.
> >        * The replacement however does need to be a MarkupContainer, more
> >        * specifically a (sub)class of replacementClass. Implementation
> > may choose
> >        * at this point to do the next replacement with a different class
> > by using
> >        * {@link #setReplacementClass(Class)} in order to create a switch
> > like
> >        * behavior.
> >        *
> >        * @param current
> >        *            the component to be replaced
> >        * @param id
> >        *            the id of the new container
> >        * @param replacementClass
> >        *            the class of the replacement
> >        * @return a new replacement or null if the original component is
> > not to be
> >        *         replaced
> >        * @see #setReplacementClass(Class)
> >        */
> >       protected abstract MarkupContainer getReplacementFor(Component
> > current, String id,
> >                       Class replacementClass);
> >
> >       /**
> >        * Generates the securitycheck for this link. by default this is a
> >        * {@link LinkSecurityCheck} but implementations may choose to
> > override
> >        * this. Note that the returned LinkSecurityCheck should not be
> > placed in
> >        * alternative rendering mode as this will completely change the
> > intended
> >        * behavior.
> >        *
> >        * @return the securitycheck for this link or null if no security
> > is to be
> >        *         enforced
> >        */
> >       protected ISecurityCheck generateSecurityCheck()
> >       {
> >               return new LinkSecurityCheck(this, getReplacementClass());
> >       }
> >
> >       /**
> >        * @see
> > org.apache.wicket.security.components.ISecureComponent#getSecurityChec
> > k()
> >        */
> >       public ISecurityCheck getSecurityCheck()
> >       {
> >               return SecureComponentHelper.getSecurityCheck(this);
> >       }
> >
> >       /**
> >        * @see
> > org.apache.wicket.security.components.ISecureComponent#isActionAuthori
> > zed(java.lang.String)
> >        */
> >       public boolean isActionAuthorized(String waspAction)
> >       {
> >               return SecureComponentHelper.isActionAuthorized(this, waspAction);
> >       }
> >
> >       /**
> >        * @see
> > org.apache.wicket.security.components.ISecureComponent#isActionAuthori
> > zed(org.apache.wicket.security.actions.AbstractWaspAction)
> >        */
> >       public boolean isActionAuthorized(AbstractWaspAction action)
> >       {
> >               return SecureComponentHelper.isActionAuthorized(this, action);
> >       }
> >
> >       /**
> >        * @see
> > org.apache.wicket.security.components.ISecureComponent#isAuthenticated
> > ()
> >        */
> >       public boolean isAuthenticated()
> >       {
> >               return SecureComponentHelper.isAuthenticated(this);
> >       }
> >
> >       /**
> >        * @see
> > org.apache.wicket.security.components.ISecureComponent#setSecurityChec
> > k(org.apache.wicket.security.checks.ISecurityCheck)
> >        */
> >       public void setSecurityCheck(ISecurityCheck check)
> >       {
> >               SecureComponentHelper.setSecurityCheck(this, check);
> >       }
> >
> >       /**
> >        * Gets replacementClass.
> >        *
> >        * @return replacementClass
> >        */
> >       protected final Class getReplacementClass()
> >       {
> >               return replacementClass;
> >       }
> >
> >       /**
> >        * Sets replacementClass. Note by changing the replacement class a
> > new
> >        * securitycheck is automatically created.
> >        *
> >        * @param replacementClass
> >        *            replacementClass
> >        * @see #generateSecurityCheck()
> >        * @throws WicketRuntimeException
> >        *             if the class is null or not a {@link MarkupContainer}
> >        */
> >       protected final void setReplacementClass(Class replacementClass)
> >       {
> >               if (replacementClass == null ||
> > !MarkupContainer.class.isAssignableFrom(replacementClass))
> >                       throw new WicketRuntimeException("This link requires a " +
> > MarkupContainer.class
> >                                       + ", not a " + replacementClass);
> >               this.replacementClass = replacementClass;
> >               setSecurityCheck(generateSecurityCheck());
> >       }
> > }
> >
> >
> > On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
> >> Create your custom request cycle, and add a getter that uses the
> >> session's username/id to retrieve the user from the database, and
> >> cache it locally.
> >>
> >> Martijn
> >>
> >> On 9/11/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
> >>> This makes sense. Where would you stick the user on the
> >>> requestcycle?
> >>> It's not obvious from the javadocs. Is there a "wicket way"?
> >>>
> >>> -Anthony
> >>>
> >>> On Sep 11, 2007, at 10:05 AM, Maurice Marrink wrote:
> >>>
> >>>> Martijn, you are absolutely right, i forgot we moved the user
> >>>> from the
> >>>> session to the requestcycle. Just keep the id for your user in the
> >>>> session and keep the actual user for this request in the
> >>>> requestcycle.
> >>>> This way each thread will have its own instance of the user.
> >>>>
> >>>> Maurice
> >>>>
> >>>> On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
> >>>>> Just a quick note: storing objects that are not thread safe in
> >>>>> your
> >>>>> session is asking for trouble. While Wicket does limit page
> >>>>> processing
> >>>>> to one request at a time, other requests like resources can run in
> >>>>> parallel. What does this mean?
> >>>>>
> >>>>> One thing that comes to mind is that when two requests for the
> >>>>> same
> >>>>> session are being processed, and one is done before the other
> >>>>> it will
> >>>>> detach the user model. What are the semantics now for the other
> >>>>> thread?
> >>>>>
> >>>>> For instance if you have a detachable model storing a User
> >>>>> object in
> >>>>> your session and use Hibernate you are in a world of hurt, or
> >>>>> rather
> >>>>> Hibernate will sometimes bork because your Session tries to attach
> >>>>> the
> >>>>> single User instance to multiple Hibernate Session objects.
> >>>>> Exceptions
> >>>>> will be having a party.
> >>>>>
> >>>>> Now this is not meant as a Hibernate bashing reply, it just
> >>>>> happens
> >>>>> that Hibernate correctly detects multiple threads modifying the
> >>>>> same
> >>>>> object's state and stops tampering with it.
> >>>>>
> >>>>> Martijn
> >>>>>
> >>>>> --
> >>>>> Buy Wicket in Action: http://manning.com/dashorst
> >>>>> Apache Wicket 1.3.0-beta3 is released
> >>>>> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-
> >>>>> beta3/
> >>>>>
> >>>>> ------------------------------------------------------------------
> >>>>> ---
> >>>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> >>>>> For additional commands, e-mail: users-help@wicket.apache.org
> >>>>>
> >>>>>
> >>>>
> >>>> -------------------------------------------------------------------
> >>>> --
> >>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> >>>> For additional commands, e-mail: users-help@wicket.apache.org
> >>>>
> >>>
> >>>
> >>> --------------------------------------------------------------------
> >>> -
> >>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> >>> For additional commands, e-mail: users-help@wicket.apache.org
> >>>
> >>>
> >>
> >>
> >> --
> >> Buy Wicket in Action: http://manning.com/dashorst
> >> Apache Wicket 1.3.0-beta3 is released
> >> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> >> For additional commands, e-mail: users-help@wicket.apache.org
> >>
> >>
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Anthony Schexnaildre <ap...@gmail.com>.
Sitting down with the SecureContainerLink now. I may be slow but I am  
a little confused by it's intended use. I am not sure what the  
implementation of getReplacementFor(.....) is meant to look like.

-Anthony

On Sep 11, 2007, at 11:24 PM, Maurice Marrink wrote:

> Ok, i just finished a SecureContainerLink that should do what your
> SecurePanelLink does, but it is a bit less complex. I haven't checked
> it in yet or tested it for that matter but hope to hear from you if
> this is what you meant. If so i will make it a part of wasp.
>
> Maurice
>
> /*
>  * 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.security.components.markup.html.links;
>
> import org.apache.wicket.Component;
> import org.apache.wicket.MarkupContainer;
> import org.apache.wicket.WicketRuntimeException;
> import org.apache.wicket.markup.html.link.Link;
> import org.apache.wicket.model.IModel;
> import org.apache.wicket.security.actions.AbstractWaspAction;
> import org.apache.wicket.security.checks.ISecurityCheck;
> import org.apache.wicket.security.checks.LinkSecurityCheck;
> import org.apache.wicket.security.components.ISecureComponent;
> import org.apache.wicket.security.components.SecureComponentHelper;
>
> /**
>  * A secure link to handle panel replacements or any other type of
>  * {@link MarkupContainer}s. It is also usable as a link to switch  
> between 2 or
>  * more panels. Security is enforced on the replacing class.
>  *
>  * @author marrink
>  */
> public abstract class SecureContainerLink extends Link implements
> ISecureComponent
> {
> 	/**
> 	 *
> 	 */
> 	private static final long serialVersionUID = 1L;
>
> 	private Class replacementClass;
> 	private MarkupContainer containerParent;
> 	private String containerId;
>
> 	/**
> 	 * Constructs a new replacement link.
> 	 *
> 	 * @param id
> 	 *            id of the link
> 	 * @param replacementPanel
> 	 *            the class of the container replacing the component  
> on the
> 	 *            supplied parent
> 	 * @param parentOfReplaceablePanel
> 	 *            the parent component where the replacement needs to  
> take place
> 	 * @param panelId
> 	 *            the id of the component to be replaced
> 	 */
> 	public SecureContainerLink(String id, Class replacementPanel,
> 			MarkupContainer parentOfReplaceablePanel, String panelId)
> 	{
> 		this(id, null, replacementPanel, parentOfReplaceablePanel, panelId);
>
> 	}
>
> 	/**
> 	 * Constructs a new replacement link.
> 	 *
> 	 * @param id
> 	 *            id of the link
> 	 * @param object
> 	 *            model of the link
> 	 * @param replacementPanel
> 	 *            the class of the container replacing the component  
> on the
> 	 *            supplied parent
> 	 * @param parentOfReplaceablePanel
> 	 *            the parent component where the replacement needs to  
> take place
> 	 * @param panelId
> 	 *            the id of the component to be replaced
> 	 */
> 	public SecureContainerLink(String id, IModel object, Class  
> replacementPanel,
> 			MarkupContainer parentOfReplaceablePanel, String panelId)
> 	{
> 		super(id, object);
> 		setReplacementClass(replacementPanel);
> 		if (parentOfReplaceablePanel == null)
> 			throw new WicketRuntimeException("Parent required for replacing
> components.");
> 		containerParent = parentOfReplaceablePanel;
> 		if (panelId == null)
> 			throw new WicketRuntimeException("Id required from component to be
> replaced.");
> 		containerId = panelId;
> 	}
>
> 	/**
> 	 * Performs the replacement, only if an actual replacement was  
> constructed.
> 	 *
> 	 * @see org.apache.wicket.markup.html.link.Link#onClick()
> 	 * @see #getReplacementFor(Component, String, Class)
> 	 * @throws WicketRuntimeException
> 	 *             if a problem occurs in replacing the container.
> 	 */
> 	public final void onClick()
> 	{
> 		Component replaceMe = containerParent.get(containerId);
> 		if (replaceMe == null)
> 			throw new WicketRuntimeException("unable to find child with id: " +
> containerId
> 					+ " on parent: " + containerParent);
> 		Class myReplacementClass = getReplacementClass();
> 		MarkupContainer replacement = getReplacementFor(replaceMe,
> containerId, myReplacementClass);
> 		if (replacement == null)
> 			return; // do nothing
> 		if (!containerId.equals(replacement.getId()))
> 			throw new WicketRuntimeException("The replacement does not have the
> specified id: "
> 					+ containerId + ", but id: " + replacement.getId());
> 		if (myReplacementClass.isAssignableFrom(replacement.getClass()))
> 			containerParent.replace(replacement);
> 		else
> 			throw new WicketRuntimeException("The replacement for " +
> containerId + " on "
> 					+ containerParent + " is not assignable from " +  
> myReplacementClass);
>
> 	}
>
> 	/**
> 	 * Creates a replacement for a component. although the component  
> to be
> 	 * replaced does not need to be a {@link MarkupContainer} it  
> typically is.
> 	 * The replacement however does need to be a MarkupContainer, more
> 	 * specifically a (sub)class of replacementClass. Implementation  
> may choose
> 	 * at this point to do the next replacement with a different class  
> by using
> 	 * {@link #setReplacementClass(Class)} in order to create a switch  
> like
> 	 * behavior.
> 	 *
> 	 * @param current
> 	 *            the component to be replaced
> 	 * @param id
> 	 *            the id of the new container
> 	 * @param replacementClass
> 	 *            the class of the replacement
> 	 * @return a new replacement or null if the original component is  
> not to be
> 	 *         replaced
> 	 * @see #setReplacementClass(Class)
> 	 */
> 	protected abstract MarkupContainer getReplacementFor(Component
> current, String id,
> 			Class replacementClass);
>
> 	/**
> 	 * Generates the securitycheck for this link. by default this is a
> 	 * {@link LinkSecurityCheck} but implementations may choose to  
> override
> 	 * this. Note that the returned LinkSecurityCheck should not be  
> placed in
> 	 * alternative rendering mode as this will completely change the  
> intended
> 	 * behavior.
> 	 *
> 	 * @return the securitycheck for this link or null if no security  
> is to be
> 	 *         enforced
> 	 */
> 	protected ISecurityCheck generateSecurityCheck()
> 	{
> 		return new LinkSecurityCheck(this, getReplacementClass());
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#getSecurityChec 
> k()
> 	 */
> 	public ISecurityCheck getSecurityCheck()
> 	{
> 		return SecureComponentHelper.getSecurityCheck(this);
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#isActionAuthori 
> zed(java.lang.String)
> 	 */
> 	public boolean isActionAuthorized(String waspAction)
> 	{
> 		return SecureComponentHelper.isActionAuthorized(this, waspAction);
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#isActionAuthori 
> zed(org.apache.wicket.security.actions.AbstractWaspAction)
> 	 */
> 	public boolean isActionAuthorized(AbstractWaspAction action)
> 	{
> 		return SecureComponentHelper.isActionAuthorized(this, action);
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#isAuthenticated 
> ()
> 	 */
> 	public boolean isAuthenticated()
> 	{
> 		return SecureComponentHelper.isAuthenticated(this);
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#setSecurityChec 
> k(org.apache.wicket.security.checks.ISecurityCheck)
> 	 */
> 	public void setSecurityCheck(ISecurityCheck check)
> 	{
> 		SecureComponentHelper.setSecurityCheck(this, check);
> 	}
>
> 	/**
> 	 * Gets replacementClass.
> 	 *
> 	 * @return replacementClass
> 	 */
> 	protected final Class getReplacementClass()
> 	{
> 		return replacementClass;
> 	}
>
> 	/**
> 	 * Sets replacementClass. Note by changing the replacement class a  
> new
> 	 * securitycheck is automatically created.
> 	 *
> 	 * @param replacementClass
> 	 *            replacementClass
> 	 * @see #generateSecurityCheck()
> 	 * @throws WicketRuntimeException
> 	 *             if the class is null or not a {@link MarkupContainer}
> 	 */
> 	protected final void setReplacementClass(Class replacementClass)
> 	{
> 		if (replacementClass == null ||
> !MarkupContainer.class.isAssignableFrom(replacementClass))
> 			throw new WicketRuntimeException("This link requires a " +
> MarkupContainer.class
> 					+ ", not a " + replacementClass);
> 		this.replacementClass = replacementClass;
> 		setSecurityCheck(generateSecurityCheck());
> 	}
> }
>
>
> On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
>> Create your custom request cycle, and add a getter that uses the
>> session's username/id to retrieve the user from the database, and
>> cache it locally.
>>
>> Martijn
>>
>> On 9/11/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
>>> This makes sense. Where would you stick the user on the  
>>> requestcycle?
>>> It's not obvious from the javadocs. Is there a "wicket way"?
>>>
>>> -Anthony
>>>
>>> On Sep 11, 2007, at 10:05 AM, Maurice Marrink wrote:
>>>
>>>> Martijn, you are absolutely right, i forgot we moved the user  
>>>> from the
>>>> session to the requestcycle. Just keep the id for your user in the
>>>> session and keep the actual user for this request in the  
>>>> requestcycle.
>>>> This way each thread will have its own instance of the user.
>>>>
>>>> Maurice
>>>>
>>>> On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
>>>>> Just a quick note: storing objects that are not thread safe in  
>>>>> your
>>>>> session is asking for trouble. While Wicket does limit page
>>>>> processing
>>>>> to one request at a time, other requests like resources can run in
>>>>> parallel. What does this mean?
>>>>>
>>>>> One thing that comes to mind is that when two requests for the  
>>>>> same
>>>>> session are being processed, and one is done before the other  
>>>>> it will
>>>>> detach the user model. What are the semantics now for the other
>>>>> thread?
>>>>>
>>>>> For instance if you have a detachable model storing a User  
>>>>> object in
>>>>> your session and use Hibernate you are in a world of hurt, or  
>>>>> rather
>>>>> Hibernate will sometimes bork because your Session tries to attach
>>>>> the
>>>>> single User instance to multiple Hibernate Session objects.
>>>>> Exceptions
>>>>> will be having a party.
>>>>>
>>>>> Now this is not meant as a Hibernate bashing reply, it just  
>>>>> happens
>>>>> that Hibernate correctly detects multiple threads modifying the  
>>>>> same
>>>>> object's state and stops tampering with it.
>>>>>
>>>>> Martijn
>>>>>
>>>>> --
>>>>> Buy Wicket in Action: http://manning.com/dashorst
>>>>> Apache Wicket 1.3.0-beta3 is released
>>>>> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0- 
>>>>> beta3/
>>>>>
>>>>> ------------------------------------------------------------------ 
>>>>> ---
>>>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>>>
>>>>>
>>>>
>>>> ------------------------------------------------------------------- 
>>>> --
>>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>>
>>>
>>>
>>> -------------------------------------------------------------------- 
>>> -
>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>
>>>
>>
>>
>> --
>> Buy Wicket in Action: http://manning.com/dashorst
>> Apache Wicket 1.3.0-beta3 is released
>> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Anthony Schexnaildre <ap...@gmail.com>.
At first glance this looks more impressive than my first attempt. I  
am just reorganizing my application by storing the User in the  
RequestCycle as was suggested earlier and storing the User id in the  
session.

After that I will give this code a spin and let you know my thoughts.


-Anthony


On Sep 11, 2007, at 11:24 PM, Maurice Marrink wrote:

> Ok, i just finished a SecureContainerLink that should do what your
> SecurePanelLink does, but it is a bit less complex. I haven't checked
> it in yet or tested it for that matter but hope to hear from you if
> this is what you meant. If so i will make it a part of wasp.
>
> Maurice
>
> /*
>  * 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.security.components.markup.html.links;
>
> import org.apache.wicket.Component;
> import org.apache.wicket.MarkupContainer;
> import org.apache.wicket.WicketRuntimeException;
> import org.apache.wicket.markup.html.link.Link;
> import org.apache.wicket.model.IModel;
> import org.apache.wicket.security.actions.AbstractWaspAction;
> import org.apache.wicket.security.checks.ISecurityCheck;
> import org.apache.wicket.security.checks.LinkSecurityCheck;
> import org.apache.wicket.security.components.ISecureComponent;
> import org.apache.wicket.security.components.SecureComponentHelper;
>
> /**
>  * A secure link to handle panel replacements or any other type of
>  * {@link MarkupContainer}s. It is also usable as a link to switch  
> between 2 or
>  * more panels. Security is enforced on the replacing class.
>  *
>  * @author marrink
>  */
> public abstract class SecureContainerLink extends Link implements
> ISecureComponent
> {
> 	/**
> 	 *
> 	 */
> 	private static final long serialVersionUID = 1L;
>
> 	private Class replacementClass;
> 	private MarkupContainer containerParent;
> 	private String containerId;
>
> 	/**
> 	 * Constructs a new replacement link.
> 	 *
> 	 * @param id
> 	 *            id of the link
> 	 * @param replacementPanel
> 	 *            the class of the container replacing the component  
> on the
> 	 *            supplied parent
> 	 * @param parentOfReplaceablePanel
> 	 *            the parent component where the replacement needs to  
> take place
> 	 * @param panelId
> 	 *            the id of the component to be replaced
> 	 */
> 	public SecureContainerLink(String id, Class replacementPanel,
> 			MarkupContainer parentOfReplaceablePanel, String panelId)
> 	{
> 		this(id, null, replacementPanel, parentOfReplaceablePanel, panelId);
>
> 	}
>
> 	/**
> 	 * Constructs a new replacement link.
> 	 *
> 	 * @param id
> 	 *            id of the link
> 	 * @param object
> 	 *            model of the link
> 	 * @param replacementPanel
> 	 *            the class of the container replacing the component  
> on the
> 	 *            supplied parent
> 	 * @param parentOfReplaceablePanel
> 	 *            the parent component where the replacement needs to  
> take place
> 	 * @param panelId
> 	 *            the id of the component to be replaced
> 	 */
> 	public SecureContainerLink(String id, IModel object, Class  
> replacementPanel,
> 			MarkupContainer parentOfReplaceablePanel, String panelId)
> 	{
> 		super(id, object);
> 		setReplacementClass(replacementPanel);
> 		if (parentOfReplaceablePanel == null)
> 			throw new WicketRuntimeException("Parent required for replacing
> components.");
> 		containerParent = parentOfReplaceablePanel;
> 		if (panelId == null)
> 			throw new WicketRuntimeException("Id required from component to be
> replaced.");
> 		containerId = panelId;
> 	}
>
> 	/**
> 	 * Performs the replacement, only if an actual replacement was  
> constructed.
> 	 *
> 	 * @see org.apache.wicket.markup.html.link.Link#onClick()
> 	 * @see #getReplacementFor(Component, String, Class)
> 	 * @throws WicketRuntimeException
> 	 *             if a problem occurs in replacing the container.
> 	 */
> 	public final void onClick()
> 	{
> 		Component replaceMe = containerParent.get(containerId);
> 		if (replaceMe == null)
> 			throw new WicketRuntimeException("unable to find child with id: " +
> containerId
> 					+ " on parent: " + containerParent);
> 		Class myReplacementClass = getReplacementClass();
> 		MarkupContainer replacement = getReplacementFor(replaceMe,
> containerId, myReplacementClass);
> 		if (replacement == null)
> 			return; // do nothing
> 		if (!containerId.equals(replacement.getId()))
> 			throw new WicketRuntimeException("The replacement does not have the
> specified id: "
> 					+ containerId + ", but id: " + replacement.getId());
> 		if (myReplacementClass.isAssignableFrom(replacement.getClass()))
> 			containerParent.replace(replacement);
> 		else
> 			throw new WicketRuntimeException("The replacement for " +
> containerId + " on "
> 					+ containerParent + " is not assignable from " +  
> myReplacementClass);
>
> 	}
>
> 	/**
> 	 * Creates a replacement for a component. although the component  
> to be
> 	 * replaced does not need to be a {@link MarkupContainer} it  
> typically is.
> 	 * The replacement however does need to be a MarkupContainer, more
> 	 * specifically a (sub)class of replacementClass. Implementation  
> may choose
> 	 * at this point to do the next replacement with a different class  
> by using
> 	 * {@link #setReplacementClass(Class)} in order to create a switch  
> like
> 	 * behavior.
> 	 *
> 	 * @param current
> 	 *            the component to be replaced
> 	 * @param id
> 	 *            the id of the new container
> 	 * @param replacementClass
> 	 *            the class of the replacement
> 	 * @return a new replacement or null if the original component is  
> not to be
> 	 *         replaced
> 	 * @see #setReplacementClass(Class)
> 	 */
> 	protected abstract MarkupContainer getReplacementFor(Component
> current, String id,
> 			Class replacementClass);
>
> 	/**
> 	 * Generates the securitycheck for this link. by default this is a
> 	 * {@link LinkSecurityCheck} but implementations may choose to  
> override
> 	 * this. Note that the returned LinkSecurityCheck should not be  
> placed in
> 	 * alternative rendering mode as this will completely change the  
> intended
> 	 * behavior.
> 	 *
> 	 * @return the securitycheck for this link or null if no security  
> is to be
> 	 *         enforced
> 	 */
> 	protected ISecurityCheck generateSecurityCheck()
> 	{
> 		return new LinkSecurityCheck(this, getReplacementClass());
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#getSecurityChec 
> k()
> 	 */
> 	public ISecurityCheck getSecurityCheck()
> 	{
> 		return SecureComponentHelper.getSecurityCheck(this);
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#isActionAuthori 
> zed(java.lang.String)
> 	 */
> 	public boolean isActionAuthorized(String waspAction)
> 	{
> 		return SecureComponentHelper.isActionAuthorized(this, waspAction);
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#isActionAuthori 
> zed(org.apache.wicket.security.actions.AbstractWaspAction)
> 	 */
> 	public boolean isActionAuthorized(AbstractWaspAction action)
> 	{
> 		return SecureComponentHelper.isActionAuthorized(this, action);
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#isAuthenticated 
> ()
> 	 */
> 	public boolean isAuthenticated()
> 	{
> 		return SecureComponentHelper.isAuthenticated(this);
> 	}
>
> 	/**
> 	 * @see  
> org.apache.wicket.security.components.ISecureComponent#setSecurityChec 
> k(org.apache.wicket.security.checks.ISecurityCheck)
> 	 */
> 	public void setSecurityCheck(ISecurityCheck check)
> 	{
> 		SecureComponentHelper.setSecurityCheck(this, check);
> 	}
>
> 	/**
> 	 * Gets replacementClass.
> 	 *
> 	 * @return replacementClass
> 	 */
> 	protected final Class getReplacementClass()
> 	{
> 		return replacementClass;
> 	}
>
> 	/**
> 	 * Sets replacementClass. Note by changing the replacement class a  
> new
> 	 * securitycheck is automatically created.
> 	 *
> 	 * @param replacementClass
> 	 *            replacementClass
> 	 * @see #generateSecurityCheck()
> 	 * @throws WicketRuntimeException
> 	 *             if the class is null or not a {@link MarkupContainer}
> 	 */
> 	protected final void setReplacementClass(Class replacementClass)
> 	{
> 		if (replacementClass == null ||
> !MarkupContainer.class.isAssignableFrom(replacementClass))
> 			throw new WicketRuntimeException("This link requires a " +
> MarkupContainer.class
> 					+ ", not a " + replacementClass);
> 		this.replacementClass = replacementClass;
> 		setSecurityCheck(generateSecurityCheck());
> 	}
> }
>
>
> On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
>> Create your custom request cycle, and add a getter that uses the
>> session's username/id to retrieve the user from the database, and
>> cache it locally.
>>
>> Martijn
>>
>> On 9/11/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
>>> This makes sense. Where would you stick the user on the  
>>> requestcycle?
>>> It's not obvious from the javadocs. Is there a "wicket way"?
>>>
>>> -Anthony
>>>
>>> On Sep 11, 2007, at 10:05 AM, Maurice Marrink wrote:
>>>
>>>> Martijn, you are absolutely right, i forgot we moved the user  
>>>> from the
>>>> session to the requestcycle. Just keep the id for your user in the
>>>> session and keep the actual user for this request in the  
>>>> requestcycle.
>>>> This way each thread will have its own instance of the user.
>>>>
>>>> Maurice
>>>>
>>>> On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
>>>>> Just a quick note: storing objects that are not thread safe in  
>>>>> your
>>>>> session is asking for trouble. While Wicket does limit page
>>>>> processing
>>>>> to one request at a time, other requests like resources can run in
>>>>> parallel. What does this mean?
>>>>>
>>>>> One thing that comes to mind is that when two requests for the  
>>>>> same
>>>>> session are being processed, and one is done before the other  
>>>>> it will
>>>>> detach the user model. What are the semantics now for the other
>>>>> thread?
>>>>>
>>>>> For instance if you have a detachable model storing a User  
>>>>> object in
>>>>> your session and use Hibernate you are in a world of hurt, or  
>>>>> rather
>>>>> Hibernate will sometimes bork because your Session tries to attach
>>>>> the
>>>>> single User instance to multiple Hibernate Session objects.
>>>>> Exceptions
>>>>> will be having a party.
>>>>>
>>>>> Now this is not meant as a Hibernate bashing reply, it just  
>>>>> happens
>>>>> that Hibernate correctly detects multiple threads modifying the  
>>>>> same
>>>>> object's state and stops tampering with it.
>>>>>
>>>>> Martijn
>>>>>
>>>>> --
>>>>> Buy Wicket in Action: http://manning.com/dashorst
>>>>> Apache Wicket 1.3.0-beta3 is released
>>>>> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0- 
>>>>> beta3/
>>>>>
>>>>> ------------------------------------------------------------------ 
>>>>> ---
>>>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>>>
>>>>>
>>>>
>>>> ------------------------------------------------------------------- 
>>>> --
>>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>>
>>>
>>>
>>> -------------------------------------------------------------------- 
>>> -
>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>
>>>
>>
>>
>> --
>> Buy Wicket in Action: http://manning.com/dashorst
>> Apache Wicket 1.3.0-beta3 is released
>> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Maurice Marrink <ma...@gmail.com>.
Ok, i just finished a SecureContainerLink that should do what your
SecurePanelLink does, but it is a bit less complex. I haven't checked
it in yet or tested it for that matter but hope to hear from you if
this is what you meant. If so i will make it a part of wasp.

Maurice

/*
 * 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.security.components.markup.html.links;

import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.model.IModel;
import org.apache.wicket.security.actions.AbstractWaspAction;
import org.apache.wicket.security.checks.ISecurityCheck;
import org.apache.wicket.security.checks.LinkSecurityCheck;
import org.apache.wicket.security.components.ISecureComponent;
import org.apache.wicket.security.components.SecureComponentHelper;

/**
 * A secure link to handle panel replacements or any other type of
 * {@link MarkupContainer}s. It is also usable as a link to switch between 2 or
 * more panels. Security is enforced on the replacing class.
 *
 * @author marrink
 */
public abstract class SecureContainerLink extends Link implements
ISecureComponent
{
	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	private Class replacementClass;
	private MarkupContainer containerParent;
	private String containerId;

	/**
	 * Constructs a new replacement link.
	 *
	 * @param id
	 *            id of the link
	 * @param replacementPanel
	 *            the class of the container replacing the component on the
	 *            supplied parent
	 * @param parentOfReplaceablePanel
	 *            the parent component where the replacement needs to take place
	 * @param panelId
	 *            the id of the component to be replaced
	 */
	public SecureContainerLink(String id, Class replacementPanel,
			MarkupContainer parentOfReplaceablePanel, String panelId)
	{
		this(id, null, replacementPanel, parentOfReplaceablePanel, panelId);

	}

	/**
	 * Constructs a new replacement link.
	 *
	 * @param id
	 *            id of the link
	 * @param object
	 *            model of the link
	 * @param replacementPanel
	 *            the class of the container replacing the component on the
	 *            supplied parent
	 * @param parentOfReplaceablePanel
	 *            the parent component where the replacement needs to take place
	 * @param panelId
	 *            the id of the component to be replaced
	 */
	public SecureContainerLink(String id, IModel object, Class replacementPanel,
			MarkupContainer parentOfReplaceablePanel, String panelId)
	{
		super(id, object);
		setReplacementClass(replacementPanel);
		if (parentOfReplaceablePanel == null)
			throw new WicketRuntimeException("Parent required for replacing
components.");
		containerParent = parentOfReplaceablePanel;
		if (panelId == null)
			throw new WicketRuntimeException("Id required from component to be
replaced.");
		containerId = panelId;
	}

	/**
	 * Performs the replacement, only if an actual replacement was constructed.
	 *
	 * @see org.apache.wicket.markup.html.link.Link#onClick()
	 * @see #getReplacementFor(Component, String, Class)
	 * @throws WicketRuntimeException
	 *             if a problem occurs in replacing the container.
	 */
	public final void onClick()
	{
		Component replaceMe = containerParent.get(containerId);
		if (replaceMe == null)
			throw new WicketRuntimeException("unable to find child with id: " +
containerId
					+ " on parent: " + containerParent);
		Class myReplacementClass = getReplacementClass();
		MarkupContainer replacement = getReplacementFor(replaceMe,
containerId, myReplacementClass);
		if (replacement == null)
			return; // do nothing
		if (!containerId.equals(replacement.getId()))
			throw new WicketRuntimeException("The replacement does not have the
specified id: "
					+ containerId + ", but id: " + replacement.getId());
		if (myReplacementClass.isAssignableFrom(replacement.getClass()))
			containerParent.replace(replacement);
		else
			throw new WicketRuntimeException("The replacement for " +
containerId + " on "
					+ containerParent + " is not assignable from " + myReplacementClass);

	}

	/**
	 * Creates a replacement for a component. although the component to be
	 * replaced does not need to be a {@link MarkupContainer} it typically is.
	 * The replacement however does need to be a MarkupContainer, more
	 * specifically a (sub)class of replacementClass. Implementation may choose
	 * at this point to do the next replacement with a different class by using
	 * {@link #setReplacementClass(Class)} in order to create a switch like
	 * behavior.
	 *
	 * @param current
	 *            the component to be replaced
	 * @param id
	 *            the id of the new container
	 * @param replacementClass
	 *            the class of the replacement
	 * @return a new replacement or null if the original component is not to be
	 *         replaced
	 * @see #setReplacementClass(Class)
	 */
	protected abstract MarkupContainer getReplacementFor(Component
current, String id,
			Class replacementClass);

	/**
	 * Generates the securitycheck for this link. by default this is a
	 * {@link LinkSecurityCheck} but implementations may choose to override
	 * this. Note that the returned LinkSecurityCheck should not be placed in
	 * alternative rendering mode as this will completely change the intended
	 * behavior.
	 *
	 * @return the securitycheck for this link or null if no security is to be
	 *         enforced
	 */
	protected ISecurityCheck generateSecurityCheck()
	{
		return new LinkSecurityCheck(this, getReplacementClass());
	}

	/**
	 * @see org.apache.wicket.security.components.ISecureComponent#getSecurityCheck()
	 */
	public ISecurityCheck getSecurityCheck()
	{
		return SecureComponentHelper.getSecurityCheck(this);
	}

	/**
	 * @see org.apache.wicket.security.components.ISecureComponent#isActionAuthorized(java.lang.String)
	 */
	public boolean isActionAuthorized(String waspAction)
	{
		return SecureComponentHelper.isActionAuthorized(this, waspAction);
	}

	/**
	 * @see org.apache.wicket.security.components.ISecureComponent#isActionAuthorized(org.apache.wicket.security.actions.AbstractWaspAction)
	 */
	public boolean isActionAuthorized(AbstractWaspAction action)
	{
		return SecureComponentHelper.isActionAuthorized(this, action);
	}

	/**
	 * @see org.apache.wicket.security.components.ISecureComponent#isAuthenticated()
	 */
	public boolean isAuthenticated()
	{
		return SecureComponentHelper.isAuthenticated(this);
	}

	/**
	 * @see org.apache.wicket.security.components.ISecureComponent#setSecurityCheck(org.apache.wicket.security.checks.ISecurityCheck)
	 */
	public void setSecurityCheck(ISecurityCheck check)
	{
		SecureComponentHelper.setSecurityCheck(this, check);
	}

	/**
	 * Gets replacementClass.
	 *
	 * @return replacementClass
	 */
	protected final Class getReplacementClass()
	{
		return replacementClass;
	}

	/**
	 * Sets replacementClass. Note by changing the replacement class a new
	 * securitycheck is automatically created.
	 *
	 * @param replacementClass
	 *            replacementClass
	 * @see #generateSecurityCheck()
	 * @throws WicketRuntimeException
	 *             if the class is null or not a {@link MarkupContainer}
	 */
	protected final void setReplacementClass(Class replacementClass)
	{
		if (replacementClass == null ||
!MarkupContainer.class.isAssignableFrom(replacementClass))
			throw new WicketRuntimeException("This link requires a " +
MarkupContainer.class
					+ ", not a " + replacementClass);
		this.replacementClass = replacementClass;
		setSecurityCheck(generateSecurityCheck());
	}
}


On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
> Create your custom request cycle, and add a getter that uses the
> session's username/id to retrieve the user from the database, and
> cache it locally.
>
> Martijn
>
> On 9/11/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
> > This makes sense. Where would you stick the user on the requestcycle?
> > It's not obvious from the javadocs. Is there a "wicket way"?
> >
> > -Anthony
> >
> > On Sep 11, 2007, at 10:05 AM, Maurice Marrink wrote:
> >
> > > Martijn, you are absolutely right, i forgot we moved the user from the
> > > session to the requestcycle. Just keep the id for your user in the
> > > session and keep the actual user for this request in the requestcycle.
> > > This way each thread will have its own instance of the user.
> > >
> > > Maurice
> > >
> > > On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
> > >> Just a quick note: storing objects that are not thread safe in your
> > >> session is asking for trouble. While Wicket does limit page
> > >> processing
> > >> to one request at a time, other requests like resources can run in
> > >> parallel. What does this mean?
> > >>
> > >> One thing that comes to mind is that when two requests for the same
> > >> session are being processed, and one is done before the other it will
> > >> detach the user model. What are the semantics now for the other
> > >> thread?
> > >>
> > >> For instance if you have a detachable model storing a User object in
> > >> your session and use Hibernate you are in a world of hurt, or rather
> > >> Hibernate will sometimes bork because your Session tries to attach
> > >> the
> > >> single User instance to multiple Hibernate Session objects.
> > >> Exceptions
> > >> will be having a party.
> > >>
> > >> Now this is not meant as a Hibernate bashing reply, it just happens
> > >> that Hibernate correctly detects multiple threads modifying the same
> > >> object's state and stops tampering with it.
> > >>
> > >> Martijn
> > >>
> > >> --
> > >> Buy Wicket in Action: http://manning.com/dashorst
> > >> Apache Wicket 1.3.0-beta3 is released
> > >> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/
> > >>
> > >> ---------------------------------------------------------------------
> > >> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > >> For additional commands, e-mail: users-help@wicket.apache.org
> > >>
> > >>
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > > For additional commands, e-mail: users-help@wicket.apache.org
> > >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
> >
>
>
> --
> Buy Wicket in Action: http://manning.com/dashorst
> Apache Wicket 1.3.0-beta3 is released
> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Martijn Dashorst <ma...@gmail.com>.
Create your custom request cycle, and add a getter that uses the
session's username/id to retrieve the user from the database, and
cache it locally.

Martijn

On 9/11/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
> This makes sense. Where would you stick the user on the requestcycle?
> It's not obvious from the javadocs. Is there a "wicket way"?
>
> -Anthony
>
> On Sep 11, 2007, at 10:05 AM, Maurice Marrink wrote:
>
> > Martijn, you are absolutely right, i forgot we moved the user from the
> > session to the requestcycle. Just keep the id for your user in the
> > session and keep the actual user for this request in the requestcycle.
> > This way each thread will have its own instance of the user.
> >
> > Maurice
> >
> > On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
> >> Just a quick note: storing objects that are not thread safe in your
> >> session is asking for trouble. While Wicket does limit page
> >> processing
> >> to one request at a time, other requests like resources can run in
> >> parallel. What does this mean?
> >>
> >> One thing that comes to mind is that when two requests for the same
> >> session are being processed, and one is done before the other it will
> >> detach the user model. What are the semantics now for the other
> >> thread?
> >>
> >> For instance if you have a detachable model storing a User object in
> >> your session and use Hibernate you are in a world of hurt, or rather
> >> Hibernate will sometimes bork because your Session tries to attach
> >> the
> >> single User instance to multiple Hibernate Session objects.
> >> Exceptions
> >> will be having a party.
> >>
> >> Now this is not meant as a Hibernate bashing reply, it just happens
> >> that Hibernate correctly detects multiple threads modifying the same
> >> object's state and stops tampering with it.
> >>
> >> Martijn
> >>
> >> --
> >> Buy Wicket in Action: http://manning.com/dashorst
> >> Apache Wicket 1.3.0-beta3 is released
> >> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> >> For additional commands, e-mail: users-help@wicket.apache.org
> >>
> >>
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>


-- 
Buy Wicket in Action: http://manning.com/dashorst
Apache Wicket 1.3.0-beta3 is released
Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Anthony Schexnaildre <ap...@gmail.com>.
This makes sense. Where would you stick the user on the requestcycle?  
It's not obvious from the javadocs. Is there a "wicket way"?

-Anthony

On Sep 11, 2007, at 10:05 AM, Maurice Marrink wrote:

> Martijn, you are absolutely right, i forgot we moved the user from the
> session to the requestcycle. Just keep the id for your user in the
> session and keep the actual user for this request in the requestcycle.
> This way each thread will have its own instance of the user.
>
> Maurice
>
> On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
>> Just a quick note: storing objects that are not thread safe in your
>> session is asking for trouble. While Wicket does limit page  
>> processing
>> to one request at a time, other requests like resources can run in
>> parallel. What does this mean?
>>
>> One thing that comes to mind is that when two requests for the same
>> session are being processed, and one is done before the other it will
>> detach the user model. What are the semantics now for the other
>> thread?
>>
>> For instance if you have a detachable model storing a User object in
>> your session and use Hibernate you are in a world of hurt, or rather
>> Hibernate will sometimes bork because your Session tries to attach  
>> the
>> single User instance to multiple Hibernate Session objects.  
>> Exceptions
>> will be having a party.
>>
>> Now this is not meant as a Hibernate bashing reply, it just happens
>> that Hibernate correctly detects multiple threads modifying the same
>> object's state and stops tampering with it.
>>
>> Martijn
>>
>> --
>> Buy Wicket in Action: http://manning.com/dashorst
>> Apache Wicket 1.3.0-beta3 is released
>> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Maurice Marrink <ma...@gmail.com>.
Martijn, you are absolutely right, i forgot we moved the user from the
session to the requestcycle. Just keep the id for your user in the
session and keep the actual user for this request in the requestcycle.
This way each thread will have its own instance of the user.

Maurice

On 9/11/07, Martijn Dashorst <ma...@gmail.com> wrote:
> Just a quick note: storing objects that are not thread safe in your
> session is asking for trouble. While Wicket does limit page processing
> to one request at a time, other requests like resources can run in
> parallel. What does this mean?
>
> One thing that comes to mind is that when two requests for the same
> session are being processed, and one is done before the other it will
> detach the user model. What are the semantics now for the other
> thread?
>
> For instance if you have a detachable model storing a User object in
> your session and use Hibernate you are in a world of hurt, or rather
> Hibernate will sometimes bork because your Session tries to attach the
> single User instance to multiple Hibernate Session objects. Exceptions
> will be having a party.
>
> Now this is not meant as a Hibernate bashing reply, it just happens
> that Hibernate correctly detects multiple threads modifying the same
> object's state and stops tampering with it.
>
> Martijn
>
> --
> Buy Wicket in Action: http://manning.com/dashorst
> Apache Wicket 1.3.0-beta3 is released
> Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Martijn Dashorst <ma...@gmail.com>.
Just a quick note: storing objects that are not thread safe in your
session is asking for trouble. While Wicket does limit page processing
to one request at a time, other requests like resources can run in
parallel. What does this mean?

One thing that comes to mind is that when two requests for the same
session are being processed, and one is done before the other it will
detach the user model. What are the semantics now for the other
thread?

For instance if you have a detachable model storing a User object in
your session and use Hibernate you are in a world of hurt, or rather
Hibernate will sometimes bork because your Session tries to attach the
single User instance to multiple Hibernate Session objects. Exceptions
will be having a party.

Now this is not meant as a Hibernate bashing reply, it just happens
that Hibernate correctly detects multiple threads modifying the same
object's state and stops tampering with it.

Martijn

-- 
Buy Wicket in Action: http://manning.com/dashorst
Apache Wicket 1.3.0-beta3 is released
Get it now: http://www.apache.org/dyn/closer.cgi/wicket/1.3.0-beta3/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Maurice Marrink <ma...@gmail.com>.
On 9/11/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
> Please hijack away.
>
> I have been quite happy with Wasp and Swarm. It's simple and painless
> but quite flexible. The examples are the life saver though. To be
> honest, the security framework is why I chose to use Wicket for this
> project instead of Tapestry.
>
> I am however having a few issues figuring out some "best practices"
> that maybe you or some other experienced Wasp/Swarm users may be able
> to shed some light on.
>
> 1. Where would you store a reference to the logged in user. Currently
> have it in a DetachableModel in a custom session. There has to be a
> better place to put the user reference that fits more directly with
> the security framework.
A detachable model in a custom session is as good a place as any, in
fact i keep it there too. Swarm indeed does not keep a ref to your
user object but it does keep a reference to the subject (which
translates into the user rights, but also could be the user itself).
Although you can get this subject by casting the strategy to a
SwarmStrategy, i recommend storing the user yourself like you do now,
which is perfectly compatible with the wicket philosophy that if you
wish to store things in the session you should create a custom session
and provide strongtyped getters / setters for it.


> 2. I very much like your SecureTab example but something like a
> SecurePanelLink within the framework would be helpful.
The ContainerSecurityCheck was created for helping out with panel
replacements by treating panels exactly like pages but if you feel we
need to provide more stuff out of the box here feel free to speak up.
After thinking about this for a bit i think i can come up with a
secure link that automatically replaces one panel with another.

>I have been
> working on my own that mirrors the SecurePageLink as much as possible
> but it is still a bit wonky.
I saw it, and i must admit my first thought was: "couldn't he use ...,
or do ...." but after looking deeper in what you were trying to
accomplish, i think you did alright. Although looking back at my
previous comment about making a panel link i think a combination of
LinkSecurityCheck and ContainerSecurityCheck would be ideal.


>This is helpful because once you get
> into a tab layout, navigation to other panels that are not directly
> attached to a tab becomes annoying at best. I am working through it
> but seems like someone must have solved this issues a few times over
> in an elegant fashion. Maybe some kind of "panel stack" with tab
> integration?
I am not sure i get what it is you are trying to accomplish here. It
should not matter where the panel is located. if you use a regular
ComponentSecurityCheck the full path with the parent is considered but
if you use a ContainerSecurityCheck the panel class is used and where
ever it is placed in the page hierarchy is irrelevant. Personally i
use Swarm in a page based approach, but panels should be just as easy.

>
> 3. I don't understand the DataPermissions, configuration and their
> use cases. I must admit I have not spent the time to dig through the
> example extensively but I don't understand the use cases enough to
> know why I would want to spend the time.
The DataPermissions are indeed a bit under lighted in the examples.
The beauty about them is that you can build entire applications
without ever needing them. They are intended for use cases where it
makes more sense to let the data / model dictate if a user has
permissions for them. One benefit of this is that you can share the
secure model (which is typically used for data permissions) between
multiple components and instead of securing each component the
security is on 1 central place namely the model. An example of this is
the SwarmCompoundPropertyModel.

>
> 4. I am working on an application that will eventually have very
> complicated permission structure. Right now I am fumbling a solution
> together for phase one. Eventually I would like to be able to
> "filter" the date returned to a user based on some permissions while
> not coupling the security layer to the Dao's to tightly.
We have a similar use case in our organization and although you could
use datapermissions to hide components showing restricted data
(completely disconnecting your dao's from your security layer),
consider the following: by letting you security layer provide you with
some sort of filter for your dao (perhaps a list of allowed id's or a
query part) you bypass the need to secure your components as the data
is already made to fit what is allowed to see. In our application we
chose the latter approach.

>A typical
> structure would be as follows:
>
> O - Organisation
> U - User
>
>          O
>       /  / \  \
>     /   |   |   \
>    U U U O
>               /  |  \
>             U O O
>               / |    |   \
>             U U  U  U
>
> Consider a use case where you have a hierarchy of Financial
> Transaction Processors with the following 2 user types/principals:
>
> Customer Service - Allowed to see transactions and act on them if the
> transactions are for their direct organisation
> Billing - Allowed to see transaction and act on them for their direct
> organisation and any sub-organisations
In our application we tackled this problem by introducing a few more
actions (i suggest looking into the custom actionfactory example) by
creating 2 additional actions: 1 for the direct organizations and the
2nd which implies the first for the direct and the sub-organizations.
Then by creating a custom ISecurityCheck you can verify if the
organization is allowed or not.

>
> The final goal would be to have an interface much like that in the
> wicket-phonebook example where the DataProvider ( or something else )
> would feed the appropriate results out of the hibernate dao's into
> the DataTable based on the users permissions.
>
> Any clues to some elegant approach?
Well i can tell you about how we did it. Our dataproviders work with
filters (which are simple pojos with the same fields as the object(s)
we want to display). In addition these filters know the security
privileges of the user and based on that the provide a list of id's
(not that elegant i admit, another option would be to have them donate
a query fragment) of allowed entities. the provider then builds the
query based on the filter and uses an in query on the id's to have the
database only return the allowed records. Note that we have used this
approach only in DataView and not in DataTable. DataTable might make
it a bit more trickier because it gives you less control over the
filtering. Anyway i think having your filter create query fragments
based on security is even more elegant then id's, but try getting time
to refactor that ;)


Maurice

>
> -Anthony
>
>
>
> On Sep 9, 2007, at 6:12 PM, Maurice Marrink wrote:
>
> > Allow me to hijack this topic because my eye sees the magic word
> > ISecureComponent :D
> >
> > Glad to come across another user of Wasp and Swarm. Any comments /
> > questions about them?
> >
> > Maurice
> >
> > On 9/9/07, Igor Vaynberg <ig...@gmail.com> wrote:
> >> heh, seems a lot of people run into it. the short is that you have
> >> to do
> >> this:
> >>
> >> lets say you have a ref to the panel: private Panel panel;
> >>
> >> what you do is this:
> >> panel.replaceWith(new Panel());
> >>
> >> and then later again
> >> panel.replaceWith(new Panel());
> >>
> >> ^ the second time will fail beause you have removed panel from
> >> hierarchy
> >> already - you replaced it with another panel.
> >>
> >> the proper way to do it is to keep the reference up to date, so
> >> Panel temp=new Panel();
> >> panel.replaceWith(temp);
> >> panel=temp;
> >>
> >> that way when it happens the second time it will properly act on
> >> the new
> >> panel that is inside the hierarchy now.
> >>
> >> -igor
> >>
> >>
> >>
> >>
> >> On 9/9/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
> >>>
> >>> I am trying to create a link that will replace one panel with
> >>> another
> >>> on the page. This seems as though it should be an easy task but
> >>> after
> >>> many attempts and searching the net for examples I have yet to
> >>> get it
> >>> working so the replacement can happen more than one without the
> >>> component becoming orphaned. On the second replace attempt i get the
> >>> following exception. Anyone have the solution?
> >>>
> >>> Thank you,
> >>>
> >>> Anthony
> >>>
> >>>
> >>> java.lang.IllegalStateException: This method can only be called on a
> >>> component that has already been added to its parent.
> >>>       at org.apache.wicket.Component.replaceWith(Component.java:
> >>> 2266)
> >>>       at com.pinwise.pinbase.web.components.links.SecurePanelLink
> >>> $4.onClick(SecurePanelLink.java:142)
> >>>       at org.apache.wicket.markup.html.link.Link.onLinkClicked
> >>> (Link.java:222)
> >>>       at java.lang.reflect.Method.invoke(Method.java:585)
> >>>       at org.apache.wicket.RequestListenerInterface.invoke
> >>> (RequestListenerInterface.java:186)
> >>>
> >>>
> >>> =====================================
> >>>
> >>> =====================================
> >>>
> >>>         public UserPanel(String id) {
> >>>                 super(id);
> >>>
> >>>
> >>>                 UserFormPanel userFormPanel = new
> >>> UserFormPanel("userFormPanel");
> >>>                 add( userFormPanel );
> >>>
> >>>                 List<IColumn> columns = new ArrayList<IColumn>();
> >>>                 final Model m = new Model(userFormPanel);
> >>>          columns.add(new PropertyColumn(new Model("Actions"), "id")
> >>>          {
> >>>                         public void populateItem(Item cellItem,
> >>> String
> >>> componentId, final
> >>> IModel model)
> >>>              {
> >>>                                 EditActionPanel panel = new
> >>> EditActionPanel(componentId, model);
> >>>                                 panel.add(
> >>> SecurePanelLink.createSecurePanelLink( "edit", m,
> >>> UserFormPanel.class, model ) );
> >>>                cellItem.add( panel );
> >>>              }
> >>>          });
> >>>
> >>>          columns.add(new PropertyColumn(new Model("Username"),
> >>> "username", "username"));
> >>>          columns.add(new PropertyColumn(new Model("First Name"),
> >>> "firstName", "firstName"));
> >>>          columns.add(new PropertyColumn(new Model("Last Name"),
> >>> "lastName", "lastName"));
> >>>
> >>>          add(new DefaultDataTable("table", columns, new
> >>> SortableUserDataProvider(), 10));
> >>>         }
> >>>
> >>>
> >>> ====================================
> >>> SecurePanelLink
> >>> ====================================
> >>> public class SecurePanelLink extends Link implements
> >>> ISecureComponent {
> >>>
> >>>         /**
> >>>          *
> >>>          */
> >>>         private static final long serialVersionUID = 1L;
> >>>
> >>>         protected IPanelLink panelLink;
> >>>
> >>>         /**
> >>>          * @param id
> >>>          * @param c
> >>>          */
> >>>         public SecurePanelLink(String id, final Class c)
> >>>         {
> >>>                 super(id);
> >>>                 // Ensure that c is a subclass of Panel
> >>>                 if (!Panel.class.isAssignableFrom(c))
> >>>                 {
> >>>                         throw new IllegalArgumentException("Class
> >>> " + c +
> >>> " is not a
> >>> subclass of Panel");
> >>>                 }
> >>>
> >>>                 this.panelLink = createIPanelLink( id, c );
> >>>                 setSecurityCheck(new LinkSecurityCheck(this, c));
> >>>         }
> >>>
> >>>         public SecurePanelLink(String id, final Class c, Model
> >>> existingPanel)
> >>>         {
> >>>                 super(id);
> >>>                 // Ensure that c is a subclass of Panel
> >>>                 if (!Panel.class.isAssignableFrom(c))
> >>>                 {
> >>>                         throw new IllegalArgumentException("Class
> >>> " + c +
> >>> " is not a
> >>> subclass of Panel");
> >>>                 }
> >>>
> >>>                 this.panelLink = createIPanelLink( id, c );
> >>>                 setSecurityCheck(new LinkSecurityCheck(this, c));
> >>>         }
> >>>
> >>>         private IPanelLink createIPanelLink( String id, final
> >>> Class c ) {
> >>>                 return new IPanelLink()
> >>>                 {
> >>>                         private static final long
> >>> serialVersionUID = 1L;
> >>>
> >>>                         public Panel getPanel( String id )
> >>>                         {
> >>>                                 // Create panel using panel factory
> >>>                                 return getPanelFactory().newPanel
> >>> (id, c );
> >>>                         }
> >>>
> >>>                         public Panel getPanel( String id, IModel
> >>> model)
> >>>                         {
> >>>                                 // Create panel using panel factory
> >>>                                 return getPanelFactory().newPanel
> >>> (id, c,
> >>> model);
> >>>                         }
> >>>
> >>>                         public Panel getPanel( Panel panel,
> >>> IModel model)
> >>>                         {
> >>>                                 // Create panel using panel factory
> >>>                                 return getPanelFactory().newPanel(
> >>> panel.getId(), c, model);
> >>>                         }
> >>>
> >>>                         public Class getPanelIdentity()
> >>>                         {
> >>>                                 return c;
> >>>                         }
> >>>                 };
> >>>         }
> >>>
> >>>         /**
> >>>          *
> >>>          */
> >>>         public static SecurePanelLink createSecurePanelLink
> >>> ( String id,
> >>> Class clazz ) {
> >>>                 return new SecurePanelLink( id, clazz ) {
> >>>                         /**
> >>>                          *
> >>>                          */
> >>>                         private static final long
> >>> serialVersionUID = 1L;
> >>>
> >>>                         public void onClick() {
> >>>                                 Panel panel = ((Panel)findParent(
> >>> Panel.class));
> >>>                                 panel.replaceWith
> >>> ( panelLink.getPanel(
> >>> panel.getId() ) );
> >>>                         }
> >>>                 };
> >>>         }
> >>>
> >>>         /**
> >>>          *
> >>>          */
> >>>         public static SecurePanelLink createSecurePanelLink
> >>> ( String id,
> >>> Class newPanel, final IModel model ) {
> >>>                 return new SecurePanelLink( id, newPanel ) {
> >>>                         /**
> >>>                          *
> >>>                          */
> >>>                         private static final long
> >>> serialVersionUID = 1L;
> >>>
> >>>                         public void onClick() {
> >>>                                 Panel panel = ((Panel)findParent(
> >>> Panel.class));
> >>>                                 panel.replaceWith
> >>> ( panelLink.getPanel(
> >>> panel.getId(), model ) );
> >>>                         }
> >>>                 };
> >>>         }
> >>>
> >>>         /**
> >>>          *
> >>>          */
> >>>         public static SecurePanelLink createSecurePanelLink
> >>> ( String id,
> >>> final Model existingPanel, Class newPanel, final IModel model ) {
> >>>                 return new SecurePanelLink( id, newPanel,
> >>> existingPanel )
> >>> {
> >>>                         /**
> >>>                          *
> >>>                          */
> >>>                         private static final long
> >>> serialVersionUID = 1L;
> >>>
> >>>
> >>>                         public void onClick() {
> >>>                                 Panel p =
> >>> (Panel)existingPanel.getObject();
> >>>                                 Panel panel = panelLink.getPanel
> >>> ((Panel)existingPanel.getObject
> >>> (), model );
> >>>                                 panel.setOutputMarkupId(true);
> >>>                                 p.getParent().replace( panel );
> >>>                                 p=panel;
> >>>                         }
> >>>                 };
> >>>         }
> >>>
> >>
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Wasp/Swarm Questions was Re: Component parent null after replace

Posted by Anthony Schexnaildre <ap...@gmail.com>.
Please hijack away.

I have been quite happy with Wasp and Swarm. It's simple and painless  
but quite flexible. The examples are the life saver though. To be  
honest, the security framework is why I chose to use Wicket for this  
project instead of Tapestry.

I am however having a few issues figuring out some "best practices"  
that maybe you or some other experienced Wasp/Swarm users may be able  
to shed some light on.

1. Where would you store a reference to the logged in user. Currently  
have it in a DetachableModel in a custom session. There has to be a  
better place to put the user reference that fits more directly with  
the security framework.

2. I very much like your SecureTab example but something like a  
SecurePanelLink within the framework would be helpful. I have been  
working on my own that mirrors the SecurePageLink as much as possible  
but it is still a bit wonky. This is helpful because once you get  
into a tab layout, navigation to other panels that are not directly  
attached to a tab becomes annoying at best. I am working through it  
but seems like someone must have solved this issues a few times over  
in an elegant fashion. Maybe some kind of "panel stack" with tab  
integration?

3. I don't understand the DataPermissions, configuration and their  
use cases. I must admit I have not spent the time to dig through the  
example extensively but I don't understand the use cases enough to  
know why I would want to spend the time.

4. I am working on an application that will eventually have very  
complicated permission structure. Right now I am fumbling a solution  
together for phase one. Eventually I would like to be able to  
"filter" the date returned to a user based on some permissions while  
not coupling the security layer to the Dao's to tightly. A typical  
structure would be as follows:

O - Organisation
U - User

         O
      /  / \  \
    /   |   |   \
   U U U O
              /  |  \
            U O O
              / |    |   \
            U U  U  U

Consider a use case where you have a hierarchy of Financial  
Transaction Processors with the following 2 user types/principals:

Customer Service - Allowed to see transactions and act on them if the  
transactions are for their direct organisation
Billing - Allowed to see transaction and act on them for their direct  
organisation and any sub-organisations

The final goal would be to have an interface much like that in the  
wicket-phonebook example where the DataProvider ( or something else )  
would feed the appropriate results out of the hibernate dao's into  
the DataTable based on the users permissions.

Any clues to some elegant approach?

-Anthony



On Sep 9, 2007, at 6:12 PM, Maurice Marrink wrote:

> Allow me to hijack this topic because my eye sees the magic word
> ISecureComponent :D
>
> Glad to come across another user of Wasp and Swarm. Any comments /
> questions about them?
>
> Maurice
>
> On 9/9/07, Igor Vaynberg <ig...@gmail.com> wrote:
>> heh, seems a lot of people run into it. the short is that you have  
>> to do
>> this:
>>
>> lets say you have a ref to the panel: private Panel panel;
>>
>> what you do is this:
>> panel.replaceWith(new Panel());
>>
>> and then later again
>> panel.replaceWith(new Panel());
>>
>> ^ the second time will fail beause you have removed panel from  
>> hierarchy
>> already - you replaced it with another panel.
>>
>> the proper way to do it is to keep the reference up to date, so
>> Panel temp=new Panel();
>> panel.replaceWith(temp);
>> panel=temp;
>>
>> that way when it happens the second time it will properly act on  
>> the new
>> panel that is inside the hierarchy now.
>>
>> -igor
>>
>>
>>
>>
>> On 9/9/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
>>>
>>> I am trying to create a link that will replace one panel with  
>>> another
>>> on the page. This seems as though it should be an easy task but  
>>> after
>>> many attempts and searching the net for examples I have yet to  
>>> get it
>>> working so the replacement can happen more than one without the
>>> component becoming orphaned. On the second replace attempt i get the
>>> following exception. Anyone have the solution?
>>>
>>> Thank you,
>>>
>>> Anthony
>>>
>>>
>>> java.lang.IllegalStateException: This method can only be called on a
>>> component that has already been added to its parent.
>>>       at org.apache.wicket.Component.replaceWith(Component.java: 
>>> 2266)
>>>       at com.pinwise.pinbase.web.components.links.SecurePanelLink
>>> $4.onClick(SecurePanelLink.java:142)
>>>       at org.apache.wicket.markup.html.link.Link.onLinkClicked
>>> (Link.java:222)
>>>       at java.lang.reflect.Method.invoke(Method.java:585)
>>>       at org.apache.wicket.RequestListenerInterface.invoke
>>> (RequestListenerInterface.java:186)
>>>
>>>
>>> =====================================
>>>
>>> =====================================
>>>
>>>         public UserPanel(String id) {
>>>                 super(id);
>>>
>>>
>>>                 UserFormPanel userFormPanel = new
>>> UserFormPanel("userFormPanel");
>>>                 add( userFormPanel );
>>>
>>>                 List<IColumn> columns = new ArrayList<IColumn>();
>>>                 final Model m = new Model(userFormPanel);
>>>          columns.add(new PropertyColumn(new Model("Actions"), "id")
>>>          {
>>>                         public void populateItem(Item cellItem,  
>>> String
>>> componentId, final
>>> IModel model)
>>>              {
>>>                                 EditActionPanel panel = new
>>> EditActionPanel(componentId, model);
>>>                                 panel.add(
>>> SecurePanelLink.createSecurePanelLink( "edit", m,
>>> UserFormPanel.class, model ) );
>>>                cellItem.add( panel );
>>>              }
>>>          });
>>>
>>>          columns.add(new PropertyColumn(new Model("Username"),
>>> "username", "username"));
>>>          columns.add(new PropertyColumn(new Model("First Name"),
>>> "firstName", "firstName"));
>>>          columns.add(new PropertyColumn(new Model("Last Name"),
>>> "lastName", "lastName"));
>>>
>>>          add(new DefaultDataTable("table", columns, new
>>> SortableUserDataProvider(), 10));
>>>         }
>>>
>>>
>>> ====================================
>>> SecurePanelLink
>>> ====================================
>>> public class SecurePanelLink extends Link implements  
>>> ISecureComponent {
>>>
>>>         /**
>>>          *
>>>          */
>>>         private static final long serialVersionUID = 1L;
>>>
>>>         protected IPanelLink panelLink;
>>>
>>>         /**
>>>          * @param id
>>>          * @param c
>>>          */
>>>         public SecurePanelLink(String id, final Class c)
>>>         {
>>>                 super(id);
>>>                 // Ensure that c is a subclass of Panel
>>>                 if (!Panel.class.isAssignableFrom(c))
>>>                 {
>>>                         throw new IllegalArgumentException("Class  
>>> " + c +
>>> " is not a
>>> subclass of Panel");
>>>                 }
>>>
>>>                 this.panelLink = createIPanelLink( id, c );
>>>                 setSecurityCheck(new LinkSecurityCheck(this, c));
>>>         }
>>>
>>>         public SecurePanelLink(String id, final Class c, Model
>>> existingPanel)
>>>         {
>>>                 super(id);
>>>                 // Ensure that c is a subclass of Panel
>>>                 if (!Panel.class.isAssignableFrom(c))
>>>                 {
>>>                         throw new IllegalArgumentException("Class  
>>> " + c +
>>> " is not a
>>> subclass of Panel");
>>>                 }
>>>
>>>                 this.panelLink = createIPanelLink( id, c );
>>>                 setSecurityCheck(new LinkSecurityCheck(this, c));
>>>         }
>>>
>>>         private IPanelLink createIPanelLink( String id, final  
>>> Class c ) {
>>>                 return new IPanelLink()
>>>                 {
>>>                         private static final long  
>>> serialVersionUID = 1L;
>>>
>>>                         public Panel getPanel( String id )
>>>                         {
>>>                                 // Create panel using panel factory
>>>                                 return getPanelFactory().newPanel 
>>> (id, c );
>>>                         }
>>>
>>>                         public Panel getPanel( String id, IModel  
>>> model)
>>>                         {
>>>                                 // Create panel using panel factory
>>>                                 return getPanelFactory().newPanel 
>>> (id, c,
>>> model);
>>>                         }
>>>
>>>                         public Panel getPanel( Panel panel,  
>>> IModel model)
>>>                         {
>>>                                 // Create panel using panel factory
>>>                                 return getPanelFactory().newPanel(
>>> panel.getId(), c, model);
>>>                         }
>>>
>>>                         public Class getPanelIdentity()
>>>                         {
>>>                                 return c;
>>>                         }
>>>                 };
>>>         }
>>>
>>>         /**
>>>          *
>>>          */
>>>         public static SecurePanelLink createSecurePanelLink 
>>> ( String id,
>>> Class clazz ) {
>>>                 return new SecurePanelLink( id, clazz ) {
>>>                         /**
>>>                          *
>>>                          */
>>>                         private static final long  
>>> serialVersionUID = 1L;
>>>
>>>                         public void onClick() {
>>>                                 Panel panel = ((Panel)findParent(
>>> Panel.class));
>>>                                 panel.replaceWith 
>>> ( panelLink.getPanel(
>>> panel.getId() ) );
>>>                         }
>>>                 };
>>>         }
>>>
>>>         /**
>>>          *
>>>          */
>>>         public static SecurePanelLink createSecurePanelLink 
>>> ( String id,
>>> Class newPanel, final IModel model ) {
>>>                 return new SecurePanelLink( id, newPanel ) {
>>>                         /**
>>>                          *
>>>                          */
>>>                         private static final long  
>>> serialVersionUID = 1L;
>>>
>>>                         public void onClick() {
>>>                                 Panel panel = ((Panel)findParent(
>>> Panel.class));
>>>                                 panel.replaceWith 
>>> ( panelLink.getPanel(
>>> panel.getId(), model ) );
>>>                         }
>>>                 };
>>>         }
>>>
>>>         /**
>>>          *
>>>          */
>>>         public static SecurePanelLink createSecurePanelLink 
>>> ( String id,
>>> final Model existingPanel, Class newPanel, final IModel model ) {
>>>                 return new SecurePanelLink( id, newPanel,  
>>> existingPanel )
>>> {
>>>                         /**
>>>                          *
>>>                          */
>>>                         private static final long  
>>> serialVersionUID = 1L;
>>>
>>>
>>>                         public void onClick() {
>>>                                 Panel p =
>>> (Panel)existingPanel.getObject();
>>>                                 Panel panel = panelLink.getPanel
>>> ((Panel)existingPanel.getObject
>>> (), model );
>>>                                 panel.setOutputMarkupId(true);
>>>                                 p.getParent().replace( panel );
>>>                                 p=panel;
>>>                         }
>>>                 };
>>>         }
>>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Component parent null after replace

Posted by Maurice Marrink <ma...@gmail.com>.
Allow me to hijack this topic because my eye sees the magic word
ISecureComponent :D

Glad to come across another user of Wasp and Swarm. Any comments /
questions about them?

Maurice

On 9/9/07, Igor Vaynberg <ig...@gmail.com> wrote:
> heh, seems a lot of people run into it. the short is that you have to do
> this:
>
> lets say you have a ref to the panel: private Panel panel;
>
> what you do is this:
> panel.replaceWith(new Panel());
>
> and then later again
> panel.replaceWith(new Panel());
>
> ^ the second time will fail beause you have removed panel from hierarchy
> already - you replaced it with another panel.
>
> the proper way to do it is to keep the reference up to date, so
> Panel temp=new Panel();
> panel.replaceWith(temp);
> panel=temp;
>
> that way when it happens the second time it will properly act on the new
> panel that is inside the hierarchy now.
>
> -igor
>
>
>
>
> On 9/9/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
> >
> > I am trying to create a link that will replace one panel with another
> > on the page. This seems as though it should be an easy task but after
> > many attempts and searching the net for examples I have yet to get it
> > working so the replacement can happen more than one without the
> > component becoming orphaned. On the second replace attempt i get the
> > following exception. Anyone have the solution?
> >
> > Thank you,
> >
> > Anthony
> >
> >
> > java.lang.IllegalStateException: This method can only be called on a
> > component that has already been added to its parent.
> >       at org.apache.wicket.Component.replaceWith(Component.java:2266)
> >       at com.pinwise.pinbase.web.components.links.SecurePanelLink
> > $4.onClick(SecurePanelLink.java:142)
> >       at org.apache.wicket.markup.html.link.Link.onLinkClicked
> > (Link.java:222)
> >       at java.lang.reflect.Method.invoke(Method.java:585)
> >       at org.apache.wicket.RequestListenerInterface.invoke
> > (RequestListenerInterface.java:186)
> >
> >
> > =====================================
> >
> > =====================================
> >
> >         public UserPanel(String id) {
> >                 super(id);
> >
> >
> >                 UserFormPanel userFormPanel = new
> > UserFormPanel("userFormPanel");
> >                 add( userFormPanel );
> >
> >                 List<IColumn> columns = new ArrayList<IColumn>();
> >                 final Model m = new Model(userFormPanel);
> >          columns.add(new PropertyColumn(new Model("Actions"), "id")
> >          {
> >                         public void populateItem(Item cellItem, String
> > componentId, final
> > IModel model)
> >              {
> >                                 EditActionPanel panel = new
> > EditActionPanel(componentId, model);
> >                                 panel.add(
> > SecurePanelLink.createSecurePanelLink( "edit", m,
> > UserFormPanel.class, model ) );
> >                cellItem.add( panel );
> >              }
> >          });
> >
> >          columns.add(new PropertyColumn(new Model("Username"),
> > "username", "username"));
> >          columns.add(new PropertyColumn(new Model("First Name"),
> > "firstName", "firstName"));
> >          columns.add(new PropertyColumn(new Model("Last Name"),
> > "lastName", "lastName"));
> >
> >          add(new DefaultDataTable("table", columns, new
> > SortableUserDataProvider(), 10));
> >         }
> >
> >
> > ====================================
> > SecurePanelLink
> > ====================================
> > public class SecurePanelLink extends Link implements ISecureComponent {
> >
> >         /**
> >          *
> >          */
> >         private static final long serialVersionUID = 1L;
> >
> >         protected IPanelLink panelLink;
> >
> >         /**
> >          * @param id
> >          * @param c
> >          */
> >         public SecurePanelLink(String id, final Class c)
> >         {
> >                 super(id);
> >                 // Ensure that c is a subclass of Panel
> >                 if (!Panel.class.isAssignableFrom(c))
> >                 {
> >                         throw new IllegalArgumentException("Class " + c +
> > " is not a
> > subclass of Panel");
> >                 }
> >
> >                 this.panelLink = createIPanelLink( id, c );
> >                 setSecurityCheck(new LinkSecurityCheck(this, c));
> >         }
> >
> >         public SecurePanelLink(String id, final Class c, Model
> > existingPanel)
> >         {
> >                 super(id);
> >                 // Ensure that c is a subclass of Panel
> >                 if (!Panel.class.isAssignableFrom(c))
> >                 {
> >                         throw new IllegalArgumentException("Class " + c +
> > " is not a
> > subclass of Panel");
> >                 }
> >
> >                 this.panelLink = createIPanelLink( id, c );
> >                 setSecurityCheck(new LinkSecurityCheck(this, c));
> >         }
> >
> >         private IPanelLink createIPanelLink( String id, final Class c ) {
> >                 return new IPanelLink()
> >                 {
> >                         private static final long serialVersionUID = 1L;
> >
> >                         public Panel getPanel( String id )
> >                         {
> >                                 // Create panel using panel factory
> >                                 return getPanelFactory().newPanel(id, c );
> >                         }
> >
> >                         public Panel getPanel( String id, IModel model)
> >                         {
> >                                 // Create panel using panel factory
> >                                 return getPanelFactory().newPanel(id, c,
> > model);
> >                         }
> >
> >                         public Panel getPanel( Panel panel, IModel model)
> >                         {
> >                                 // Create panel using panel factory
> >                                 return getPanelFactory().newPanel(
> > panel.getId(), c, model);
> >                         }
> >
> >                         public Class getPanelIdentity()
> >                         {
> >                                 return c;
> >                         }
> >                 };
> >         }
> >
> >         /**
> >          *
> >          */
> >         public static SecurePanelLink createSecurePanelLink( String id,
> > Class clazz ) {
> >                 return new SecurePanelLink( id, clazz ) {
> >                         /**
> >                          *
> >                          */
> >                         private static final long serialVersionUID = 1L;
> >
> >                         public void onClick() {
> >                                 Panel panel = ((Panel)findParent(
> > Panel.class));
> >                                 panel.replaceWith( panelLink.getPanel(
> > panel.getId() ) );
> >                         }
> >                 };
> >         }
> >
> >         /**
> >          *
> >          */
> >         public static SecurePanelLink createSecurePanelLink( String id,
> > Class newPanel, final IModel model ) {
> >                 return new SecurePanelLink( id, newPanel ) {
> >                         /**
> >                          *
> >                          */
> >                         private static final long serialVersionUID = 1L;
> >
> >                         public void onClick() {
> >                                 Panel panel = ((Panel)findParent(
> > Panel.class));
> >                                 panel.replaceWith( panelLink.getPanel(
> > panel.getId(), model ) );
> >                         }
> >                 };
> >         }
> >
> >         /**
> >          *
> >          */
> >         public static SecurePanelLink createSecurePanelLink( String id,
> > final Model existingPanel, Class newPanel, final IModel model ) {
> >                 return new SecurePanelLink( id, newPanel, existingPanel )
> > {
> >                         /**
> >                          *
> >                          */
> >                         private static final long serialVersionUID = 1L;
> >
> >
> >                         public void onClick() {
> >                                 Panel p =
> > (Panel)existingPanel.getObject();
> >                                 Panel panel = panelLink.getPanel
> > ((Panel)existingPanel.getObject
> > (), model );
> >                                 panel.setOutputMarkupId(true);
> >                                 p.getParent().replace( panel );
> >                                 p=panel;
> >                         }
> >                 };
> >         }
> >
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Component parent null after replace

Posted by Pedro Santos <pe...@gmail.com>.
referenceToDatabaseParentComponent.replace(replacement)
you has an reference to referenceToDatabaseParentComponent, right?

On Fri, Oct 23, 2009 at 4:05 AM, wicketnewuser <sw...@hotmail.com> wrote:

>
> Hi I have similiar situation but i'm using autonomous  inner class
>        final AjaxFallbackDefaultDataTable datatable = new
> AjaxFallbackDefaultDataTable("trafficreportlistdatatable", columns, new
> ReportListProvider("Traffic", include), 8);
>                add(datatable);
>            final WebMarkupContainer showMineSpan = new
> WebMarkupContainer("showMineSpan");
>                final WebMarkupContainer showAllSpan = new
> WebMarkupContainer("showAllSpan");
>                  final Link showAllLink = new
> AjaxFallbackLink("trafficreportlistshowall") {
>                                public void onClick(AjaxRequestTarget
> target) {
>                                        AjaxFallbackDefaultDataTable
> replacement = new
> AjaxFallbackDefaultDataTable("trafficreportlistdatatable", columns, new
> ReportListProvider("Traffic", "all"), 8);
>                                        //this.replaceWith(replacement);
>                                        replacement.setOutputMarkupId(true);
>
>                                        datatable.replaceWith(replacement);
>
> I can't do datatable = replacement as datatable has to be final in my case
> as i'm using it in the anonymous  inner class. Do you know if there is any
> solution to this. Would appreciate your help
>
>
>
> igor.vaynberg wrote:
> >
> > heh, seems a lot of people run into it. the short is that you have to do
> > this:
> >
> > lets say you have a ref to the panel: private Panel panel;
> >
> > what you do is this:
> > panel.replaceWith(new Panel());
> >
> > and then later again
> > panel.replaceWith(new Panel());
> >
> > ^ the second time will fail beause you have removed panel from hierarchy
> > already - you replaced it with another panel.
> >
> > the proper way to do it is to keep the reference up to date, so
> > Panel temp=new Panel();
> > panel.replaceWith(temp);
> > panel=temp;
> >
> > that way when it happens the second time it will properly act on the new
> > panel that is inside the hierarchy now.
> >
> > -igor
> >
> >
> >
> >
> > On 9/9/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
> >>
> >> I am trying to create a link that will replace one panel with another
> >> on the page. This seems as though it should be an easy task but after
> >> many attempts and searching the net for examples I have yet to get it
> >> working so the replacement can happen more than one without the
> >> component becoming orphaned. On the second replace attempt i get the
> >> following exception. Anyone have the solution?
> >>
> >> Thank you,
> >>
> >> Anthony
> >>
> >>
> >> java.lang.IllegalStateException: This method can only be called on a
> >> component that has already been added to its parent.
> >>       at org.apache.wicket.Component.replaceWith(Component.java:2266)
> >>       at com.pinwise.pinbase.web.components.links.SecurePanelLink
> >> $4.onClick(SecurePanelLink.java:142)
> >>       at org.apache.wicket.markup.html.link.Link.onLinkClicked
> >> (Link.java:222)
> >>       at java.lang.reflect.Method.invoke(Method.java:585)
> >>       at org.apache.wicket.RequestListenerInterface.invoke
> >> (RequestListenerInterface.java:186)
> >>
> >>
> >> =====================================
> >>
> >> =====================================
> >>
> >>         public UserPanel(String id) {
> >>                 super(id);
> >>
> >>
> >>                 UserFormPanel userFormPanel = new
> >> UserFormPanel("userFormPanel");
> >>                 add( userFormPanel );
> >>
> >>                 List<IColumn> columns = new ArrayList<IColumn>();
> >>                 final Model m = new Model(userFormPanel);
> >>          columns.add(new PropertyColumn(new Model("Actions"), "id")
> >>          {
> >>                         public void populateItem(Item cellItem, String
> >> componentId, final
> >> IModel model)
> >>              {
> >>                                 EditActionPanel panel = new
> >> EditActionPanel(componentId, model);
> >>                                 panel.add(
> >> SecurePanelLink.createSecurePanelLink( "edit", m,
> >> UserFormPanel.class, model ) );
> >>                cellItem.add( panel );
> >>              }
> >>          });
> >>
> >>          columns.add(new PropertyColumn(new Model("Username"),
> >> "username", "username"));
> >>          columns.add(new PropertyColumn(new Model("First Name"),
> >> "firstName", "firstName"));
> >>          columns.add(new PropertyColumn(new Model("Last Name"),
> >> "lastName", "lastName"));
> >>
> >>          add(new DefaultDataTable("table", columns, new
> >> SortableUserDataProvider(), 10));
> >>         }
> >>
> >>
> >> ====================================
> >> SecurePanelLink
> >> ====================================
> >> public class SecurePanelLink extends Link implements ISecureComponent {
> >>
> >>         /**
> >>          *
> >>          */
> >>         private static final long serialVersionUID = 1L;
> >>
> >>         protected IPanelLink panelLink;
> >>
> >>         /**
> >>          * @param id
> >>          * @param c
> >>          */
> >>         public SecurePanelLink(String id, final Class c)
> >>         {
> >>                 super(id);
> >>                 // Ensure that c is a subclass of Panel
> >>                 if (!Panel.class.isAssignableFrom(c))
> >>                 {
> >>                         throw new IllegalArgumentException("Class " + c
> +
> >> " is not a
> >> subclass of Panel");
> >>                 }
> >>
> >>                 this.panelLink = createIPanelLink( id, c );
> >>                 setSecurityCheck(new LinkSecurityCheck(this, c));
> >>         }
> >>
> >>         public SecurePanelLink(String id, final Class c, Model
> >> existingPanel)
> >>         {
> >>                 super(id);
> >>                 // Ensure that c is a subclass of Panel
> >>                 if (!Panel.class.isAssignableFrom(c))
> >>                 {
> >>                         throw new IllegalArgumentException("Class " + c
> +
> >> " is not a
> >> subclass of Panel");
> >>                 }
> >>
> >>                 this.panelLink = createIPanelLink( id, c );
> >>                 setSecurityCheck(new LinkSecurityCheck(this, c));
> >>         }
> >>
> >>         private IPanelLink createIPanelLink( String id, final Class c )
> {
> >>                 return new IPanelLink()
> >>                 {
> >>                         private static final long serialVersionUID = 1L;
> >>
> >>                         public Panel getPanel( String id )
> >>                         {
> >>                                 // Create panel using panel factory
> >>                                 return getPanelFactory().newPanel(id, c
> >> );
> >>                         }
> >>
> >>                         public Panel getPanel( String id, IModel model)
> >>                         {
> >>                                 // Create panel using panel factory
> >>                                 return getPanelFactory().newPanel(id, c,
> >> model);
> >>                         }
> >>
> >>                         public Panel getPanel( Panel panel, IModel
> model)
> >>                         {
> >>                                 // Create panel using panel factory
> >>                                 return getPanelFactory().newPanel(
> >> panel.getId(), c, model);
> >>                         }
> >>
> >>                         public Class getPanelIdentity()
> >>                         {
> >>                                 return c;
> >>                         }
> >>                 };
> >>         }
> >>
> >>         /**
> >>          *
> >>          */
> >>         public static SecurePanelLink createSecurePanelLink( String id,
> >> Class clazz ) {
> >>                 return new SecurePanelLink( id, clazz ) {
> >>                         /**
> >>                          *
> >>                          */
> >>                         private static final long serialVersionUID = 1L;
> >>
> >>                         public void onClick() {
> >>                                 Panel panel = ((Panel)findParent(
> >> Panel.class));
> >>                                 panel.replaceWith( panelLink.getPanel(
> >> panel.getId() ) );
> >>                         }
> >>                 };
> >>         }
> >>
> >>         /**
> >>          *
> >>          */
> >>         public static SecurePanelLink createSecurePanelLink( String id,
> >> Class newPanel, final IModel model ) {
> >>                 return new SecurePanelLink( id, newPanel ) {
> >>                         /**
> >>                          *
> >>                          */
> >>                         private static final long serialVersionUID = 1L;
> >>
> >>                         public void onClick() {
> >>                                 Panel panel = ((Panel)findParent(
> >> Panel.class));
> >>                                 panel.replaceWith( panelLink.getPanel(
> >> panel.getId(), model ) );
> >>                         }
> >>                 };
> >>         }
> >>
> >>         /**
> >>          *
> >>          */
> >>         public static SecurePanelLink createSecurePanelLink( String id,
> >> final Model existingPanel, Class newPanel, final IModel model ) {
> >>                 return new SecurePanelLink( id, newPanel, existingPanel
> )
> >> {
> >>                         /**
> >>                          *
> >>                          */
> >>                         private static final long serialVersionUID = 1L;
> >>
> >>
> >>                         public void onClick() {
> >>                                 Panel p =
> >> (Panel)existingPanel.getObject();
> >>                                 Panel panel = panelLink.getPanel
> >> ((Panel)existingPanel.getObject
> >> (), model );
> >>                                 panel.setOutputMarkupId(true);
> >>                                 p.getParent().replace( panel );
> >>                                 p=panel;
> >>                         }
> >>                 };
> >>         }
> >>
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/Component-parent-null-after-replace-tp12576967p26021314.html
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>


-- 
Pedro Henrique Oliveira dos Santos

Re: Component parent null after replace

Posted by wicketnewuser <sw...@hotmail.com>.
Hi I have similiar situation but i'm using autonomous  inner class
	final AjaxFallbackDefaultDataTable datatable = new
AjaxFallbackDefaultDataTable("trafficreportlistdatatable", columns, new
ReportListProvider("Traffic", include), 8);
		add(datatable);
	    final WebMarkupContainer showMineSpan = new
WebMarkupContainer("showMineSpan");
		final WebMarkupContainer showAllSpan = new
WebMarkupContainer("showAllSpan");
		  final Link showAllLink = new
AjaxFallbackLink("trafficreportlistshowall") { 
				public void onClick(AjaxRequestTarget target) {
					AjaxFallbackDefaultDataTable replacement = new
AjaxFallbackDefaultDataTable("trafficreportlistdatatable", columns, new
ReportListProvider("Traffic", "all"), 8);
					//this.replaceWith(replacement);
					replacement.setOutputMarkupId(true);
					
					datatable.replaceWith(replacement);

I can't do datatable = replacement as datatable has to be final in my case
as i'm using it in the anonymous  inner class. Do you know if there is any
solution to this. Would appreciate your help



igor.vaynberg wrote:
> 
> heh, seems a lot of people run into it. the short is that you have to do
> this:
> 
> lets say you have a ref to the panel: private Panel panel;
> 
> what you do is this:
> panel.replaceWith(new Panel());
> 
> and then later again
> panel.replaceWith(new Panel());
> 
> ^ the second time will fail beause you have removed panel from hierarchy
> already - you replaced it with another panel.
> 
> the proper way to do it is to keep the reference up to date, so
> Panel temp=new Panel();
> panel.replaceWith(temp);
> panel=temp;
> 
> that way when it happens the second time it will properly act on the new
> panel that is inside the hierarchy now.
> 
> -igor
> 
> 
> 
> 
> On 9/9/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
>>
>> I am trying to create a link that will replace one panel with another
>> on the page. This seems as though it should be an easy task but after
>> many attempts and searching the net for examples I have yet to get it
>> working so the replacement can happen more than one without the
>> component becoming orphaned. On the second replace attempt i get the
>> following exception. Anyone have the solution?
>>
>> Thank you,
>>
>> Anthony
>>
>>
>> java.lang.IllegalStateException: This method can only be called on a
>> component that has already been added to its parent.
>>       at org.apache.wicket.Component.replaceWith(Component.java:2266)
>>       at com.pinwise.pinbase.web.components.links.SecurePanelLink
>> $4.onClick(SecurePanelLink.java:142)
>>       at org.apache.wicket.markup.html.link.Link.onLinkClicked
>> (Link.java:222)
>>       at java.lang.reflect.Method.invoke(Method.java:585)
>>       at org.apache.wicket.RequestListenerInterface.invoke
>> (RequestListenerInterface.java:186)
>>
>>
>> =====================================
>>
>> =====================================
>>
>>         public UserPanel(String id) {
>>                 super(id);
>>
>>
>>                 UserFormPanel userFormPanel = new
>> UserFormPanel("userFormPanel");
>>                 add( userFormPanel );
>>
>>                 List<IColumn> columns = new ArrayList<IColumn>();
>>                 final Model m = new Model(userFormPanel);
>>          columns.add(new PropertyColumn(new Model("Actions"), "id")
>>          {
>>                         public void populateItem(Item cellItem, String
>> componentId, final
>> IModel model)
>>              {
>>                                 EditActionPanel panel = new
>> EditActionPanel(componentId, model);
>>                                 panel.add(
>> SecurePanelLink.createSecurePanelLink( "edit", m,
>> UserFormPanel.class, model ) );
>>                cellItem.add( panel );
>>              }
>>          });
>>
>>          columns.add(new PropertyColumn(new Model("Username"),
>> "username", "username"));
>>          columns.add(new PropertyColumn(new Model("First Name"),
>> "firstName", "firstName"));
>>          columns.add(new PropertyColumn(new Model("Last Name"),
>> "lastName", "lastName"));
>>
>>          add(new DefaultDataTable("table", columns, new
>> SortableUserDataProvider(), 10));
>>         }
>>
>>
>> ====================================
>> SecurePanelLink
>> ====================================
>> public class SecurePanelLink extends Link implements ISecureComponent {
>>
>>         /**
>>          *
>>          */
>>         private static final long serialVersionUID = 1L;
>>
>>         protected IPanelLink panelLink;
>>
>>         /**
>>          * @param id
>>          * @param c
>>          */
>>         public SecurePanelLink(String id, final Class c)
>>         {
>>                 super(id);
>>                 // Ensure that c is a subclass of Panel
>>                 if (!Panel.class.isAssignableFrom(c))
>>                 {
>>                         throw new IllegalArgumentException("Class " + c +
>> " is not a
>> subclass of Panel");
>>                 }
>>
>>                 this.panelLink = createIPanelLink( id, c );
>>                 setSecurityCheck(new LinkSecurityCheck(this, c));
>>         }
>>
>>         public SecurePanelLink(String id, final Class c, Model
>> existingPanel)
>>         {
>>                 super(id);
>>                 // Ensure that c is a subclass of Panel
>>                 if (!Panel.class.isAssignableFrom(c))
>>                 {
>>                         throw new IllegalArgumentException("Class " + c +
>> " is not a
>> subclass of Panel");
>>                 }
>>
>>                 this.panelLink = createIPanelLink( id, c );
>>                 setSecurityCheck(new LinkSecurityCheck(this, c));
>>         }
>>
>>         private IPanelLink createIPanelLink( String id, final Class c ) {
>>                 return new IPanelLink()
>>                 {
>>                         private static final long serialVersionUID = 1L;
>>
>>                         public Panel getPanel( String id )
>>                         {
>>                                 // Create panel using panel factory
>>                                 return getPanelFactory().newPanel(id, c
>> );
>>                         }
>>
>>                         public Panel getPanel( String id, IModel model)
>>                         {
>>                                 // Create panel using panel factory
>>                                 return getPanelFactory().newPanel(id, c,
>> model);
>>                         }
>>
>>                         public Panel getPanel( Panel panel, IModel model)
>>                         {
>>                                 // Create panel using panel factory
>>                                 return getPanelFactory().newPanel(
>> panel.getId(), c, model);
>>                         }
>>
>>                         public Class getPanelIdentity()
>>                         {
>>                                 return c;
>>                         }
>>                 };
>>         }
>>
>>         /**
>>          *
>>          */
>>         public static SecurePanelLink createSecurePanelLink( String id,
>> Class clazz ) {
>>                 return new SecurePanelLink( id, clazz ) {
>>                         /**
>>                          *
>>                          */
>>                         private static final long serialVersionUID = 1L;
>>
>>                         public void onClick() {
>>                                 Panel panel = ((Panel)findParent(
>> Panel.class));
>>                                 panel.replaceWith( panelLink.getPanel(
>> panel.getId() ) );
>>                         }
>>                 };
>>         }
>>
>>         /**
>>          *
>>          */
>>         public static SecurePanelLink createSecurePanelLink( String id,
>> Class newPanel, final IModel model ) {
>>                 return new SecurePanelLink( id, newPanel ) {
>>                         /**
>>                          *
>>                          */
>>                         private static final long serialVersionUID = 1L;
>>
>>                         public void onClick() {
>>                                 Panel panel = ((Panel)findParent(
>> Panel.class));
>>                                 panel.replaceWith( panelLink.getPanel(
>> panel.getId(), model ) );
>>                         }
>>                 };
>>         }
>>
>>         /**
>>          *
>>          */
>>         public static SecurePanelLink createSecurePanelLink( String id,
>> final Model existingPanel, Class newPanel, final IModel model ) {
>>                 return new SecurePanelLink( id, newPanel, existingPanel )
>> {
>>                         /**
>>                          *
>>                          */
>>                         private static final long serialVersionUID = 1L;
>>
>>
>>                         public void onClick() {
>>                                 Panel p =
>> (Panel)existingPanel.getObject();
>>                                 Panel panel = panelLink.getPanel
>> ((Panel)existingPanel.getObject
>> (), model );
>>                                 panel.setOutputMarkupId(true);
>>                                 p.getParent().replace( panel );
>>                                 p=panel;
>>                         }
>>                 };
>>         }
>>
> 
> 

-- 
View this message in context: http://www.nabble.com/Component-parent-null-after-replace-tp12576967p26021314.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Component parent null after replace

Posted by Anthony Schexnaildre <ap...@gmail.com>.
Igor,

Thank you for your reply. I did see another message from you recently  
on this same topic but the key the problem was having the "private  
Panel panel;" field to store the reference.

-Anthony


On Sep 9, 2007, at 5:09 PM, Igor Vaynberg wrote:

> heh, seems a lot of people run into it. the short is that you have  
> to do
> this:
>
> lets say you have a ref to the panel: private Panel panel;
>
> what you do is this:
> panel.replaceWith(new Panel());
>
> and then later again
> panel.replaceWith(new Panel());
>
> ^ the second time will fail beause you have removed panel from  
> hierarchy
> already - you replaced it with another panel.
>
> the proper way to do it is to keep the reference up to date, so
> Panel temp=new Panel();
> panel.replaceWith(temp);
> panel=temp;
>
> that way when it happens the second time it will properly act on  
> the new
> panel that is inside the hierarchy now.
>
> -igor
>
>
>
>
> On 9/9/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
>>
>> I am trying to create a link that will replace one panel with another
>> on the page. This seems as though it should be an easy task but after
>> many attempts and searching the net for examples I have yet to get it
>> working so the replacement can happen more than one without the
>> component becoming orphaned. On the second replace attempt i get the
>> following exception. Anyone have the solution?
>>
>> Thank you,
>>
>> Anthony
>>
>>
>> java.lang.IllegalStateException: This method can only be called on a
>> component that has already been added to its parent.
>>       at org.apache.wicket.Component.replaceWith(Component.java:2266)
>>       at com.pinwise.pinbase.web.components.links.SecurePanelLink
>> $4.onClick(SecurePanelLink.java:142)
>>       at org.apache.wicket.markup.html.link.Link.onLinkClicked
>> (Link.java:222)
>>       at java.lang.reflect.Method.invoke(Method.java:585)
>>       at org.apache.wicket.RequestListenerInterface.invoke
>> (RequestListenerInterface.java:186)
>>
>>
>> =====================================
>>
>> =====================================
>>
>>         public UserPanel(String id) {
>>                 super(id);
>>
>>
>>                 UserFormPanel userFormPanel = new
>> UserFormPanel("userFormPanel");
>>                 add( userFormPanel );
>>
>>                 List<IColumn> columns = new ArrayList<IColumn>();
>>                 final Model m = new Model(userFormPanel);
>>          columns.add(new PropertyColumn(new Model("Actions"), "id")
>>          {
>>                         public void populateItem(Item cellItem,  
>> String
>> componentId, final
>> IModel model)
>>              {
>>                                 EditActionPanel panel = new
>> EditActionPanel(componentId, model);
>>                                 panel.add(
>> SecurePanelLink.createSecurePanelLink( "edit", m,
>> UserFormPanel.class, model ) );
>>                cellItem.add( panel );
>>              }
>>          });
>>
>>          columns.add(new PropertyColumn(new Model("Username"),
>> "username", "username"));
>>          columns.add(new PropertyColumn(new Model("First Name"),
>> "firstName", "firstName"));
>>          columns.add(new PropertyColumn(new Model("Last Name"),
>> "lastName", "lastName"));
>>
>>          add(new DefaultDataTable("table", columns, new
>> SortableUserDataProvider(), 10));
>>         }
>>
>>
>> ====================================
>> SecurePanelLink
>> ====================================
>> public class SecurePanelLink extends Link implements  
>> ISecureComponent {
>>
>>         /**
>>          *
>>          */
>>         private static final long serialVersionUID = 1L;
>>
>>         protected IPanelLink panelLink;
>>
>>         /**
>>          * @param id
>>          * @param c
>>          */
>>         public SecurePanelLink(String id, final Class c)
>>         {
>>                 super(id);
>>                 // Ensure that c is a subclass of Panel
>>                 if (!Panel.class.isAssignableFrom(c))
>>                 {
>>                         throw new IllegalArgumentException("Class  
>> " + c +
>> " is not a
>> subclass of Panel");
>>                 }
>>
>>                 this.panelLink = createIPanelLink( id, c );
>>                 setSecurityCheck(new LinkSecurityCheck(this, c));
>>         }
>>
>>         public SecurePanelLink(String id, final Class c, Model
>> existingPanel)
>>         {
>>                 super(id);
>>                 // Ensure that c is a subclass of Panel
>>                 if (!Panel.class.isAssignableFrom(c))
>>                 {
>>                         throw new IllegalArgumentException("Class  
>> " + c +
>> " is not a
>> subclass of Panel");
>>                 }
>>
>>                 this.panelLink = createIPanelLink( id, c );
>>                 setSecurityCheck(new LinkSecurityCheck(this, c));
>>         }
>>
>>         private IPanelLink createIPanelLink( String id, final  
>> Class c ) {
>>                 return new IPanelLink()
>>                 {
>>                         private static final long serialVersionUID  
>> = 1L;
>>
>>                         public Panel getPanel( String id )
>>                         {
>>                                 // Create panel using panel factory
>>                                 return getPanelFactory().newPanel 
>> (id, c );
>>                         }
>>
>>                         public Panel getPanel( String id, IModel  
>> model)
>>                         {
>>                                 // Create panel using panel factory
>>                                 return getPanelFactory().newPanel 
>> (id, c,
>> model);
>>                         }
>>
>>                         public Panel getPanel( Panel panel, IModel  
>> model)
>>                         {
>>                                 // Create panel using panel factory
>>                                 return getPanelFactory().newPanel(
>> panel.getId(), c, model);
>>                         }
>>
>>                         public Class getPanelIdentity()
>>                         {
>>                                 return c;
>>                         }
>>                 };
>>         }
>>
>>         /**
>>          *
>>          */
>>         public static SecurePanelLink createSecurePanelLink 
>> ( String id,
>> Class clazz ) {
>>                 return new SecurePanelLink( id, clazz ) {
>>                         /**
>>                          *
>>                          */
>>                         private static final long serialVersionUID  
>> = 1L;
>>
>>                         public void onClick() {
>>                                 Panel panel = ((Panel)findParent(
>> Panel.class));
>>                                 panel.replaceWith 
>> ( panelLink.getPanel(
>> panel.getId() ) );
>>                         }
>>                 };
>>         }
>>
>>         /**
>>          *
>>          */
>>         public static SecurePanelLink createSecurePanelLink 
>> ( String id,
>> Class newPanel, final IModel model ) {
>>                 return new SecurePanelLink( id, newPanel ) {
>>                         /**
>>                          *
>>                          */
>>                         private static final long serialVersionUID  
>> = 1L;
>>
>>                         public void onClick() {
>>                                 Panel panel = ((Panel)findParent(
>> Panel.class));
>>                                 panel.replaceWith 
>> ( panelLink.getPanel(
>> panel.getId(), model ) );
>>                         }
>>                 };
>>         }
>>
>>         /**
>>          *
>>          */
>>         public static SecurePanelLink createSecurePanelLink 
>> ( String id,
>> final Model existingPanel, Class newPanel, final IModel model ) {
>>                 return new SecurePanelLink( id, newPanel,  
>> existingPanel )
>> {
>>                         /**
>>                          *
>>                          */
>>                         private static final long serialVersionUID  
>> = 1L;
>>
>>
>>                         public void onClick() {
>>                                 Panel p =
>> (Panel)existingPanel.getObject();
>>                                 Panel panel = panelLink.getPanel
>> ((Panel)existingPanel.getObject
>> (), model );
>>                                 panel.setOutputMarkupId(true);
>>                                 p.getParent().replace( panel );
>>                                 p=panel;
>>                         }
>>                 };
>>         }
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Component parent null after replace

Posted by Igor Vaynberg <ig...@gmail.com>.
heh, seems a lot of people run into it. the short is that you have to do
this:

lets say you have a ref to the panel: private Panel panel;

what you do is this:
panel.replaceWith(new Panel());

and then later again
panel.replaceWith(new Panel());

^ the second time will fail beause you have removed panel from hierarchy
already - you replaced it with another panel.

the proper way to do it is to keep the reference up to date, so
Panel temp=new Panel();
panel.replaceWith(temp);
panel=temp;

that way when it happens the second time it will properly act on the new
panel that is inside the hierarchy now.

-igor




On 9/9/07, Anthony Schexnaildre <ap...@gmail.com> wrote:
>
> I am trying to create a link that will replace one panel with another
> on the page. This seems as though it should be an easy task but after
> many attempts and searching the net for examples I have yet to get it
> working so the replacement can happen more than one without the
> component becoming orphaned. On the second replace attempt i get the
> following exception. Anyone have the solution?
>
> Thank you,
>
> Anthony
>
>
> java.lang.IllegalStateException: This method can only be called on a
> component that has already been added to its parent.
>       at org.apache.wicket.Component.replaceWith(Component.java:2266)
>       at com.pinwise.pinbase.web.components.links.SecurePanelLink
> $4.onClick(SecurePanelLink.java:142)
>       at org.apache.wicket.markup.html.link.Link.onLinkClicked
> (Link.java:222)
>       at java.lang.reflect.Method.invoke(Method.java:585)
>       at org.apache.wicket.RequestListenerInterface.invoke
> (RequestListenerInterface.java:186)
>
>
> =====================================
>
> =====================================
>
>         public UserPanel(String id) {
>                 super(id);
>
>
>                 UserFormPanel userFormPanel = new
> UserFormPanel("userFormPanel");
>                 add( userFormPanel );
>
>                 List<IColumn> columns = new ArrayList<IColumn>();
>                 final Model m = new Model(userFormPanel);
>          columns.add(new PropertyColumn(new Model("Actions"), "id")
>          {
>                         public void populateItem(Item cellItem, String
> componentId, final
> IModel model)
>              {
>                                 EditActionPanel panel = new
> EditActionPanel(componentId, model);
>                                 panel.add(
> SecurePanelLink.createSecurePanelLink( "edit", m,
> UserFormPanel.class, model ) );
>                cellItem.add( panel );
>              }
>          });
>
>          columns.add(new PropertyColumn(new Model("Username"),
> "username", "username"));
>          columns.add(new PropertyColumn(new Model("First Name"),
> "firstName", "firstName"));
>          columns.add(new PropertyColumn(new Model("Last Name"),
> "lastName", "lastName"));
>
>          add(new DefaultDataTable("table", columns, new
> SortableUserDataProvider(), 10));
>         }
>
>
> ====================================
> SecurePanelLink
> ====================================
> public class SecurePanelLink extends Link implements ISecureComponent {
>
>         /**
>          *
>          */
>         private static final long serialVersionUID = 1L;
>
>         protected IPanelLink panelLink;
>
>         /**
>          * @param id
>          * @param c
>          */
>         public SecurePanelLink(String id, final Class c)
>         {
>                 super(id);
>                 // Ensure that c is a subclass of Panel
>                 if (!Panel.class.isAssignableFrom(c))
>                 {
>                         throw new IllegalArgumentException("Class " + c +
> " is not a
> subclass of Panel");
>                 }
>
>                 this.panelLink = createIPanelLink( id, c );
>                 setSecurityCheck(new LinkSecurityCheck(this, c));
>         }
>
>         public SecurePanelLink(String id, final Class c, Model
> existingPanel)
>         {
>                 super(id);
>                 // Ensure that c is a subclass of Panel
>                 if (!Panel.class.isAssignableFrom(c))
>                 {
>                         throw new IllegalArgumentException("Class " + c +
> " is not a
> subclass of Panel");
>                 }
>
>                 this.panelLink = createIPanelLink( id, c );
>                 setSecurityCheck(new LinkSecurityCheck(this, c));
>         }
>
>         private IPanelLink createIPanelLink( String id, final Class c ) {
>                 return new IPanelLink()
>                 {
>                         private static final long serialVersionUID = 1L;
>
>                         public Panel getPanel( String id )
>                         {
>                                 // Create panel using panel factory
>                                 return getPanelFactory().newPanel(id, c );
>                         }
>
>                         public Panel getPanel( String id, IModel model)
>                         {
>                                 // Create panel using panel factory
>                                 return getPanelFactory().newPanel(id, c,
> model);
>                         }
>
>                         public Panel getPanel( Panel panel, IModel model)
>                         {
>                                 // Create panel using panel factory
>                                 return getPanelFactory().newPanel(
> panel.getId(), c, model);
>                         }
>
>                         public Class getPanelIdentity()
>                         {
>                                 return c;
>                         }
>                 };
>         }
>
>         /**
>          *
>          */
>         public static SecurePanelLink createSecurePanelLink( String id,
> Class clazz ) {
>                 return new SecurePanelLink( id, clazz ) {
>                         /**
>                          *
>                          */
>                         private static final long serialVersionUID = 1L;
>
>                         public void onClick() {
>                                 Panel panel = ((Panel)findParent(
> Panel.class));
>                                 panel.replaceWith( panelLink.getPanel(
> panel.getId() ) );
>                         }
>                 };
>         }
>
>         /**
>          *
>          */
>         public static SecurePanelLink createSecurePanelLink( String id,
> Class newPanel, final IModel model ) {
>                 return new SecurePanelLink( id, newPanel ) {
>                         /**
>                          *
>                          */
>                         private static final long serialVersionUID = 1L;
>
>                         public void onClick() {
>                                 Panel panel = ((Panel)findParent(
> Panel.class));
>                                 panel.replaceWith( panelLink.getPanel(
> panel.getId(), model ) );
>                         }
>                 };
>         }
>
>         /**
>          *
>          */
>         public static SecurePanelLink createSecurePanelLink( String id,
> final Model existingPanel, Class newPanel, final IModel model ) {
>                 return new SecurePanelLink( id, newPanel, existingPanel )
> {
>                         /**
>                          *
>                          */
>                         private static final long serialVersionUID = 1L;
>
>
>                         public void onClick() {
>                                 Panel p =
> (Panel)existingPanel.getObject();
>                                 Panel panel = panelLink.getPanel
> ((Panel)existingPanel.getObject
> (), model );
>                                 panel.setOutputMarkupId(true);
>                                 p.getParent().replace( panel );
>                                 p=panel;
>                         }
>                 };
>         }
>