diff --git a/commons-juzu/pom.xml b/commons-juzu/pom.xml
new file mode 100644
index 00000000..e4ceb9b5
--- /dev/null
+++ b/commons-juzu/pom.xml
@@ -0,0 +1,65 @@
+
+
+ 4.0.0
+
+ org.exoplatform.commons-exo
+ commons-exo
+ 6.5.x-security-fix-SNAPSHOT
+
+
+ commons-juzu
+ jar
+ eXo PLF:: Commons - Juzu Bridge for Platform
+
+ This module contains :
+ - assemblies for Juzu application packaging inside eXoPlatform
+ - eXo Kernel Provider Factory
+
+
+
+ org.exoplatform.commons
+ commons-api
+
+
+ org.exoplatform.commons
+ commons-component-common
+
+
+
+
+ org.juzu
+ juzu-core
+
+
+ org.juzu
+ juzu-plugins-validation
+
+
+ org.juzu
+ juzu-plugins-less
+
+
+ org.juzu
+ juzu-plugins-less4j
+
+
+ org.juzu
+ juzu-plugins-webjars
+
+
+ org.juzu
+ juzu-plugins-portlet
+
+
+ org.juzu
+ juzu-plugins-upload
+
+
+ com.google.inject
+ guice
+
+
+
+
diff --git a/commons-juzu/src/main/java/org/exoplatform/commons/juzu/KernelProviderFactory.java b/commons-juzu/src/main/java/org/exoplatform/commons/juzu/KernelProviderFactory.java
new file mode 100644
index 00000000..8078121c
--- /dev/null
+++ b/commons-juzu/src/main/java/org/exoplatform/commons/juzu/KernelProviderFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.exoplatform.commons.juzu;
+
+import juzu.inject.ProviderFactory;
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.spi.ComponentAdapter;
+
+import javax.inject.Provider;
+
+/**
+ * Provides kernel services in Juzu application.
+ *
+ * @author Frederic Drouet
+ */
+public class KernelProviderFactory implements ProviderFactory {
+
+ @Override
+ public Provider extends T> getProvider(final Class implementationType) throws Exception {
+ final PortalContainer container = PortalContainer.getInstance();
+ if (container == null) {
+ throw new IllegalStateException("Not running in the context of a portal container");
+ }
+ final ComponentAdapter adapter = container.getComponentAdapterOfType(implementationType);
+ if (adapter != null) {
+ return new Provider() {
+ @Override
+ public T get() {
+ Object service = adapter.getComponentInstance();
+ if (service == null) {
+ throw new RuntimeException("Could not obtain service " + implementationType + " from container " + container);
+ }
+ return implementationType.cast(service);
+ }
+ };
+ } else {
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/Ajax.java b/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/Ajax.java
new file mode 100644
index 00000000..02ad805e
--- /dev/null
+++ b/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/Ajax.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.exoplatform.commons.juzu.ajax;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** @author Julien Viet */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Ajax {
+}
diff --git a/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/AjaxMetaModelPlugin.java b/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/AjaxMetaModelPlugin.java
new file mode 100644
index 00000000..7490f6ee
--- /dev/null
+++ b/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/AjaxMetaModelPlugin.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.exoplatform.commons.juzu.ajax;
+
+import juzu.impl.common.Name;
+import juzu.impl.plugin.application.metamodel.ApplicationMetaModel;
+import juzu.impl.plugin.application.metamodel.ApplicationMetaModelPlugin;
+import juzu.impl.metamodel.AnnotationKey;
+import juzu.impl.metamodel.AnnotationState;
+import juzu.impl.compiler.ElementHandle;
+import juzu.impl.common.JSON;
+import juzu.impl.compiler.ProcessingContext;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Set;
+
+/** @author Julien Viet */
+public class AjaxMetaModelPlugin extends ApplicationMetaModelPlugin {
+
+ /** . */
+ private static final Name AJAX = Name.create(Ajax.class);
+
+ /** . */
+ private final HashMap enabledMap = new HashMap();
+
+ public AjaxMetaModelPlugin() {
+ super("plf4-ajax");
+ }
+
+ @Override
+ public Set> init(ProcessingContext env) {
+ return Collections.>singleton(Ajax.class);
+ }
+
+ @Override
+ public void processAnnotationAdded(ApplicationMetaModel metaModel, AnnotationKey key, AnnotationState added) {
+ if (key.getType().equals(AJAX)) {
+ ElementHandle.Package handle = metaModel.getHandle();
+ enabledMap.put(handle, true);
+ }
+ }
+
+ @Override
+ public void processAnnotationRemoved(ApplicationMetaModel metaModel, AnnotationKey key, AnnotationState removed) {
+ if (key.getType().equals(AJAX)) {
+ ElementHandle.Package handle = metaModel.getHandle();
+ enabledMap.remove(handle);
+ }
+ }
+
+ @Override
+ public void init(ApplicationMetaModel application) {
+ }
+
+ @Override
+ public void destroy(ApplicationMetaModel application) {
+ enabledMap.remove(application.getHandle());
+ }
+
+ @Override
+ public JSON getDescriptor(ApplicationMetaModel application) {
+ ElementHandle.Package handle = application.getHandle();
+ Boolean enabled = enabledMap.get(handle);
+ return enabled != null && enabled ? new JSON() : null;
+ }
+}
diff --git a/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/AjaxService.java b/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/AjaxService.java
new file mode 100644
index 00000000..9aaf1927
--- /dev/null
+++ b/commons-juzu/src/main/java/org/exoplatform/commons/juzu/ajax/AjaxService.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2012 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.exoplatform.commons.juzu.ajax;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import juzu.Response;
+import juzu.impl.plugin.ServiceContext;
+import juzu.impl.plugin.ServiceDescriptor;
+import juzu.impl.plugin.application.ApplicationService;
+import juzu.impl.plugin.controller.ControllerService;
+import juzu.impl.request.ControllerHandler;
+import juzu.impl.request.Request;
+import juzu.impl.request.RequestFilter;
+import juzu.impl.request.Stage;
+import juzu.io.Chunk;
+import juzu.io.Stream;
+import juzu.io.Streamable;
+import juzu.request.Phase;
+
+/** @author Julien Viet */
+public class AjaxService extends ApplicationService implements RequestFilter {
+
+ /** . */
+ Map table;
+
+ @Inject
+ ControllerService controllerService;
+
+ public AjaxService() {
+ super("plf4-ajax");
+ }
+
+ @Override
+ public ServiceDescriptor init(ServiceContext context) throws Exception {
+ return context.getConfig() != null ? new ServiceDescriptor() : null;
+ }
+
+ @PostConstruct
+ public void start() throws Exception {
+ //
+ Map table = new HashMap();
+ for (ControllerHandler cm : controllerService.getDescriptor().getHandlers()) {
+ Ajax ajax = cm.getMethod().getAnnotation(Ajax.class);
+ if (ajax != null) {
+ table.put(cm.getName(), cm);
+ }
+ }
+
+ //
+ this.table = table;
+ }
+
+ @Override
+ public Class getStageType() {
+ return Stage.Unmarshalling.class;
+ }
+
+ @Override
+ public Response handle(Stage.Unmarshalling argument) {
+ final Request request = argument.getRequest();
+ Response result = argument.invoke();
+
+ //
+ if (request.getPhase() == Phase.VIEW) {
+ if (result instanceof Response.Content) {
+ Response.Status status = (Response.Status)result;
+ final Streamable wrapped = status.streamable();
+ Streamable wrapper = new Streamable() {
+ public void send(final Stream stream) throws IllegalStateException {
+ Stream our = new Stream() {
+ boolean done = false;
+ public void provide(Chunk chunk) {
+ if (chunk instanceof Chunk.Data && !done) {
+ done = true;
+ // FOR NOW WE DO WITH THE METHOD NAME
+ // BUT THAT SHOULD BE REVISED TO USE THE ID INSTEAD
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n");
+ for (Map.Entry
entry : table.entrySet()) {
+ String baseURL = request.createDispatch(entry.getValue()).toString();
+ sb.append("");
+ }
+ stream.provide(Chunk.create(sb));
+ }
+ stream.provide(chunk);
+ }
+ public void close(Thread.UncaughtExceptionHandler errorHandler) {
+ stream.provide(Chunk.create(" "));
+ stream.close(errorHandler);
+ }
+ };
+ wrapped.send(our);
+ }
+ };
+ result = new Response.Content(status.getCode(), wrapper);
+ }
+ }
+
+ //
+ return result;
+ }
+}
diff --git a/commons-juzu/src/main/resources/META-INF/services/juzu.impl.plugin.application.ApplicationService b/commons-juzu/src/main/resources/META-INF/services/juzu.impl.plugin.application.ApplicationService
new file mode 100644
index 00000000..91206f33
--- /dev/null
+++ b/commons-juzu/src/main/resources/META-INF/services/juzu.impl.plugin.application.ApplicationService
@@ -0,0 +1 @@
+org.exoplatform.commons.juzu.ajax.AjaxService
\ No newline at end of file
diff --git a/commons-juzu/src/main/resources/META-INF/services/juzu.impl.plugin.application.metamodel.ApplicationMetaModelPlugin b/commons-juzu/src/main/resources/META-INF/services/juzu.impl.plugin.application.metamodel.ApplicationMetaModelPlugin
new file mode 100644
index 00000000..9810d7eb
--- /dev/null
+++ b/commons-juzu/src/main/resources/META-INF/services/juzu.impl.plugin.application.metamodel.ApplicationMetaModelPlugin
@@ -0,0 +1 @@
+org.exoplatform.commons.juzu.ajax.AjaxMetaModelPlugin
\ No newline at end of file
diff --git a/commons-juzu/src/main/resources/META-INF/services/juzu.inject.ProviderFactory b/commons-juzu/src/main/resources/META-INF/services/juzu.inject.ProviderFactory
new file mode 100644
index 00000000..c98a9a2f
--- /dev/null
+++ b/commons-juzu/src/main/resources/META-INF/services/juzu.inject.ProviderFactory
@@ -0,0 +1 @@
+org.exoplatform.commons.juzu.KernelProviderFactory
\ No newline at end of file
diff --git a/commons-juzu/src/main/resources/assemblies/platform-juzu.xml b/commons-juzu/src/main/resources/assemblies/platform-juzu.xml
new file mode 100644
index 00000000..fdbac951
--- /dev/null
+++ b/commons-juzu/src/main/resources/assemblies/platform-juzu.xml
@@ -0,0 +1,48 @@
+
+
+ platform-juzu
+
+ war
+
+ false
+
+
+ ${project.build.outputDirectory}
+ /WEB-INF/classes
+
+
+ ${project.build.sourceDirectory}
+ /WEB-INF/src
+
+
+ ${project.basedir}/src/main/webapp
+ /
+
+ **/less/**
+
+
+
+ ${project.build.directory}/${project.build.finalName}/skin/css
+ /skin/css
+
+
+
diff --git a/pom.xml b/pom.xml
index 0e3b8df8..6e788016 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,6 +13,7 @@
pom
eXo PLF:: eXo Platform Commons
+ commons-juzu
web
@@ -40,6 +41,11 @@
pom
import
+
+ org.exoplatform.commons-exo
+ commons-juzu
+ ${project.version}
+
org.exoplatform.commons-exo
commons-exo.portal.web.eXoSkin