diff --git a/src-db/database/sourcedata/AD_MODEL_OBJECT.xml b/src-db/database/sourcedata/AD_MODEL_OBJECT.xml
--- a/src-db/database/sourcedata/AD_MODEL_OBJECT.xml
+++ b/src-db/database/sourcedata/AD_MODEL_OBJECT.xml
@@ -39,6 +39,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src-db/database/sourcedata/AD_MODEL_OBJECT_MAPPING.xml b/src-db/database/sourcedata/AD_MODEL_OBJECT_MAPPING.xml
--- a/src-db/database/sourcedata/AD_MODEL_OBJECT_MAPPING.xml
+++ b/src-db/database/sourcedata/AD_MODEL_OBJECT_MAPPING.xml
@@ -1,5 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/org/openbravo/mobile/core/MobileCoreComponentServlet.java b/src/org/openbravo/mobile/core/MobileCoreComponentServlet.java
new file mode 100644
--- /dev/null
+++ b/src/org/openbravo/mobile/core/MobileCoreComponentServlet.java
@@ -0,0 +1,213 @@
+/*
+ ************************************************************************************
+ * Copyright (C) 2014 Openbravo S.L.U.
+ * Licensed under the Openbravo Commercial License version 1.0
+ * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
+ * or in the legal folder of this module distribution.
+ ************************************************************************************
+ */
+
+package org.openbravo.mobile.core;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Logger;
+import org.openbravo.base.HttpBaseUtils;
+import org.openbravo.client.kernel.BaseComponent;
+import org.openbravo.client.kernel.Component;
+import org.openbravo.client.kernel.ComponentGenerator;
+import org.openbravo.client.kernel.ComponentProvider;
+import org.openbravo.client.kernel.KernelConstants;
+import org.openbravo.client.kernel.KernelUtils;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.service.web.WebServiceUtil;
+
+/**
+ * The mobile core entry point for getting to static resources without needing to login. All
+ * components called by this servlet need to let {@link BaseComponent#bypassAuthentication()} return
+ * true.
+ *
+ * @author mtaal
+ */
+public class MobileCoreComponentServlet extends HttpServlet {
+ private static final String RESPONSE_HEADER_ETAG = "ETag";
+ private static final String RESPONSE_HEADER_LASTMODIFIED = "Last-Modified";
+ private static final String RESPONSE_HEADER_CACHE_CONTROL = "Cache-Control";
+ private static final String RESPONSE_NO_CACHE = "no-cache";
+ private static final String RESPONSE_HEADER_CONTENTTYPE = "Content-Type";
+
+ private static final String REQUEST_HEADER_IFMODIFIEDSINCE = "If-Modified-Since";
+ private static final String REQUEST_HEADER_IFNONEMATCH = "If-None-Match";
+
+ private static final Logger log = Logger.getLogger(MobileCoreComponentServlet.class);
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String servletPathPart = "org.openbravo.mobile.core";
+
+ private static ServletContext servletContext;
+
+ @Inject
+ @Any
+ private Instance componentProviders;
+
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
+ servletContext = config.getServletContext();
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,
+ ServletException {
+
+ if (!request.getRequestURI().contains("/" + servletPathPart)) {
+ throw new UnsupportedOperationException("Invalid url " + request.getRequestURI());
+ }
+
+ OBContext.setAdminMode(true);
+ try {
+ processComponentRequest(request, response);
+ } finally {
+ OBContext.restorePreviousMode();
+ OBContext.setOBContext((OBContext) null);
+ }
+ }
+
+ // NOTE: this exact same method is present in the KernelServlet, if changed
+ // here, please also check the method in the KernelServlet class
+ private Component getComponent(HttpServletRequest request) {
+
+ final int nameIndex = request.getRequestURI().indexOf(servletPathPart);
+ final String servicePart = request.getRequestURI().substring(nameIndex);
+ final String[] pathParts = WebServiceUtil.getInstance().getSegments(servicePart);
+ if (pathParts.length < 2) {
+ throw new UnsupportedOperationException("No service name present in url "
+ + request.getRequestURI());
+ }
+ final String componentProviderName = pathParts[1];
+
+ final String componentId;
+ if (pathParts.length > 2) {
+ componentId = pathParts[2];
+ } else {
+ componentId = null;
+ }
+
+ final ComponentProvider componentProvider = componentProviders.select(
+ new ComponentProvider.Selector(componentProviderName)).get();
+
+ final Map parameters = getParameterMap(request);
+ final Component component = componentProvider.getComponent(componentId, parameters);
+
+ // we are not logging in allow only selected components
+ if (!((BaseComponent) component).bypassAuthentication()) {
+ throw new UnsupportedOperationException("Request not supported " + request.getRequestURI());
+ }
+
+ return component;
+ }
+
+ // NOTE: this exact same method is present in the KernelServlet, if changed
+ // here, please also check the method in the KernelServlet class
+ private void processComponentRequest(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ Component component = getComponent(request);
+ OBContext.setAdminMode(true);
+ String eTag;
+ try {
+ eTag = component.getETag();
+ } finally {
+ OBContext.restorePreviousMode();
+ }
+ final String requestETag = request.getHeader(REQUEST_HEADER_IFNONEMATCH);
+
+ if (requestETag != null && eTag.equals(requestETag)) {
+ response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
+ response.setDateHeader(RESPONSE_HEADER_LASTMODIFIED,
+ request.getDateHeader(REQUEST_HEADER_IFMODIFIEDSINCE));
+ return;
+ }
+
+ try {
+ final String result = ComponentGenerator.getInstance().generate(component);
+
+ response.setHeader(RESPONSE_HEADER_ETAG, eTag);
+ response.setDateHeader(RESPONSE_HEADER_LASTMODIFIED, component.getLastModified().getTime());
+ response.setContentType(component.getContentType());
+ response.setHeader(RESPONSE_HEADER_CONTENTTYPE, component.getContentType());
+ response.setHeader(RESPONSE_HEADER_CACHE_CONTROL, RESPONSE_NO_CACHE);
+
+ final PrintWriter pw = response.getWriter();
+ pw.write(result);
+ pw.close();
+ } catch (Exception e) {
+ log.error("Generating content using component: "
+ + (component != null ? component.getClass().getName() : "NULL"), e);
+ if (!response.isCommitted()) {
+ response.setContentType(KernelConstants.JAVASCRIPT_CONTENTTYPE);
+ response.setHeader(RESPONSE_HEADER_CONTENTTYPE, KernelConstants.JAVASCRIPT_CONTENTTYPE);
+ response.setHeader(RESPONSE_HEADER_CACHE_CONTROL, RESPONSE_NO_CACHE);
+ response.getWriter().write(KernelUtils.getInstance().createErrorJavaScript(e));
+ }
+ }
+ }
+
+ @Override
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException,
+ ServletException {
+ doGet(request, response);
+ }
+
+ @Override
+ public void doDelete(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ throw new UnsupportedOperationException("Only GET/POST is supported");
+ }
+
+ @Override
+ public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException,
+ ServletException {
+ throw new UnsupportedOperationException("Only GET/POST is supported");
+ }
+
+ @SuppressWarnings("rawtypes")
+ private Map getParameterMap(HttpServletRequest request) {
+ final Map parameterMap = new HashMap();
+ for (Enumeration keys = request.getParameterNames(); keys.hasMoreElements();) {
+ final String key = (String) keys.nextElement();
+ parameterMap.put(key, request.getParameter(key));
+ }
+
+ if (!parameterMap.containsKey(KernelConstants.CONTEXT_URL)) {
+ parameterMap.put(KernelConstants.CONTEXT_URL, computeContextURL(request));
+ }
+
+ if (!parameterMap.containsKey(KernelConstants.SERVLET_CONTEXT)) {
+ parameterMap.put(KernelConstants.SERVLET_CONTEXT, servletContext);
+ }
+
+ if (!parameterMap.containsKey(KernelConstants.SKIN_PARAMETER)) {
+ parameterMap.put(KernelConstants.SKIN_PARAMETER, KernelConstants.SKIN_DEFAULT);
+ }
+
+ return parameterMap;
+ }
+
+ private String computeContextURL(HttpServletRequest request) {
+ return HttpBaseUtils.getLocalAddress(request);
+ }
+}
diff --git a/src/org/openbravo/mobile/core/templates/cache-manifest.ftl b/src/org/openbravo/mobile/core/templates/cache-manifest.ftl
--- a/src/org/openbravo/mobile/core/templates/cache-manifest.ftl
+++ b/src/org/openbravo/mobile/core/templates/cache-manifest.ftl
@@ -9,12 +9,12 @@
# Core 3rd party libraries
-../../org.openbravo.client.kernel/OBMOBC_Main/Lib?_id=Enyo
-../../org.openbravo.client.kernel/OBMOBC_Main/Lib?_id=Deps
+../../org.openbravo.mobile.core/OBMOBC_Main/Lib?_id=Enyo
+../../org.openbravo.mobile.core/OBMOBC_Main/Lib?_id=Deps
<#if data.appName != "">
# Static resources
-../../org.openbravo.client.kernel/OBMOBC_Main/StaticResources?_appName=${data.appName}
+../../org.openbravo.mobile.core/OBMOBC_Main/StaticResources?_appName=${data.appName}
../../web/js/gen/${data.genFileName}.js
#if>
diff --git a/web/org.openbravo.mobile.core/source/data/ob-model.js b/web/org.openbravo.mobile.core/source/data/ob-model.js
--- a/web/org.openbravo.mobile.core/source/data/ob-model.js
+++ b/web/org.openbravo.mobile.core/source/data/ob-model.js
@@ -33,7 +33,7 @@
online: true
});
} else if (modelParam.prototype.generatedStructure) {
- var url = '../../org.openbravo.client.kernel/OBMOBC_Main/ClientModel';
+ var url = '../../org.openbravo.mobile.core/OBMOBC_Main/ClientModel';
url += '?entity=' + modelParam.prototype.entityName;
url += '&modelName=' + modelParam.prototype.modelName;
url += '&source=' + modelParam.prototype.source;
@@ -244,4 +244,4 @@
});
return '(' + columns + ')';
}
-});
\ No newline at end of file
+});