myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Aleksei Valikov <vali...@gmx.net>
Subject Re: Direct usage of myfaces out of a Java program and save/restoreState issues
Date Wed, 06 Sep 2006 10:35:33 GMT
Hi Ulrich,

I create and compone a lot of components programmatically. I've written library 
that creates JSF-based editors base on the XML Schema of the document.

Editors are composed from a large number of JSF components (inputs, command 
links and buttons) and so on.

I use a lot of dynamic value and method bindings to allow user input change the 
underlying document. You'll see a typical example of what I'm doing in the end 
of the mail.

As for me, correct state management with JSF was SO compilcated that I've 
desided to drop it for now and implement dirty and easy solution.

In JSF, you save structure and state of components separately. State is what you 
components put into these arrays. Structure is saved as tree of component classes.

When you restore the state you first re-create a tree of components (i.e. 
instantiate classes) and the provide them with the state.

This is very very very inconvenient for my case.

1. I have a lot of dynamic bindings via anonymous classes. They simply aren't 
serializable! And even if I invent a way to make them serializable, this would 
take SO much time to restore all these dynamic bindings.

2. Simply restoring component tree from component classes tree is a huge 
overhead. I may have hundreds of components on a single page, and I don't want 
them to be serialized/deserialized on each request. This is too slow.

So I have finally decided to do a dirty hack. I simply save one UIViewRoot per 
view ID in the session. Basta. No serialization/deserialization, simply get 
attribute from session.

Yes it is a dirty hack. If you access the same page concurrently, you will have 
problems. But I don't see another solution right now. I'm simply limiting users 
to have one browser window per application, that's it.

Bye.
/lexi

ps. Code example. This creates a label for the complex component, with text, 
pop-up context menu (copy and paste) add and remove buttons.


help = HelpUtils.createHelpLink("sd.structure." + getHelpTopicId(),
		getHelpSubTopicId());
label = TemplatedPanelUtils.createTemplatedPanel(getTemplateName(),
		getFragmentId());

text = FacesUtils.createOutputText(getEditor().getMessageId());
text.setValueBinding("styleClass", new LabelStyleClassValueBinding(
				getEditor()));

final UIComponent copy = CommandUtils.createLink("copy",
		new ClipboardMethodBinding() {
			protected Object invokeInternal(Clipboard clipboard) {
				clipboard.copy(getModel());
				return "Success.";
			}
		});

final UIComponent paste = CommandUtils.createLink("paste",
		new ClipboardMethodBinding() {
			protected Object invokeInternal(Clipboard clipboard) {
				clipboard.paste(getModel());
				return "Success.";
			}
		});

paste.setValueBinding("rendered", new ClipboardValueBinding() {
	protected Object getInternal(Clipboard clipboard) {
		return Boolean.valueOf(clipboard.isPastePossible(getModel()));
	}
});

final HtmlCommandLink refresh = CommandUtils.createLink(
		Messages.REFRESH, null);

contextMenu = FacesUtils.createPopupBox(FacesUtils
		.createContextMenuGraphicImage(), new UIComponent[] { copy,
		paste, refresh });
contextMenu.setStyleClass("hijack-contextMenu");
contextMenu.setStyleClassBox("hijack-contextMenu-box");

label.getFacets().put("contextMenu", contextMenu);

final VoidMethodBinding addAction = new VoidMethodBinding() {
	protected void execute() {
		getModel().addValue();
	}
};

addButton = AjaxCommandUtils.createAddImageLink(addAction);

final VoidMethodBinding removeAction = new VoidMethodBinding() {
protected void execute() {
		getModel().removeValue();
	}
};

removeButton = AjaxCommandUtils.createRemoveImageLink(removeAction);
label.getFacets().put("text", text);
label.getFacets().put("help", help);
label.getFacets().put("contextMenu", contextMenu);
label.getFacets().put("add", addButton);
label.getFacets().put("remove", removeButton);
label.getFacets().put("validity", getEditor().getValidity());
update();
return label;



Mime
View raw message