Archive for décembre, 2007

Shindig: an Apache openSocial container.

Brian MacCallister has proposed 2 weeks ago a new project for apache incubator. This project is called Shindig and has now an Apache page.

Here is an extract for the proposal :

= Abstract =

Shindig will develop a container and backend server components for hosting OpenSocial applications.

= Proposal =

Shindig will develop a JavaScript container and implementations of the backend APIs and proxy required for hosting OpenSocial applications.

= Background =

OpenSocial provides a common set of APIs for social applications across multiple websites. With standard JavaScript and HTML, developers can create social applications that use a social network’s friends and update feeds.

A social application, in this context, is an application run by a third party provider and embedded in a web page, or web application, which consumes services provided by the container and by the application host. This is very similar to Portal/Portlet technology, but is based on client-side compositing, rather than server.

More information can be found about OpenSocial at http://code.google.com/apis/opensocial/




Google has also started an OpenSocial container implementation : http://code.google.com/p/opensocial-container-sample/ but both projects seem to try to make effort to be merged in Shindig.

Goojet is out with a private Beta

From Goojet website :
Your phone is entering a totally new dimension. We created Goojet to make mobile services really simple and effective, from any phone – not just high-end handsets. Goojet enables you to customize your phone by organizing YOUR “mobile space”, picking services that are really useful to you. You can also use Goojet to communicate and share with your friends or professional contacts; and to express your creativity, by inventing and sharing new services.

  • Unite your web and mobile lives
  • Create and customize your own personal mobile space
  • Discover other mobile spaces
  • Invent and share new services



If you want to get invitation you can fill the invitation form, or let me know on this blog.

You can go to the website to find out more information :


Or take a look to the guided tour.



More info, in french on Cédric Girogi Blog

NB : Goojet is now at « Le web 3″, you can meet part of the team there

Simulate ajax file upload with wicket

First of all, we need to know upload is not supported by XmlHttpRequest so if we want to do ajax upload we need to use an Iframe. This iframe will upload the file and then notify the parent window with javascript. Here is a way to do that with wicket :


