keyStorePath,
+ * keyStoreProvider, keyStoreType are all
+ * null, the SSLContext will be initialised with a
+ * null array of KeyManagers. Similarly, if
+ * trustStorePath, trustStoreProvider,
+ * trustStoreType are all null, a
+ * null array of TrustManagers will be used.
+ *
+ * @see SSLContext#init(javax.net.ssl.KeyManager[],
+ * javax.net.ssl.TrustManager[], SecureRandom)
+ */
+ @Override
+ public SSLContext createSslContext() throws Exception {
+
+ KeyManagerFactory kmf = null;
+ if ((this.keyStorePath != null) || (this.keyStoreProvider != null)
+ || (this.keyStoreType != null)) {
+ /*
+ * Loads the key store.
+ */
+ final KeyStore keyStore = (this.keyStoreProvider != null) ? KeyStore
+ .getInstance(
+ (this.keyStoreType != null) ? this.keyStoreType
+ : KeyStore.getDefaultType(),
+ this.keyStoreProvider)
+ : KeyStore
+ .getInstance((this.keyStoreType != null) ? this.keyStoreType
+ : KeyStore.getDefaultType());
+ FileInputStream keyStoreInputStream = null;
+ try {
+ keyStoreInputStream = ((this.keyStorePath != null) && (!"NONE"
+ .equals(this.keyStorePath))) ? new FileInputStream(
+ this.keyStorePath) : null;
+ keyStore.load(keyStoreInputStream, this.keyStorePassword);
+ } finally {
+ if (keyStoreInputStream != null) {
+ keyStoreInputStream.close();
+ }
+ }
+
+ /*
+ * Creates the key-manager factory.
+ */
+ kmf = KeyManagerFactory.getInstance(this.keyManagerAlgorithm);
+ kmf.init(keyStore, this.keyStoreKeyPassword);
+ }
+
+ TrustManagerFactory tmf = null;
+ if ((this.trustStorePath != null) || (this.trustStoreProvider != null)
+ || (this.trustStoreType != null)) {
+ /*
+ * Loads the trust store.
+ */
+ final KeyStore trustStore = (this.trustStoreProvider != null) ? KeyStore
+ .getInstance(
+ (this.trustStoreType != null) ? this.trustStoreType
+ : KeyStore.getDefaultType(),
+ this.trustStoreProvider)
+ : KeyStore
+ .getInstance((this.trustStoreType != null) ? this.trustStoreType
+ : KeyStore.getDefaultType());
+
+ FileInputStream trustStoreInputStream = null;
+ try {
+ trustStoreInputStream = ((this.trustStorePath != null) && (!"NONE"
+ .equals(this.trustStorePath))) ? new FileInputStream(
+ this.trustStorePath) : null;
+ trustStore.load(trustStoreInputStream, this.trustStorePassword);
+ } finally {
+ if (trustStoreInputStream != null) {
+ trustStoreInputStream.close();
+ }
+ }
+
+ /*
+ * Creates the trust-manager factory.
+ */
+ tmf = TrustManagerFactory.getInstance(this.trustManagerAlgorithm);
+ tmf.init(trustStore);
+ }
+
+ TrustManager[] trustManagers = null;
+ if (tmf != null) {
+ trustManagers = tmf.getTrustManagers();
+ } else {
+ trustManagers = new TrustManager[]{
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ }
+ };
+ }
+ /*
+ * Creates the SSLContext.
+ */
+ final SSLContext sslContext = SSLContext
+ .getInstance(this.secureSocketProtocol);
+ SecureRandom sr = null;
+ if (this.secureRandomAlgorithm != null) {
+ sr = SecureRandom.getInstance(this.secureRandomAlgorithm);
+ }
+ sslContext.init(kmf != null ? kmf.getKeyManagers() : null, trustManagers, sr);
+
+ return sslContext;
+ }
+
+}
diff --git a/client/src/org/adempiere/client/ServerInterface.java b/client/src/org/adempiere/client/ServerInterface.java
new file mode 100644
index 0000000000..8f08729345
--- /dev/null
+++ b/client/src/org/adempiere/client/ServerInterface.java
@@ -0,0 +1,208 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.client;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.util.RestletUtil;
+import org.compiere.db.CConnection;
+import org.compiere.db.SecurityPrincipal;
+import org.compiere.interfaces.Server;
+import org.compiere.process.ProcessInfo;
+import org.compiere.util.EMail;
+import org.restlet.Context;
+import org.restlet.data.ChallengeResponse;
+import org.restlet.data.ChallengeScheme;
+import org.restlet.resource.ClientResource;
+import org.restlet.representation.ObjectRepresentation;
+import org.restlet.representation.Representation;
+
+/**
+ * Server interface using restlet. Use ssl and http basic authentication.
+ * @author hengsin
+ */
+public class ServerInterface implements Server {
+
+ private ClientResource createClientResource(URI uri) {
+ Context context = getContext();
+ ClientResource resource = new ClientResource(context, uri);
+ resource.setChallengeResponse(createChallengeResponse());
+ return resource;
+ }
+
+ private ChallengeResponse createChallengeResponse()
+ {
+ SecurityPrincipal principal = CConnection.get().getAppServerCredential();
+ ChallengeResponse cr = new ChallengeResponse(ChallengeScheme.HTTP_BASIC, principal.identity, principal.secret);
+ return cr;
+ }
+
+ private Context getContext() {
+ return Application.context;
+ }
+
+ /* (non-Javadoc)
+ * @see org.compiere.interfaces.Server#postImmediate(java.util.Properties, int, int, int, boolean)
+ */
+ @Override
+ public String postImmediate(Properties ctx, int AD_Client_ID,
+ int AD_Table_ID, int Record_ID, boolean force) {
+ HashMap map = new HashMap();
+ map.put("context", ctx);
+ map.put("AD_Table_ID", AD_Table_ID);
+ map.put("Record_ID", Record_ID);
+ map.put("force", force);
+
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/command/postDocument", null, null);
+ ClientResource resource = createClientResource(uri);
+ ObjectRepresentation> entity = new ObjectRepresentation>(map);
+ Representation response = resource.post(entity);
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.compiere.interfaces.Server#process(java.util.Properties, org.compiere.process.ProcessInfo)
+ */
+ @Override
+ public ProcessInfo process(Properties ctx, ProcessInfo pi) {
+ HashMap map = new HashMap();
+ map.put("context", ctx);
+ map.put("processInfo", pi);
+
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/command/executeProcess", null, null);
+ ClientResource resource = createClientResource(uri);
+ ObjectRepresentation entity = new ObjectRepresentation(map);
+ Representation response = resource.post(entity);
+ ProcessInfo responseInfo = RestletUtil.toObject(response);
+ return responseInfo;
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.compiere.interfaces.Server#workflow(java.util.Properties, org.compiere.process.ProcessInfo, int)
+ */
+ @Override
+ public ProcessInfo workflow(Properties ctx, ProcessInfo pi,
+ int AD_Workflow_ID) {
+ HashMap map = new HashMap();
+ map.put("context", ctx);
+ map.put("AD_Workflow_ID", AD_Workflow_ID);
+
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/command/executeWorkflow", null, null);
+ ClientResource resource = createClientResource(uri);
+ ObjectRepresentation> entity = new ObjectRepresentation>(map);
+ Representation response = resource.post(entity);
+ ProcessInfo responseInfo = RestletUtil.toObject(response);
+ return responseInfo;
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.compiere.interfaces.Server#sendEMail(java.util.Properties, org.compiere.util.EMail)
+ */
+ @Override
+ public String sendEMail(Properties ctx, EMail email) {
+ HashMap map = new HashMap();
+ map.put("context", ctx);
+ map.put("email", email);
+
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/command/sendEmail", null, null);
+ ClientResource resource = createClientResource(uri);
+ ObjectRepresentation> entity = new ObjectRepresentation>(map);
+ Representation response = resource.post(entity);
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.compiere.interfaces.Server#executeTask(java.util.Properties, int)
+ */
+ @Override
+ public String executeTask(Properties ctx, int AD_Task_ID) {
+ HashMap map = new HashMap();
+ map.put("context", ctx);
+ map.put("AD_Task_ID", AD_Task_ID);
+
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/command/executeTask", null, null);
+ ClientResource resource = createClientResource(uri);
+ ObjectRepresentation> entity = new ObjectRepresentation>(map);
+ Representation response = resource.post(entity);
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.compiere.interfaces.Server#cacheReset(java.util.Properties, java.lang.String, int)
+ */
+ @Override
+ public int cacheReset(Properties ctx, String tableName, int Record_ID) {
+ HashMap map = new HashMap();
+ map.put("context", ctx);
+ map.put("tableName", tableName);
+ map.put("Record_ID", Record_ID);
+
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/command/resetCache", null, null);
+ ClientResource resource = createClientResource(uri);
+ ObjectRepresentation> entity = new ObjectRepresentation>(map);
+ Representation response = resource.post(entity);
+ return response != null ? Integer.parseInt(response.getText()) : 0;
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.compiere.interfaces.Server#dbProcess(java.util.Properties, org.compiere.process.ProcessInfo, java.lang.String)
+ */
+ @Override
+ public ProcessInfo dbProcess(Properties ctx, ProcessInfo processInfo,
+ String procedureName) {
+ HashMap map = new HashMap();
+ map.put("context", ctx);
+ map.put("processInfo", processInfo);
+ map.put("procedureName", procedureName);
+
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/command/executeProcess", null, null);
+ ClientResource resource = createClientResource(uri);
+ ObjectRepresentation> entity = new ObjectRepresentation>(map);
+ Representation response = resource.post(entity);
+ ProcessInfo responseInfo = RestletUtil.toObject(response);
+ return responseInfo;
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+}
diff --git a/client/src/org/adempiere/client/StatusInterface.java b/client/src/org/adempiere/client/StatusInterface.java
new file mode 100644
index 0000000000..e2db297db1
--- /dev/null
+++ b/client/src/org/adempiere/client/StatusInterface.java
@@ -0,0 +1,191 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.client;
+
+import java.net.URI;
+
+import org.adempiere.exceptions.AdempiereException;
+import org.compiere.db.CConnection;
+import org.compiere.db.SecurityPrincipal;
+import org.compiere.interfaces.Status;
+import org.restlet.Context;
+import org.restlet.data.ChallengeResponse;
+import org.restlet.data.ChallengeScheme;
+import org.restlet.representation.Representation;
+import org.restlet.resource.ClientResource;
+
+/**
+ * Status interface using restlet. Use ssl and http basic authentication.
+ * @author hengsin
+ *
+ */
+public class StatusInterface implements Status {
+
+ private ClientResource createClientResource(URI uri) {
+ Context context = getContext();
+ ClientResource resource = new ClientResource(context, uri);
+ resource.setChallengeResponse(createChallengeResponse());
+ return resource;
+ }
+
+ private ChallengeResponse createChallengeResponse()
+ {
+ SecurityPrincipal principal = CConnection.get().getAppServerCredential();
+ if (principal != null)
+ {
+ ChallengeResponse cr = new ChallengeResponse(ChallengeScheme.HTTP_BASIC, principal.identity, principal.secret);
+ return cr;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private Context getContext() {
+ return Application.context;
+ }
+
+ @Override
+ public String getDateVersion() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/version/date", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public String getMainVersion() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/version/main", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public String getDbType() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/type", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public String getDbHost() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/host", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public int getDbPort() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/port", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return Integer.parseInt(response.getText());
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public String getDbName() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/name", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public String getConnectionURL() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/url", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public String getDbUid() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/uid", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public String getDbPwd() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/password", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public String getFwHost() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/fwhost", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return response != null ? response.getText() : "";
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public int getFwPort() {
+ try {
+ URI uri = new URI("https", null, CConnection.get().getAppsHost(), CConnection.get().getSSLPort(), "/admin/server/status/database/fwport", null, null);
+ ClientResource resource = createClientResource(uri);
+ Representation response = resource.get();
+ return Integer.parseInt(response.getText());
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+}
diff --git a/client/src/org/compiere/apps/AEnv.java b/client/src/org/compiere/apps/AEnv.java
index 5751f15a20..1ddec839d5 100644
--- a/client/src/org/compiere/apps/AEnv.java
+++ b/client/src/org/compiere/apps/AEnv.java
@@ -953,7 +953,7 @@ public final class AEnv
Server server = CConnection.get().getServer();
if (server != null)
{
- server.cacheReset(tableName, Record_ID);
+ server.cacheReset(Env.getRemoteCallCtx(Env.getCtx()), tableName, Record_ID);
}
}
catch (Exception e)
diff --git a/client/src/org/compiere/apps/ALogin.java b/client/src/org/compiere/apps/ALogin.java
index 4608a176a8..bc986f7cc1 100644
--- a/client/src/org/compiere/apps/ALogin.java
+++ b/client/src/org/compiere/apps/ALogin.java
@@ -112,7 +112,6 @@ public final class ALogin extends CDialog
private CPanel mainPanel = new CPanel(new BorderLayout());
private CTabbedPane loginTabPane = new CTabbedPane();
-// private BorderLayout conTabLayout = new BorderLayout();
private CPanel connectionPanel = new CPanel();
private CLabel hostLabel = new CLabel();
private CConnectionEditor hostField = new CConnectionEditor();
@@ -121,7 +120,6 @@ public final class ALogin extends CDialog
private CLabel passwordLabel = new CLabel();
private JPasswordField passwordField = new JPasswordField();
private CPanel defaultPanel = new CPanel();
-// private BorderLayout defaultLayout = new BorderLayout();
private CLabel clientLabel = new CLabel();
private CLabel orgLabel = new CLabel();
private CLabel dateLabel = new CLabel();
@@ -147,17 +145,13 @@ public final class ALogin extends CDialog
private BorderLayout southLayout = new BorderLayout();
private StatusBar statusBar = new StatusBar();
private ConfirmPanel confirmPanel = new ConfirmPanel(true, false, false, false, false, false, false);
- //private OnlineHelp onlineHelp = new OnlineHelp(true);
- //private CPanel helpPanel = new CPanel();
- // private JScrollPane helpScrollPane = new JScrollPane();
- // private BorderLayout helpLayout = new BorderLayout();
/** Server Connection */
private CConnection m_cc;
/** Application User */
private String m_user;
/** Application Password */
- private String m_pwd;
+ private char[] m_pwd = new char[0];
/** Combo Active */
private boolean m_comboActive = false;
@@ -411,8 +405,11 @@ public final class ALogin extends CDialog
} // processWindowEvent
private void validateAppServer() {
- if (!CConnection.isServerEmbedded())
- m_cc.testAppsServer();
+ m_user = userTextField.getText();
+ m_pwd = passwordField.getPassword();
+
+ m_cc.setAppServerCredential(m_user, m_pwd);
+ m_cc.testAppsServer();
}
private void connectToDatabase() {
@@ -557,7 +554,7 @@ public final class ALogin extends CDialog
if (loginTabPane.getSelectedIndex() == 2) // allow access to help
return;
- if (!(String.valueOf(passwordField.getPassword()).equals(m_pwd)
+ if (!(String.valueOf(passwordField.getPassword()).equals(String.valueOf(m_pwd))
&& userTextField.getText().equals(m_user)))
m_connectionOK = false;
//
@@ -623,7 +620,7 @@ public final class ALogin extends CDialog
private boolean tryConnection()
{
m_user = userTextField.getText();
- m_pwd = new String (passwordField.getPassword());
+ m_pwd = passwordField.getPassword();
// Establish connection
if (!DB.isConnected(false))
@@ -647,7 +644,7 @@ public final class ALogin extends CDialog
KeyNamePair[] roles = null;
try
{
- roles = m_login.getRoles(m_user, m_pwd);
+ roles = m_login.getRoles(m_user, new String(m_pwd));
if (roles == null || roles.length == 0)
{
statusBar.setStatusLine(txt_UserPwdError, true);
@@ -945,7 +942,8 @@ public final class ALogin extends CDialog
txt_LoggedIn = res.getString("Authorized");
//
loginTabPane.setTitleAt(0, res.getString("Connection"));
- loginTabPane.setTitleAt(1, res.getString("Defaults"));
+ if (loginTabPane.getTabCount() > 1)
+ loginTabPane.setTitleAt(1, res.getString("Defaults"));
confirmPanel.getOKButton().setToolTipText(res.getString("Ok"));
confirmPanel.getCancelButton().setToolTipText(res.getString("Cancel"));
diff --git a/client/src/org/compiere/apps/AMenu.java b/client/src/org/compiere/apps/AMenu.java
index d567680c67..e46366bc39 100644
--- a/client/src/org/compiere/apps/AMenu.java
+++ b/client/src/org/compiere/apps/AMenu.java
@@ -37,6 +37,7 @@ import java.beans.PropertyChangeListener;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.Properties;
+import java.util.UUID;
import java.util.logging.Level;
import javax.swing.BorderFactory;
@@ -55,6 +56,7 @@ import org.adempiere.plaf.AdempierePLAF;
import org.compiere.Adempiere;
import org.compiere.apps.wf.WFActivity;
import org.compiere.apps.wf.WFPanel;
+import org.compiere.db.CConnection;
import org.compiere.grid.tree.VTreePanel;
import org.compiere.model.MRole;
import org.compiere.model.MSession;
@@ -62,8 +64,6 @@ import org.compiere.model.MSysConfig;
import org.compiere.model.MSystem;
import org.compiere.model.MTreeNode;
import org.compiere.model.MUser;
-import org.compiere.print.ReportCtl;
-import org.compiere.print.SwingViewerProvider;
import org.compiere.swing.CButton;
import org.compiere.swing.CFrame;
import org.compiere.swing.CPanel;
@@ -122,7 +122,11 @@ public final class AMenu extends CFrame
//
if (!Adempiere.startupEnvironment(true)) // Load Environment
System.exit(1);
- MSession.get (Env.getCtx(), true); // Start Session
+ MSession session = MSession.get (Env.getCtx(), true); // Start Session
+ session.setWebSession(UUID.randomUUID().toString());
+ session.setDescription(session.getDescription() + " " + "Swing Client");
+ session.saveEx();
+ CConnection.get().setAppServerCredential("AD_Session_ID#"+session.getAD_Session_ID(), session.getWebSession().toCharArray());
// Setting close operation/listener - teo_sarca [ 1684168 ]
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
diff --git a/client/src/org/compiere/db/CConnectionDialog.java b/client/src/org/compiere/db/CConnectionDialog.java
index ff24bdee8a..4e41b2fe59 100644
--- a/client/src/org/compiere/db/CConnectionDialog.java
+++ b/client/src/org/compiere/db/CConnectionDialog.java
@@ -33,7 +33,9 @@ import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
+import org.adempiere.client.ClientCredentialDialog;
import org.adempiere.plaf.AdempierePLAF;
+import org.compiere.apps.AEnv;
import org.compiere.swing.CButton;
import org.compiere.swing.CCheckBox;
import org.compiere.swing.CComboBox;
@@ -43,7 +45,6 @@ import org.compiere.swing.CPanel;
import org.compiere.swing.CTextField;
import org.compiere.util.CLogger;
import org.compiere.util.Ini;
-import org.compiere.util.ValueNamePair;
/**
* Connection Dialog.
@@ -89,18 +90,10 @@ public class CConnectionDialog extends CDialog implements ActionListener
/** Resources */
private static ResourceBundle res = ResourceBundle.getBundle("org.compiere.db.DBRes");
- static
- {
- /** Connection Profiles */
- CConnection.CONNECTIONProfiles = new ValueNamePair[]{
- new ValueNamePair("L", res.getString("LAN")),
- new ValueNamePair("V", res.getString("VPN")),
- new ValueNamePair("W", res.getString("WAN"))
- };
- }
-
/** Default HTTP Port */
public static final String APPS_PORT_HTTP = "80";
+ /** Default SSL Port */
+ public static final String APPS_PORT_SSL = "443";
/** Connection */
private CConnection m_cc = null;
private CConnection m_ccResult = null;
@@ -136,6 +129,8 @@ public class CConnectionDialog extends CDialog implements ActionListener
private CCheckBox cbBequeath = new CCheckBox();
private CLabel appsHostLabel = new CLabel();
private CTextField appsHostField = new CTextField();
+ private CLabel sslPortLabel = new CLabel();
+ private CTextField sslPortField = new CTextField();
private CButton bTestApps = new CButton();
//private CCheckBox cbOverwrite = new CCheckBox();
private CLabel dbUidLabel = new CLabel();
@@ -176,6 +171,8 @@ public class CConnectionDialog extends CDialog implements ActionListener
cbBequeath.setText(res.getString("BequeathConnection"));
appsHostLabel.setText(res.getString("AppsHost"));
appsHostField.setColumns(30);
+ sslPortLabel.setText(res.getString("AppsPort"));
+ sslPortField.setColumns(10);
bTestApps.setText(res.getString("TestApps"));
bTestApps.setHorizontalAlignment(JLabel.LEFT);
//cbOverwrite.setText(res.getString("Overwrite"));
@@ -195,7 +192,10 @@ public class CConnectionDialog extends CDialog implements ActionListener
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 12, 5, 5), 0, 0));
centerPanel.add(appsHostField, new GridBagConstraints(1, 1, 2, 1, 0.0, 0.0
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 12), 0, 0));
-
+ centerPanel.add(sslPortLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0
+ ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 12, 5, 5), 0, 0));
+ centerPanel.add(sslPortField, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0
+ ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
//
centerPanel.add(bTestApps, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0
,GridBagConstraints.SOUTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 12, 0), 0, 0));
@@ -241,7 +241,7 @@ public class CConnectionDialog extends CDialog implements ActionListener
//
nameField.addActionListener(this);
appsHostField.addActionListener(this);
- //cbOverwrite.addActionListener(this);
+ sslPortField.addActionListener(this);
bTestApps.addActionListener(this);
//
dbTypeField.addActionListener(this);
@@ -261,6 +261,8 @@ public class CConnectionDialog extends CDialog implements ActionListener
{
appsHostLabel.setVisible(false);
appsHostField.setVisible(false);
+ sslPortLabel.setVisible(false);
+ sslPortField.setVisible(false);
bTestApps.setVisible(false);
}
else // Client
@@ -352,7 +354,16 @@ public class CConnectionDialog extends CDialog implements ActionListener
updateCConnection();
//
if (src == bTestApps)
- cmd_testApps();
+ {
+ ClientCredentialDialog ccd = new ClientCredentialDialog(this);
+ ccd.setModal(true);
+ AEnv.showCenterWindow(this, ccd);
+ if (ccd.isOKpressed())
+ {
+ m_cc.setAppServerCredential(ccd.getUserId(), ccd.getPassword());
+ cmd_testApps();
+ }
+ }
// Database Selection Changed
else if (src == dbTypeField)
@@ -379,6 +390,9 @@ public class CConnectionDialog extends CDialog implements ActionListener
//hengsin: avoid unnecessary requery of application server status
if (!appsHostField.getText().equals(m_cc.getAppsHost()))
m_cc.setAppsHost(appsHostField.getText());
+ if (!sslPortField.getText().equals(Integer.toString(m_cc.getSSLPort())))
+ m_cc.setSSLPort(sslPortField.getText());
+
}
else
m_cc.setAppsHost("localhost");
@@ -403,12 +417,13 @@ public class CConnectionDialog extends CDialog implements ActionListener
m_updating = true;
nameField.setText(m_cc.getName());
appsHostField.setText(m_cc.getAppsHost());
+ sslPortField.setText(String.valueOf(m_cc.getSSLPort()));
//
bTestApps.setIcon(getStatusIcon(m_cc.isAppsServerOK(false)));
// bTestApps.setToolTipText(m_cc.getRmiUri());
//cbOverwrite.setVisible(m_cc.isAppsServerOK(false));
- boolean rw = CConnection.isServerEmbedded() ? true : !m_cc.isAppsServerOK(false);
+ boolean rw = !m_cc.isAppsServerOK(false);
//
dbTypeLabel.setReadWrite(rw);
dbTypeField.setReadWrite(rw);
@@ -485,6 +500,8 @@ public class CConnectionDialog extends CDialog implements ActionListener
private void cmd_testApps()
{
setBusy (true);
+ m_cc.setAppsHost(appsHostField.getText());
+ m_cc.setSSLPort(sslPortField.getText());
Exception e = m_cc.testAppsServer();
if (e != null)
{
diff --git a/install/src/org/compiere/install/ConfigurationData.java b/install/src/org/compiere/install/ConfigurationData.java
index b8b210562a..51133bd619 100644
--- a/install/src/org/compiere/install/ConfigurationData.java
+++ b/install/src/org/compiere/install/ConfigurationData.java
@@ -759,8 +759,6 @@ public class ConfigurationData
log.warning("Open Socket " + host + ":" + port + " - " + pingSocket);
log.fine(host + ":" + port + " - " + pingSocket);
- if (pingSocket == null)
- return false;
// success
try
{
@@ -848,18 +846,14 @@ public class ConfigurationData
getDatabaseServer(), getDatabasePort(), getDatabaseName(),
getDatabaseUser(), getDatabasePassword());
cc.setAppsHost(getAppsServer());
- cc.setConnectionProfile(CConnection.PROFILE_LAN);
+ cc.setWebPort(getAppsServerWebPort());
+ cc.setSSLPort(getAppsServerSSLPort());
}
catch(Exception e)
{
log.log(Level.SEVERE, "connection", e);
return false;
}
- if (cc == null)
- {
- log.warning("No Connection");
- return false;
- }
Ini.setProperty(Ini.P_CONNECTION, cc.toStringLong());
Ini.saveProperties(false);
return true;
@@ -1339,6 +1333,7 @@ public class ConfigurationData
else
updateProperty(ADEMPIERE_DB_PASSWORD, databasePassword);
}
+
/**
* @return Returns the databasePort.
*/
diff --git a/serverRoot/META-INF/MANIFEST.MF b/serverRoot/META-INF/MANIFEST.MF
index c0cafd46ac..0819a36fe3 100644
--- a/serverRoot/META-INF/MANIFEST.MF
+++ b/serverRoot/META-INF/MANIFEST.MF
@@ -15,3 +15,12 @@ Eclipse-RegisterBuddy: org.adempiere.tools
Bundle-ClassPath: WEB-INF/lib/jardiff.jar,
WEB-INF/lib/jnlp-servlet.jar,
.
+Import-Package: org.restlet,
+ org.restlet.data,
+ org.restlet.ext.servlet,
+ org.restlet.representation,
+ org.restlet.resource,
+ org.restlet.routing,
+ org.restlet.security,
+ org.restlet.service,
+ org.restlet.util
diff --git a/serverRoot/WEB-INF/web.xml b/serverRoot/WEB-INF/web.xml
index 301baa1e4c..1442c4cb53 100644
--- a/serverRoot/WEB-INF/web.xml
+++ b/serverRoot/WEB-INF/web.xml
@@ -42,6 +42,16 @@
org.compiere.web.AdempiereMonitor
1
+
+
+ RestletServlet
+ org.restlet.ext.servlet.ServerServlet
+
+
+ org.restlet.application
+ org.adempiere.web.server.ServerApplication
+
+
JnlpDownloadServlet
*.jnlp
@@ -54,6 +64,10 @@
AdempiereMonitor
/adempiereMonitor/*
+
+ RestletServlet
+ /server/*
+
15
@@ -69,6 +83,19 @@
jnlp
application/x-java-jnlp-file
+
+
+ admin
+ /adempiereMonitor/*
+
+
+ service
+ /server/*
+
+
+ CONFIDENTIAL
+
+
adempiere.html
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/BasicVerifier.java b/serverRoot/src/main/servlet/org/adempiere/web/server/BasicVerifier.java
new file mode 100644
index 0000000000..9be478bd57
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/BasicVerifier.java
@@ -0,0 +1,83 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server;
+
+import java.util.Properties;
+import java.util.logging.Level;
+
+import org.compiere.model.MSession;
+import org.compiere.util.CLogger;
+import org.compiere.util.Env;
+import org.compiere.util.KeyNamePair;
+import org.compiere.util.Login;
+import org.restlet.security.SecretVerifier;
+
+/**
+ * Http basic authentication implementation. Support authentication using session token or
+ * userid+password
+ * @author hengsin
+ */
+public class BasicVerifier extends SecretVerifier {
+
+ private final static CLogger log = CLogger.getCLogger(BasicVerifier.class);
+
+ /* (non-Javadoc)
+ * @see org.restlet.security.SecretVerifier#verify(java.lang.String, char[])
+ */
+ @Override
+ public boolean verify(String identity, char[] password)
+ throws IllegalArgumentException {
+ //authenticate with session token
+ if (identity.startsWith("AD_Session_ID#"))
+ {
+ String sessionId = identity.substring("AD_Session_ID#".length());
+ int AD_Session_ID = 0;
+ try
+ {
+ AD_Session_ID = Integer.parseInt(sessionId);
+ }
+ catch (Exception e)
+ {
+ log.log(Level.WARNING, "Invalid session token: " + identity);
+ return false;
+ }
+ MSession session = new MSession(Env.getCtx(), AD_Session_ID, null);
+ if (session.getAD_Session_ID() != AD_Session_ID)
+ {
+ log.log(Level.WARNING, "Session not exists in database: " + identity);
+ return false;
+ }
+ if (session.isProcessed())
+ {
+ log.log(Level.WARNING, "Session have logout: " + identity);
+ return false;
+ }
+ if (!session.isActive())
+ {
+ log.log(Level.WARNING, "Session isActive=false: " + identity);
+ return false;
+ }
+ if (!session.getWebSession().equals(new String(password)))
+ {
+ log.log(Level.WARNING, "Session token doesn't match. identity=" + identity + ", token="+new String(password));
+ }
+ return true;
+ }
+
+ //authenticate with userid+password
+ Login login = new Login(new Properties());
+ KeyNamePair[] roles = login.getRoles(identity, new String(password));
+ return (roles != null && roles.length > 0);
+ }
+
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/ServerApplication.java b/serverRoot/src/main/servlet/org/adempiere/web/server/ServerApplication.java
new file mode 100644
index 0000000000..d1906c99c3
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/ServerApplication.java
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server;
+
+import org.adempiere.web.server.command.ExecuteProcessCommand;
+import org.adempiere.web.server.command.ExecuteTaskCommand;
+import org.adempiere.web.server.command.ExecuteWorkflowCommand;
+import org.adempiere.web.server.command.PostDocumentCommand;
+import org.adempiere.web.server.command.ResetCacheCommand;
+import org.adempiere.web.server.command.SendEmailCommand;
+import org.adempiere.web.server.status.DatabaseResource;
+import org.adempiere.web.server.status.VersionResource;
+import org.restlet.Application;
+import org.restlet.Restlet;
+import org.restlet.data.ChallengeScheme;
+import org.restlet.routing.Router;
+import org.restlet.security.ChallengeAuthenticator;
+
+/**
+ * Restlet application for /command and /status service.
+ * @author hengsin
+ */
+public class ServerApplication extends Application {
+
+ /**
+ * Creates a root Restlet that will receive all incoming calls.
+ */
+ @Override
+ public synchronized Restlet createInboundRoot() {
+ // Create a router Restlet that routes each call to a new instance of HelloWorldResource.
+ Router router = new Router(getContext());
+
+ // Defines command route
+ // The command handler discovery can be refactor to use equinox extension in future to make this
+ // extensible
+ router.attach("/command/postDocument", PostDocumentCommand.class);
+ router.attach("/command/executeProcess", ExecuteProcessCommand.class);
+ router.attach("/command/executeWorkflow", ExecuteWorkflowCommand.class);
+ router.attach("/command/executeTask", ExecuteTaskCommand.class);
+ router.attach("/command/sendEmail", SendEmailCommand.class);
+ router.attach("/command/resetCache", ResetCacheCommand.class);
+
+ // Defines config route
+ router.attach("/status/version/{type}", VersionResource.class);
+ router.attach("/status/database/{property}", DatabaseResource.class);
+
+
+ // Authenticate the whole hierarchy of URIs
+ ChallengeAuthenticator guard = new ChallengeAuthenticator(getContext(),
+ ChallengeScheme.HTTP_BASIC, "adempiere realm");
+ guard.setVerifier(new BasicVerifier());
+ guard.setOptional(false);
+
+ guard.setNext(router);
+
+ return guard;
+ }
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteProcessCommand.java b/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteProcessCommand.java
new file mode 100644
index 0000000000..b9c7df3f6c
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteProcessCommand.java
@@ -0,0 +1,81 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server.command;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.util.RestletUtil;
+import org.compiere.interfaces.impl.ServerBean;
+import org.compiere.model.MRole;
+import org.compiere.process.ProcessInfo;
+import org.compiere.util.Env;
+import org.restlet.resource.ResourceException;
+import org.restlet.resource.ServerResource;
+import org.restlet.representation.ObjectRepresentation;
+import org.restlet.representation.Representation;
+
+/**
+ * Command to execute java or db process ( AD_Process )
+ * @author hengsin
+ *
+ */
+public class ExecuteProcessCommand extends ServerResource {
+
+ @Override
+ protected Representation post(Representation entity)
+ throws ResourceException {
+ try {
+ HashMap map = RestletUtil.toObject(entity);
+ return new ObjectRepresentation(accept(map));
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public boolean isNegotiated() {
+ return false;
+ }
+
+ private ProcessInfo accept(HashMap entity) {
+ Properties context = (Properties) entity.get("context");
+ ProcessInfo pi = (ProcessInfo) entity.get("processInfo");
+ String procedureName = (String) entity.get("procedureName");
+
+ MRole role = MRole.get(context, Env.getAD_Role_ID(context), Env.getAD_User_ID(context), false);
+ if (!role.getProcessAccess(pi.getAD_Process_ID())) {
+ throw new AdempiereException("Access denied.");
+ }
+
+ ServerBean bean = new ServerBean();
+ //back up properties
+ Properties backup = new Properties();
+ backup.putAll(Env.getCtx());
+ try
+ {
+ Env.setCtx(context);
+ if (procedureName != null && procedureName.trim().length() > 0)
+ return bean.dbProcess(context, pi, procedureName);
+ else
+ return bean.process(context, pi);
+ }
+ finally
+ {
+ Env.setCtx(backup);
+ }
+ }
+
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteTaskCommand.java b/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteTaskCommand.java
new file mode 100644
index 0000000000..be39be01de
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteTaskCommand.java
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server.command;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.util.RestletUtil;
+import org.compiere.interfaces.impl.ServerBean;
+import org.compiere.model.MRole;
+import org.compiere.util.Env;
+import org.restlet.representation.Representation;
+import org.restlet.representation.StringRepresentation;
+import org.restlet.resource.ResourceException;
+import org.restlet.resource.ServerResource;
+
+/**
+ * Command to execute task ( AD_Task )
+ * @author hengsin
+ */
+public class ExecuteTaskCommand extends ServerResource {
+ @Override
+ protected Representation post(Representation entity)
+ throws ResourceException {
+ try {
+ HashMap map = RestletUtil.toObject(entity);
+ return new StringRepresentation(accept(map));
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public boolean isNegotiated() {
+ return false;
+ }
+
+ private String accept(HashMap entity) {
+ Properties context = (Properties) entity.get("context");
+ int AD_Task_ID = (Integer) entity.get("AD_Task_ID");
+
+ MRole role = MRole.get(context, Env.getAD_Role_ID(context), Env.getAD_User_ID(context), false);
+ if (!role.getTaskAccess(AD_Task_ID)) {
+ throw new AdempiereException("Access denied.");
+ }
+
+ ServerBean bean = new ServerBean();
+ //back up properties
+ Properties backup = new Properties();
+ backup.putAll(Env.getCtx());
+ try
+ {
+ Env.setCtx(context);
+ return bean.executeTask(context, AD_Task_ID);
+ }
+ finally
+ {
+ Env.setCtx(backup);
+ }
+ }
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteWorkflowCommand.java b/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteWorkflowCommand.java
new file mode 100644
index 0000000000..bc7eb9148a
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/command/ExecuteWorkflowCommand.java
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server.command;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.util.RestletUtil;
+import org.compiere.interfaces.impl.ServerBean;
+import org.compiere.model.MRole;
+import org.compiere.process.ProcessInfo;
+import org.compiere.util.Env;
+import org.restlet.representation.ObjectRepresentation;
+import org.restlet.representation.Representation;
+import org.restlet.resource.ResourceException;
+import org.restlet.resource.ServerResource;
+
+/**
+ * Command to execute workflow ( AD_Workflow )
+ * @author hengsin
+ */
+public class ExecuteWorkflowCommand extends ServerResource {
+
+ @Override
+ protected Representation post(Representation entity)
+ throws ResourceException {
+ try {
+ HashMap map = RestletUtil.toObject(entity);
+ return new ObjectRepresentation(accept(map));
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public boolean isNegotiated() {
+ return false;
+ }
+
+ private ProcessInfo accept(HashMap entity) {
+ Properties context = (Properties) entity.get("context");
+ ProcessInfo pi = (ProcessInfo) entity.get("processInfo");
+
+ int AD_Workflow_ID = (Integer) entity.get("AD_Workflow_ID");
+ MRole role = MRole.get(context, Env.getAD_Role_ID(context), Env.getAD_User_ID(context), false);
+ if (!role.getWorkflowAccess(AD_Workflow_ID)) {
+ throw new AdempiereException("Access denied.");
+ }
+
+ ServerBean bean = new ServerBean();
+ //back up properties
+ Properties backup = new Properties();
+ backup.putAll(Env.getCtx());
+ try
+ {
+ Env.setCtx(context);
+ return bean.workflow(context, pi, AD_Workflow_ID);
+ }
+ finally
+ {
+ Env.setCtx(backup);
+ }
+ }
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/command/PostDocumentCommand.java b/serverRoot/src/main/servlet/org/adempiere/web/server/command/PostDocumentCommand.java
new file mode 100644
index 0000000000..eb4bb68315
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/command/PostDocumentCommand.java
@@ -0,0 +1,74 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server.command;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.util.RestletUtil;
+import org.compiere.interfaces.impl.ServerBean;
+import org.compiere.util.Env;
+import org.restlet.representation.Representation;
+import org.restlet.representation.StringRepresentation;
+import org.restlet.resource.ResourceException;
+import org.restlet.resource.ServerResource;
+
+/**
+ * Command to post accounting document.
+ * @author hengsin
+ */
+public class PostDocumentCommand extends ServerResource {
+
+ @Override
+ protected Representation post(Representation entity)
+ throws ResourceException {
+ try {
+ HashMap map = RestletUtil.toObject(entity);
+ return new StringRepresentation(accept(map));
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public boolean isNegotiated() {
+ return false;
+ }
+
+ private String accept(HashMap entity) {
+ String msg = null;
+
+ Properties context = (Properties) entity.get("context");
+ int AD_Client_ID = Env.getAD_Client_ID(context);
+ int AD_Table_ID = (Integer) entity.get("AD_Table_ID");
+ int Record_ID = (Integer) entity.get("Record_ID");
+ boolean force = (Boolean) entity.get("force");
+
+ ServerBean bean = new ServerBean();
+ //back up properties
+ Properties backup = new Properties();
+ backup.putAll(Env.getCtx());
+ try
+ {
+ Env.setCtx(context);
+ msg = bean.postImmediate(context, AD_Client_ID, AD_Table_ID, Record_ID, force);
+ }
+ finally
+ {
+ Env.setCtx(backup);
+ }
+ return msg;
+ }
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/command/ResetCacheCommand.java b/serverRoot/src/main/servlet/org/adempiere/web/server/command/ResetCacheCommand.java
new file mode 100644
index 0000000000..9b445a5c31
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/command/ResetCacheCommand.java
@@ -0,0 +1,69 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server.command;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.util.RestletUtil;
+import org.compiere.interfaces.impl.ServerBean;
+import org.compiere.util.Env;
+import org.restlet.representation.Representation;
+import org.restlet.representation.StringRepresentation;
+import org.restlet.resource.ResourceException;
+import org.restlet.resource.ServerResource;
+
+/**
+ * Command to reset cache at server.
+ * @author hengsin
+ */
+public class ResetCacheCommand extends ServerResource {
+ @Override
+ protected Representation post(Representation entity)
+ throws ResourceException {
+ try {
+ HashMap map = RestletUtil.toObject(entity);
+ int i = accept(map);
+ return new StringRepresentation(Integer.toString(i));
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public boolean isNegotiated() {
+ return false;
+ }
+
+ private int accept(HashMap entity) {
+ Properties context = (Properties) entity.get("context");
+ int Record_ID = (Integer) entity.get("Record_ID");
+ String tableName = (String) entity.get("tableName");
+
+ ServerBean bean = new ServerBean();
+ //back up properties
+ Properties backup = new Properties();
+ backup.putAll(Env.getCtx());
+ try
+ {
+ Env.setCtx(context);
+ return bean.cacheReset(context, tableName, Record_ID);
+ }
+ finally
+ {
+ Env.setCtx(backup);
+ }
+ }
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/command/SendEmailCommand.java b/serverRoot/src/main/servlet/org/adempiere/web/server/command/SendEmailCommand.java
new file mode 100644
index 0000000000..bcec437bb5
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/command/SendEmailCommand.java
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server.command;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.util.RestletUtil;
+import org.compiere.interfaces.impl.ServerBean;
+import org.compiere.util.EMail;
+import org.compiere.util.Env;
+import org.restlet.representation.Representation;
+import org.restlet.representation.StringRepresentation;
+import org.restlet.resource.ResourceException;
+import org.restlet.resource.ServerResource;
+
+/**
+ * Command to send email from server.
+ * @author hengsin
+ */
+public class SendEmailCommand extends ServerResource {
+ @Override
+ protected Representation post(Representation entity)
+ throws ResourceException {
+ try {
+ HashMap map = RestletUtil.toObject(entity);
+ return new StringRepresentation(accept(map));
+ } catch (Exception e) {
+ throw new AdempiereException(e);
+ }
+ }
+
+ @Override
+ public boolean isNegotiated() {
+ return false;
+ }
+
+ private String accept(HashMap entity) {
+ Properties context = (Properties) entity.get("context");
+ EMail email = (EMail) entity.get("email");
+
+ ServerBean bean = new ServerBean();
+ //back up properties
+ Properties backup = new Properties();
+ backup.putAll(Env.getCtx());
+ try
+ {
+ Env.setCtx(context);
+ return bean.sendEMail(context, email);
+ }
+ finally
+ {
+ Env.setCtx(backup);
+ }
+ }
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/status/DatabaseResource.java b/serverRoot/src/main/servlet/org/adempiere/web/server/status/DatabaseResource.java
new file mode 100644
index 0000000000..b97b14fd35
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/status/DatabaseResource.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server.status;
+
+import org.compiere.interfaces.impl.StatusBean;
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+
+/**
+ * Implement support for remote database connection property query.
+ * @author hengsin
+ *
+ */
+public class DatabaseResource extends ServerResource {
+
+ @Get
+ public String represent() {
+ StatusBean status = new StatusBean();
+ String property = (String) getRequestAttributes().get("property");
+ String value = "";
+ if ("type".equalsIgnoreCase(property))
+ value = status.getDbType();
+ else if ("host".equals(property))
+ value = status.getDbHost();
+ else if ("port".equals(property))
+ value = Integer.toString(status.getDbPort());
+ else if ("name".equals(property))
+ value = status.getDbName();
+ else if ("url".equals(property))
+ value = status.getConnectionURL();
+ else if ("uid".equals(property))
+ value = status.getDbUid();
+ else if ("password".equals(property))
+ value = status.getDbPwd();
+ else if ("fwhost".equals(property))
+ value = status.getFwHost();
+ else if ("fwport".equals(property))
+ value = Integer.toString(status.getFwPort());
+
+ return value != null ? value : "";
+ }
+
+}
diff --git a/serverRoot/src/main/servlet/org/adempiere/web/server/status/VersionResource.java b/serverRoot/src/main/servlet/org/adempiere/web/server/status/VersionResource.java
new file mode 100644
index 0000000000..10701a555d
--- /dev/null
+++ b/serverRoot/src/main/servlet/org/adempiere/web/server/status/VersionResource.java
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Copyright (C) 2010 Low Heng Sin All Rights Reserved. *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms version 2 of the GNU General Public License as published *
+ * by the Free Software Foundation. This program 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 General Public License for more details. *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ *****************************************************************************/
+package org.adempiere.web.server.status;
+
+import org.compiere.interfaces.impl.StatusBean;
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+
+/**
+ * Implement remote version property query support.
+ * @author hengsin
+ *
+ */
+public class VersionResource extends ServerResource {
+
+ @Get
+ public String represent() {
+ String type = (String) getRequestAttributes().get("type");
+ if ("date".equalsIgnoreCase(type))
+ return new StatusBean().getDateVersion();
+ else if ("main".equalsIgnoreCase(type))
+ return new StatusBean().getMainVersion();
+ else
+ return "";
+ }
+}
diff --git a/serverRoot/src/main/servlet/org/compiere/web/AdempiereMonitor.java b/serverRoot/src/main/servlet/org/compiere/web/AdempiereMonitor.java
index b04f2d93dc..fde0c7cbbf 100644
--- a/serverRoot/src/main/servlet/org/compiere/web/AdempiereMonitor.java
+++ b/serverRoot/src/main/servlet/org/compiere/web/AdempiereMonitor.java
@@ -19,6 +19,7 @@ package org.compiere.web;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.RuntimeMXBean;
@@ -105,21 +106,45 @@ public class AdempiereMonitor extends HttpServlet
protected void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
+ boolean xmlOutput = false;
+ String responseType = request.getParameter("responseContentType");
+ xmlOutput = "xml".equalsIgnoreCase(responseType);
+
m_message = null;
if (processLogParameter (request, response))
+ {
+ if (xmlOutput)
+ createXMLSummaryPage(request, response);
return;
+ }
if (processTraceParameter (request, response))
+ {
+ if (xmlOutput)
+ createXMLSummaryPage(request, response);
return;
+ }
if (processEMailParameter (request, response))
+ {
+ if (xmlOutput)
+ createXMLSummaryPage(request, response);
return;
+ }
if (processCacheParameter (request, response))
+ {
+ if (xmlOutput)
+ createXMLSummaryPage(request, response);
return;
+ }
//
if (processRunNowParameter (request))
;
else
processActionParameter (request);
- createSummaryPage(request, response);
+
+ if (xmlOutput)
+ createXMLSummaryPage(request, response);
+ else
+ createSummaryPage(request, response);
} // doGet
/**
@@ -669,6 +694,107 @@ public class AdempiereMonitor extends HttpServlet
WebUtil.createResponse (request, response, this, null, doc, false);
} // createSummaryPage
+ /**************************************************************************
+ * Create & Return Summary Page
+ * @param request request
+ * @param response response
+ * @throws ServletException
+ * @throws IOException
+ */
+ private void createXMLSummaryPage (HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ response.setContentType("text/xml");
+ PrintWriter writer = response.getWriter();
+
+ writer.println("");
+
+ // message
+ writer.println("\t");
+ if (m_message != null)
+ {
+ writer.println(m_message);
+ }
+ writer.println("\t ");
+
+ // Summary
+ writer.print("\t");
+ writer.print(Adempiere.getName());
+ writer.println(" ");
+
+ writer.print("\t");
+ writer.print(Adempiere.getVersion());
+ writer.println(" ");
+
+ writer.print("\t");
+ writer.print(Adempiere.getImplementationVendor());
+ writer.println(" ");
+
+ writer.print("\t");
+ writer.print(Adempiere.getImplementationVersion());
+ writer.println(" ");
+
+ writer.println("\t");
+ writer.print("\t\t");
+ writer.print(m_serverMgr.getDescription());
+ writer.println(" ");
+ writer.print("\t\t");
+ writer.print(m_serverMgr.getStartTime());
+ writer.println(" ");
+ writer.print("\t\t");
+ writer.print(m_serverMgr.getServerCount());
+ writer.println(" ");
+
+ AdempiereServer[] servers = m_serverMgr.getAll();
+ for (int i = 0; i < servers.length; i++)
+ {
+ AdempiereServer server = servers[i];
+ writer.println("\t\t");
+ writer.print("\t\t\t");
+ writer.print(server.getServerID());
+ writer.println(" ");
+ writer.print("\t\t\t");
+ writer.print(server.getName());
+ writer.println(" ");
+ writer.print("\t\t\t");
+ writer.print(server.getDescription());
+ writer.println(" ");
+ writer.print("\t\t\t");
+ writer.print(server.getServerInfo());
+ writer.println(" ");
+ writer.print("\t\t\t");
+ if (server.isAlive())
+ {
+ if (server.isInterrupted())
+ writer.print("Interrupted");
+ else if (server.isSleeping())
+ writer.print("Sleeping");
+ else
+ writer.print("Running");
+ }
+ else
+ writer.print("Stopped");
+ writer.println(" ");
+ writer.print("\t\t\t");
+ writer.print(server.getStartTime());
+ writer.println(" ");
+ writer.print("\t\t\t");
+ writer.print(server.getDateLastRun());
+ writer.println(" ");
+ writer.print("\t\t\t");
+ writer.print(server.getDateNextRun(false));
+ writer.println(" ");
+ writer.print("\t\t\t");
+ writer.print(server.getStatistics());
+ writer.println(" ");
+ writer.println("\t\t ");
+ }
+
+ writer.println("\t ");
+
+ writer.flush();
+ } // createSummaryPage
+
/**
* Add Log Management to page
* @param bb body
diff --git a/serverRoot/src/main/servlet/org/compiere/web/StatusInfo.java b/serverRoot/src/main/servlet/org/compiere/web/StatusInfo.java
index 54f1e54d92..d0cc368b40 100644
--- a/serverRoot/src/main/servlet/org/compiere/web/StatusInfo.java
+++ b/serverRoot/src/main/servlet/org/compiere/web/StatusInfo.java
@@ -21,16 +21,12 @@ import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
-import javax.naming.InitialContext;
-import javax.naming.NamingEnumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.sql.DataSource;
-import org.compiere.interfaces.Server;
-import org.compiere.interfaces.Status;
+import org.compiere.db.CConnection;
/**
* Status Info Servlet
@@ -69,58 +65,10 @@ public class StatusInfo extends HttpServlet
out.println("Status Info ");
out.println("");
- InitialContext context = null;
try
{
- context = new InitialContext();
- }
- catch (Exception ex)
- {
- out.println("" + ex + "
");
- }
-
- try
- {
- Status status = (Status)context.lookup (Status.JNDI_NAME);
- out.println("" + status.getStatus() + "
");
- }
- catch (Exception ex)
- {
- out.println("" + ex + "
");
- }
-
- try
- {
- Server server = (Server)context.lookup (Server.JNDI_NAME);
- out.println("" + server.getStatus() + "
");
- }
- catch (Exception ex)
- {
- out.println("" + ex + "
");
- }
-
- try
- {
- out.println("-- /
");
- NamingEnumeration ne = context.list("/");
- while (ne.hasMore())
- out.println("
" + ne.nextElement());
- out.println("-- java
");
- ne = context.list("java:");
- while (ne.hasMore())
- out.println("
" + ne.nextElement());
- out.println("-- ejb
");
- ne = context.list("ejb");
- while (ne.hasMore())
- out.println("
" + ne.nextElement());
-
//
-
- out.println("-- DS
");
- DataSource ds = (DataSource)context.lookup("java:/OracleDS");
- out.println("
DataSource " + ds.getClass().getName() + " LoginTimeout=" + ds.getLoginTimeout());
-
- Connection con = ds.getConnection("adempiere","adempiere");
+ Connection con = CConnection.get().getConnection(true, Connection.TRANSACTION_READ_COMMITTED);
out.println("
Connection ");
getServletContext().log("Connection closed=" + con.isClosed());
diff --git a/uibase/src/org/compiere/apps/AbstractProcessCtl.java b/uibase/src/org/compiere/apps/AbstractProcessCtl.java
index 8abc542051..f9ec2a9d98 100644
--- a/uibase/src/org/compiere/apps/AbstractProcessCtl.java
+++ b/uibase/src/org/compiere/apps/AbstractProcessCtl.java
@@ -464,7 +464,7 @@ public abstract class AbstractProcessCtl implements Runnable
{
if (server != null)
{ // See ServerBean
- m_pi = server.dbProcess(m_pi, ProcedureName);
+ m_pi = server.dbProcess(Env.getRemoteCallCtx(Env.getCtx()), m_pi, ProcedureName);
log.finest("server => " + m_pi);
started = true;
}