UploadPanel.java

 package net.demay.fr.component.ajax.upload; import org.apache.wicket.Page; import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.MarkupStream; import org.apache.wicket.markup.html.WebComponent; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.form.upload.FileUpload; import org.apache.wicket.markup.html.link.IPageLink; import org.apache.wicket.markup.html.link.InlineFrame; import org.apache.wicket.markup.html.panel.Panel; /**  * A panel allowing to upload file in an iframe. This panel can be used to  * upload file in a "Ajax way" : page does not need to be reloaded. Only the iframe is reloaded  *  * @author Vincent Demay  *  */ @SuppressWarnings("serial") public abstract class UploadPanel extends Panel {     private InlineFrame uploadIFrame = null;     public UploadPanel(String id) {         super(id);         addOnUploadedCallback();         setOutputMarkupId(true);     }     /**      * Called when the upload load is uploaded and ready to be used      * Return the url of the new uploaded resource      * @param upload {@link FileUpload}      */     public abstract String onFileUploaded(FileUpload upload);     /**      * Called once the upload is finished and the traitment of the      * {@link FileUpload} has been done in {@link UploadPanel#onFileUploaded}      * @param target an {@link AjaxRequestTarget}      * @param fileName name of the file on the client side      * @param newFileUrl Url of the uploaded file      */     public abstract void onUploadFinished(AjaxRequestTarget target, String filename, String newFileUrl);     protected void onBeforeRender() {         super.onBeforeRender();         if (uploadIFrame == null) {             // the iframe should be attached to a page to be able to get its pagemap,             // that's why i'm adding it in onBeforRender             addUploadIFrame();         }     }     /**      * Create the iframe containing the upload widget      *      */     private void addUploadIFrame() {         IPageLink iFrameLink = new IPageLink() {             public Page getPage() {                 return new UploadIFrame() {                 	@Override                     protected String getOnUploadedCallback() {                         return "onUpload_" + UploadPanel.this.getMarkupId();                     }                     @Override                     protected String manageInputSream(FileUpload upload) {                     	return UploadPanel.this.onFileUploaded(upload);                     }                 };             }             public Class getPageIdentity() {                 return UploadIFrame.class;             }         };         uploadIFrame = new InlineFrame("upload", getPage().getPageMap(), iFrameLink);         add(uploadIFrame);     }     /**      * Hackie method allowing to add a javascript in the page defining the      * callback called by the innerIframe      *      */     private void addOnUploadedCallback() {         final OnUploadedBehavior onUploadBehavior = new OnUploadedBehavior();         add(onUploadBehavior);         add(new WebComponent("onUploaded") {             protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {                 // calling it through setTimeout we ensure that the callback is called                 // in the proper execution context, that is the parent frame                 replaceComponentTagBody(markupStream, openTag,                         "function onUpload_" + UploadPanel.this.getMarkupId() +                         "(clientFileName, newFileUrl) {window.setTimeout(function() { " +                         onUploadBehavior.getCallback() + " }, 0 )}");             }         });     }     private class OnUploadedBehavior extends AbstractDefaultAjaxBehavior {         public String getCallback() {             return generateCallbackScript(                     "wicketAjaxGet('" + getCallbackUrl(false) +                     "&newFileUrl=' + encodeURIComponent(newFileUrl)" +                     " + '&clientFileName=' + encodeURIComponent(clientFileName)").toString();         }         protected void respond(AjaxRequestTarget target) {         	UploadPanel.this.onUploadFinished(target, getRequest().getParameter("clientFileName"), getRequest().getParameter("newFileUrl"));         }     }; } 

UploadPanel.html

 <html xmlns:wicket> <wicket:panel>   <!-- I put the callback snippet at the body so that is rendered for each panel instead of once -->   <script wicket:id="onUploaded" type="text/javascript"></script>   <iframe wicket:id="upload" frameborder="0" height="55" width="450" style="overflow:hidden"></iframe> </wicket:panel> </html> 

UploadIFrame.java

 package net.demay.fr.component.ajax.upload; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.ComponentTag; import org.apache.wicket.markup.MarkupStream; import org.apache.wicket.markup.html.WebComponent; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.upload.FileUpload; import org.apache.wicket.markup.html.form.upload.FileUploadField; import org.apache.wicket.model.ResourceModel; /**  * A webPage to be used in an iframe in order to simulate  * an ajax file upload  * @author doume  *  */ @SuppressWarnings("serial") public abstract class UploadIFrame extends WebPage {     private boolean uploaded = false;     private FileUploadField uploadField;     private String newFileUrl;     public UploadIFrame() {         add(new UploadForm("form"));         addOnUploadedCallback();     }     /**      * return the callback url when upload is finished      * @return callback url when upload is finished      */     protected abstract String getOnUploadedCallback();     /**      * Called when the input stream has been uploaded and when it is available      * on server side      * return the url of the uploaded file      * @param upload fileUpload      */     protected abstract String manageInputSream(FileUpload upload);     private class UploadForm extends Form {     	public UploadForm(String id) {             super(id);             uploadField = new FileUploadField("file");             add(uploadField);             add(new AjaxLink("submit"){             	@Override             	protected void onClick(AjaxRequestTarget target) {             		target.appendJavascript("showProgressWheel()");             	}             });         }         public void onSubmit() {             FileUpload upload = uploadField.getFileUpload();             newFileUrl = manageInputSream(upload);             //file is now uploaded, and the IFrame will be reloaded, during             //reload we need to run the callback             uploaded = true;         }     }     private void addOnUploadedCallback() {     	//a hacked component to run the callback on the parent         add(new WebComponent("onUploaded") {             protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {                 if (uploaded) {                 	if (uploadField.getFileUpload() != null){ 	                    replaceComponentTagBody(markupStream, openTag, 	                            "window.parent." + getOnUploadedCallback() + "('" + 	                            uploadField.getFileUpload().getClientFileName() + "','" + 	                            newFileUrl +"')");                 	}                     uploaded = false;                 }             }         });     } } 

UploadIframe.html

 <html xmlns:wicket> <head> <script type="text/javascript"> function showProgressWheel() {   document.images[0].style.display = 'block';   // delay the wheel a bit so it can locally shine   setTimeout(function() { document.forms[0].submit() }, 800);   return false; } </script> </head> <body>   <form wicket:id="form">   	<table>   		<tr>   			<td>     			<input wicket:id="file" type="file"/>     		</td>     		<td> 				<table wicket:id="submit"></table> 			</td> 			<td>     			<img src="indicator.gif" style="display:none"/>     		</td>     	</tr>     </table>   </form>   <script wicket:id="onUploaded" type="text/javascript"> </body> </html> 

Usage

 final UploadPanel upload = new UploadPanel("myUpload"){ 			@Override 			public String onFileUploaded(FileUpload upload) { 				if (upload != null){ 			        try { 					//save on server side here                                         //and return the url of the saved file                                        return savedFile.getUrl() 			        } catch (IOException e) { 						// TODO Auto-generated catch block 						e.printStackTrace(); 					} 				} 				return ""; 			} 			@Override 			public void onUploadFinished(AjaxRequestTarget target, String filename, String newFileUrl) { 				//when upload is finished, will be called 			} 		}; 

A week-end at Nice and Cannes

I’m back from a nice week-end at Cannes and Nice with some firends :

looking at the sea ;)



where are Paparazzis?

more on flickr