*/
package eu.etaxonomy.cdm.api.application;
+import java.io.File;
+import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
-
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
import org.springframework.security.core.context.SecurityContext;
import eu.etaxonomy.cdm.api.cache.CdmServiceCacher;
private static CdmServiceCacher cdmServiceCacher;
+ private static String cdmlibVersion = null;
+ private static String cdmlibLastModified = null;
public static CdmApplicationState getInstance() {
if(cdmApplicationState == null) {
getInstance().setSecurityContext(null);
cdmApplicationState = null;
cdmServiceCacher = null;
+ cdmlibVersion = null;
+ cdmlibLastModified = null;
}
cdmServiceCacher = cacher;
}
+ public static void updateCdmlibManifestInfo() {
+ cdmlibVersion = null;
+ cdmlibLastModified = null;
+ String cdmlibPathPrefix = "lib/cdmlib-services-";
+ String jarSuffix = ".jar";
+ Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.cdmlib");
+ Dictionary<String, String> headers = bundle.getHeaders();
+ String bundleClasspath = headers.get(Constants.BUNDLE_CLASSPATH);
+ try {
+ ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, bundleClasspath);
+ for (ManifestElement manifestElement : elements) {
+ String jar = manifestElement.getValue();
+ if(jar.startsWith(cdmlibPathPrefix) && jar.endsWith(jarSuffix)) {
+ URL fileURL = bundle.getEntry(jar);
+ File file = null;
+ try {
+ file = new File(FileLocator.resolve(fileURL).toURI());
+ JarFile jarFile = new JarFile(file);
+ Manifest manifest = jarFile.getManifest();
+ Attributes attributes = manifest.getMainAttributes();
+ // from the OSGI spec the LastModified value is " the number of milliseconds
+ // since midnight Jan. 1, 1970 UTC with the condition that a change must
+ // always result in a higher value than the previous last modified time
+ // of any bundle"
+ cdmlibVersion = attributes.getValue("Bundle-Version");
+ cdmlibLastModified = attributes.getValue("Bnd-LastModified");
+
+ if(cdmlibVersion == null || cdmlibLastModified == null) {
+ throw new IllegalStateException("Invalid cdmlib manifest info");
+ }
+ } catch (URISyntaxException urise) {
+ throw new IllegalStateException(urise);
+ } catch (IOException ioe) {
+ throw new IllegalStateException(ioe);
+ }
+ }
+ }
+ } catch (BundleException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public static String getCdmlibVersion() {
+ if(cdmlibVersion == null) {
+ updateCdmlibManifestInfo();
+ }
+ return cdmlibVersion;
+ }
+ public static String getCdmlibLastModified() {
+ if(cdmlibLastModified == null) {
+ updateCdmlibManifestInfo();
+ }
+ return cdmlibLastModified;
+ }
}
import java.util.Comparator;
import java.util.List;
+import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
import eu.etaxonomy.cdm.config.CdmSourceException;
import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
import eu.etaxonomy.cdm.database.ICdmDataSource;
+import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
/**
private static List<CdmServerInfo> cdmServerInfoList;
+ private String cdmlibServicesVersion = "";
+ private String cdmlibServicesLastModified = "";
+
+
public CdmServerInfo(String name, String server, int port) {
this.name = name;
this.server = server;
this.port = port;
instances = new ArrayList<CdmInstanceInfo>();
+
}
return NAME_LOCALHOST_MGD.equals(name);
}
+ public String getCdmlibServicesVersion() {
+ return cdmlibServicesVersion;
+ }
+
+ public String getCdmlibLastModified() {
+ return cdmlibServicesLastModified;
+ }
+
public void refreshInstances() throws CDMServerException {
instances.clear();
if(isLocalhostMgd()) {
});
}
+ public void updateInfo() throws CDMServerException {
+ String url = "http://" + server + ":" + String.valueOf(port) + "/" + CDMSERVER_PREFIX + "/info.jsp";
+ String responseBody = getResponse(url);
+ if(responseBody != null) {
+ try {
+ JSONObject info = new JSONObject(responseBody);
+ cdmlibServicesVersion = info.getString("cdmlibServicesVersion");
+ cdmlibServicesLastModified = info.getString("cdmlibServicesLastModified");
+ } catch (JSONException e) {
+ throw new CDMServerException(e);
+ }
+ }
+ }
+
public void addInstancesViaHttp() throws CDMServerException {
+ updateInfo();
String url = "http://" + server + ":" + String.valueOf(port) + "/" + CDMSERVER_PREFIX + "/instances.jsp";
+ String responseBody = getResponse(url);
+ if(responseBody != null) {
+ try {
+ JSONArray array = new JSONArray(responseBody);
+ for(int i=0;i<array.length();i++) {
+ JSONObject instance = (JSONObject)array.get(i);
+ if(instance != null) {
+ JSONObject conf = (JSONObject)instance.get("configuration");
+ if(conf != null) {
+ String instanceName = conf.getString("instanceName");
+ // we need to remove the first (char) forward slash from
+ // the base path
+ String basePath = conf.getString("basePath").substring(1);
+ addInstance(instanceName, basePath);
+ logger.info("Added instance with name : " + instanceName + ", basePath : " + basePath);
+ }
+ }
+ }
+ } catch (JSONException e) {
+ throw new CDMServerException(e);
+ }
+ }
+ }
+ private String getResponse(String url) throws CDMServerException {
HttpClient client = new DefaultHttpClient();
+ HttpParams params = client.getParams();
+
+ HttpConnectionParams.setConnectionTimeout(params, 5000);
+ HttpConnectionParams.setSoTimeout(params, 5000);
+
HttpGet httpGet = new HttpGet(url);
logger.info("Executing request " + httpGet.getRequestLine());
} catch (IOException e) {
throw new CDMServerException(e);
}
-
-
- if(responseBody != null) {
- try {
- JSONArray array = new JSONArray(responseBody);
- for(int i=0;i<array.length();i++) {
- JSONObject instance = (JSONObject)array.get(i);
- if(instance != null) {
- JSONObject conf = (JSONObject)instance.get("configuration");
- if(conf != null) {
- String instanceName = conf.getString("instanceName");
- // we need to remove the first (char) forward slash from
- // the base path
- String basePath = conf.getString("basePath").substring(1);
- addInstance(instanceName, basePath);
- logger.info("Added instance with name : " + instanceName + ", basePath : " + basePath);
- }
- }
- }
- } catch (JSONException e) {
- throw new CDMServerException(e);
- }
- }
+ return responseBody;
}
public void addInstancesFromDataSourcesConfig() {
return null;
}
- public boolean pingServer(){
+ public boolean pingServer() {
try {
Socket s = new Socket(server, port);
logger.info("[CDM-Server] Available @ " + server + ":" + port );
+ updateInfo();
return true;
} catch (IOException ioe) {
+ } catch (CDMServerException e) {
+
}
return false;
}
return false;
}
+ public int compareDbSchemaVersion(CdmInstanceInfo instance, int port) throws CDMServerException {
+
+ ICdmRemoteSource crs = getCdmRemoteSource(instance, port);
+ String dbSchemaVersion;
+ try {
+ dbSchemaVersion = crs.getDbSchemaVersion();
+ } catch (CdmSourceException e) {
+ throw new CDMServerException(e);
+ }
+
+
+ if(dbSchemaVersion != null) {
+ return CdmMetaData.compareVersion(dbSchemaVersion, CdmMetaData.getDbSchemaVersion(), 3, null);
+ } else {
+ throw new CDMServerException("Cannot determine editor db. schema version");
+ }
+ }
+
+ public int compareCdmlibServicesVersion() throws CdmSourceException {
+ int result = 0;
+ String serverVersion = cdmlibServicesVersion;
+ String editorVersion = CdmApplicationState.getCdmlibVersion();
+
+ if(StringUtils.isBlank(serverVersion) || StringUtils.isBlank(editorVersion)) {
+ throw new CdmSourceException("cdmlib-services server or editor version is empty");
+ }
+
+ String[] serverVersionSplit = serverVersion.split("\\.");
+ String[] editorVersionSplit = editorVersion.split("\\.");
+
+ if(serverVersionSplit.length < 3 || editorVersionSplit.length < 3 || serverVersionSplit.length > 4 || editorVersionSplit.length > 4) {
+ throw new CdmSourceException("cdmlib-services server or editor version is invalid");
+ }
+
+ Integer serverVersionPart;
+ Integer editorVersionPart;
+
+ for(int i=0 ; i<3 ; i++) {
+ serverVersionPart = Integer.valueOf(serverVersionSplit[i]);
+ editorVersionPart = Integer.valueOf(editorVersionSplit[i]);
+
+ int partCompare = serverVersionPart.compareTo(editorVersionPart);
+ if (partCompare != 0){
+ return partCompare;
+ }
+ }
+ // at this point major, minor and patch versions are matching
+
+ if(StringUtils.isBlank(cdmlibServicesLastModified) || StringUtils.isBlank(CdmApplicationState.getCdmlibLastModified())) {
+ throw new CdmSourceException("cdmlib-services server or editor version is empty");
+ }
+
+ String cdmServerIgnoreVersion = System.getProperty("cdm.server.version.lm.ignore");
+ if(StringUtils.isBlank(cdmServerIgnoreVersion) || !cdmServerIgnoreVersion.equals("true")) {
+ Long serverLastModified = Long.valueOf(cdmlibServicesLastModified);
+ Long editorLastModified = Long.valueOf(CdmApplicationState.getCdmlibLastModified());
+ return serverLastModified.compareTo(editorLastModified);
+ }
+
+ return 0;
+
+ }
+
public static List<CdmServerInfo> getCdmServers() {
if(cdmServerInfoList == null) {
cdmServerInfoList = new ArrayList<CdmServerInfo>();
*/
@Override
public void onCreate(CdmBase cdmBase) {
- logger.warn("New Entity created : " + cdmBase);
+ logger.info("New Entity created : " + cdmBase);
if(CdmApplicationState.getCurrentAppConfig() instanceof CdmApplicationRemoteController){
((CdmApplicationRemoteController)CdmApplicationState.getCurrentAppConfig()).getCdmEntitySessionManager().getActiveSession().addNewCdmEntity(cdmBase);
}
*/
package eu.etaxonomy.taxeditor.ui.dialog;
+import java.text.SimpleDateFormat;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang.StringUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.model.metadata.CdmMetaData;
import eu.etaxonomy.taxeditor.model.MessagingUtils;
import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
import eu.etaxonomy.taxeditor.remoting.source.CdmRemoteSource;
private final static String STATUS_NO_INSTANCES = "No Instances Found";
private final static String STATUS_ERROR = "Error";
private final static String STATUS_REMOTING_NOT_ACTIVATED = "Remoting not activated";
+ private final static String STATUS_NOT_COMPATIBLE = "Not Compatible";
+
+ private final static String MESG_COMPATIBLE_EDITOR_OLD = "Please update the Taxonomic Editor (Help->Check for Updates) or choose a compatible cdm-server";
+ private final static String MESG_COMPATIBLE_SERVER_OLD = "Please update the chosen cdm-server or choose a compatible cdm-server";
+
private final static String STORE_PREFERENCES_NODE = "eu.etaxonomy.taxeditor.store";
private final static String LOGIN_NODE = "login";
private final int MIN_WIDTH = 530;
private final int MIN_HEIGHT = 220;
- private final int MIN_EXP_HEIGHT = 350;
+ private final int MIN_EXP_HEIGHT = 380;
private final int MESSAGE_HEIGHT = 25;
private Label lblEditorVersion;
private Text txtEditorVersion;
readPrefLastServerInstance();
}
+ setEditorInfo();
populateCdmServerCombo();
shlConnect.open();
shlConnect.layout();
lblServerVersion = new Label(compAdvanced, SWT.CENTER);
lblServerVersion.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
- lblServerVersion.setText("Server Version :");
+ lblServerVersion.setText("Server Cdmlib Version :");
lblServerVersion.setFont(SWTResourceManager.getFont("Ubuntu", 9, SWT.NORMAL));
txtServerVersion = new Text(compAdvanced, SWT.BORDER);
- txtServerVersion.setEnabled(false);
txtServerVersion.setEditable(false);
txtServerVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
new Label(compAdvanced, SWT.NONE);
lblEditorVersion = new Label(compAdvanced, SWT.CENTER);
lblEditorVersion.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
- lblEditorVersion.setText("Editor Version :");
+ lblEditorVersion.setText("Editor Cdmlib Version :");
lblEditorVersion.setFont(SWTResourceManager.getFont("Ubuntu", 9, SWT.NORMAL));
txtEditorVersion = new Text(compAdvanced, SWT.BORDER);
- txtEditorVersion.setEnabled(false);
txtEditorVersion.setEditable(false);
txtEditorVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
new Label(compAdvanced, SWT.NONE);
lblServerCDMVersion.setFont(SWTResourceManager.getFont("Ubuntu", 9, SWT.NORMAL));
txtServerCDMVersion = new Text(compAdvanced, SWT.BORDER);
- txtServerCDMVersion.setEnabled(false);
txtServerCDMVersion.setEditable(false);
txtServerCDMVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
new Label(compAdvanced, SWT.NONE);
lblEditorCDMVersion.setFont(SWTResourceManager.getFont("Ubuntu", 9, SWT.NORMAL));
txtEditorCDMVersion = new Text(compAdvanced, SWT.BORDER);
- txtEditorCDMVersion.setEnabled(false);
txtEditorCDMVersion.setEditable(false);
txtEditorCDMVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
private void checkSelectedCdmServer() {
- txtCdmInstanceStatus.setText("");
- txtPort.setEditable(false);
- txtPort.setEnabled(false);
+ clearOnServerChange();
emptyCredentials();
if(selectedCsii != null) {
if(selectedCsii.pingServer()) {
txtCdmServerStatus.setText(STATUS_AVAILABLE);
populateCdmInstanceCombo(true);
+ txtServerVersion.setText(selectedCsii.getCdmlibServicesVersion());
+ txtServerVersion.setToolTipText(generateLastModifiedTooltip(selectedCsii.getCdmlibLastModified()));
} else {
txtCdmServerStatus.setText(STATUS_NOT_AVAILABLE);
comboCdmInstance.setEnabled(false);
btnConnect.setEnabled(false);
txtCdmInstanceStatus.setText(STATUS_RETRIEVING);
+ txtCdmInstanceStatus.setToolTipText("");
Job job = new Job("Retrieve Server Instances") {
@Override
}
});
}
- } catch (CDMServerException e) {
+ } catch (final CDMServerException e) {
MessagingUtils.warn(getClass(), e);
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
- txtCdmInstanceStatus.setText(STATUS_REMOTING_NOT_ACTIVATED);
+ txtCdmInstanceStatus.setText(STATUS_NOT_AVAILABLE);
+ txtCdmInstanceStatus.setToolTipText(e.getMessage());
comboCdmInstance.setEnabled(false);
btnConnect.setEnabled(false);
}
private void refreshCdmInstance() {
txtCdmInstanceStatus.setText(STATUS_CHECKING_AVAILABILITY);
+ clearOnInstanceChange();
updateSelectedCdmInstance();
checkSelectedCdmInstance();
}
}
private void checkSelectedCdmInstance() {
+ boolean available = false;
+ String status = STATUS_NOT_AVAILABLE;
+ String message = null;
+
if(txtCdmServerStatus.getText().equals(STATUS_AVAILABLE)) {
try {
if(selectedCsii.pingInstance(selectedCdmInstance, getPort())) {
- txtCdmInstanceStatus.setText(STATUS_AVAILABLE);
- btnConnect.setEnabled(true);
+ status = STATUS_AVAILABLE;
+ available = true;
} else {
- txtCdmInstanceStatus.setText(STATUS_NOT_AVAILABLE);
- btnConnect.setEnabled(false);
+ status = STATUS_NOT_AVAILABLE;
+ available = false;
+ }
+
+ if(available) {
+ txtServerCDMVersion.setText(selectedCsii.getCdmRemoteSource(selectedCdmInstance, getPort()).getDbSchemaVersion());
+ int compareDbSchemaVersion = selectedCsii.compareDbSchemaVersion(selectedCdmInstance, getPort());
+ int compareCdmlibServicesVersion = selectedCsii.compareCdmlibServicesVersion();
+
+ if(compareDbSchemaVersion > 0 || compareCdmlibServicesVersion > 0) {
+ status = STATUS_NOT_COMPATIBLE;
+ available = false;
+ message = MESG_COMPATIBLE_EDITOR_OLD;
+ } else if(compareDbSchemaVersion < 0 || compareCdmlibServicesVersion < 0) {
+ status = STATUS_NOT_COMPATIBLE;
+ available = false;
+ message = MESG_COMPATIBLE_SERVER_OLD;
+ } else {
+ status = STATUS_AVAILABLE;
+ available = true;
+ message = "";
+ }
+
+
}
+
} catch (Exception e) {
- txtCdmInstanceStatus.setText(STATUS_NOT_AVAILABLE);
txtCdmInstanceStatus.setToolTipText(e.getMessage());
+ } finally {
+ btnConnect.setEnabled(available);
+ txtCdmInstanceStatus.setText(status);
+ if(!StringUtils.isBlank(message)) {
+ setMessage(message);
+ }
}
+
}
}
styledTxtMessage.setText(message);
styledTxtMessage.setVisible(true);
((GridData)styledTxtMessage.getLayoutData()).exclude = false;
- shlConnect.setSize(MIN_WIDTH, MIN_HEIGHT+MESSAGE_HEIGHT);
- shlConnect.setMinimumSize(MIN_WIDTH, MIN_HEIGHT+MESSAGE_HEIGHT);
+ shlConnect.setSize(MIN_WIDTH, getHeightWithoutMessage() + MESSAGE_HEIGHT);
+ shlConnect.setMinimumSize(MIN_WIDTH, getHeightWithoutMessage() + MESSAGE_HEIGHT);
} else {
styledTxtMessage.setText("");
styledTxtMessage.setVisible(false);
((GridData)styledTxtMessage.getLayoutData()).exclude = true;
- shlConnect.setSize(MIN_WIDTH, MIN_HEIGHT);
- shlConnect.setMinimumSize(MIN_WIDTH, MIN_HEIGHT);
+ shlConnect.setSize(MIN_WIDTH, getHeightWithoutMessage());
+ shlConnect.setMinimumSize(MIN_WIDTH, getHeightWithoutMessage());
}
remotingComposite.layout();
}
+ private int getHeightWithoutMessage() {
+ if(xpndblcmpstAdvanced.isExpanded()) {
+ return MIN_EXP_HEIGHT;
+ } else {
+ return MIN_HEIGHT;
+ }
+ }
public void hide(boolean isHidden) {
}
});
}
+
+ private String generateLastModifiedTooltip(String cdmlibLastModified) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss z");
+ Date cdmlibLastModifiedDate;
+ String cdmlibLastModifiedTimestamp = "";
+
+ cdmlibLastModifiedDate = new Date(Long.valueOf(cdmlibLastModified));
+ cdmlibLastModifiedTimestamp = sdf.format(cdmlibLastModifiedDate);
+
+ return "last modified : " + cdmlibLastModifiedTimestamp;
+ }
+
+ private void setEditorInfo() {
+ txtEditorCDMVersion.setText(CdmMetaData.getDbSchemaVersion());
+ txtEditorVersion.setText(CdmApplicationState.getCdmlibVersion());
+ txtEditorVersion.setToolTipText(generateLastModifiedTooltip(CdmApplicationState.getCdmlibLastModified()));
+ }
+
+ private void clearOnServerChange() {
+ setMessage("");
+ txtServerCDMVersion.setText("");
+ txtServerVersion.setText("");
+ txtServerVersion.setToolTipText("");
+ txtServerCDMVersion.setText("");
+ txtPort.setEditable(false);
+ txtPort.setEnabled(false);
+ }
+
+ private void clearOnInstanceChange() {
+ setMessage("");
+ txtServerCDMVersion.setText("");
+ }
+
+ private void updateOnServerChange(String serverVersion, String serverVersionTooltip) {
+
+ }
+
}
Taxon grandChildTaxon = Taxon.NewInstance(null, null);
TaxonNode grandChildTaxonNode = childTaxonNode.addChildTaxon(grandChildTaxon, null, null);
-
CdmStore.getService(ITaxonNodeService.class).merge(taxonNode,true);
Assert.assertEquals(taxonNode.getChildNodes().get(0).getId(), childTaxonNode.getId());
--- /dev/null
+// $Id$
+/**
+* Copyright (C) 2015 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.session;
+
+import org.junit.Test;
+import org.springframework.util.Assert;
+import org.unitils.UnitilsJUnit4;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+
+/**
+ * @author cmathew
+ * @date 5 Oct 2015
+ *
+ */
+public class CdmApplicationStateTest extends UnitilsJUnit4 {
+
+ @Test
+ public void testCdmlibManifestInfoUpdate() {
+ CdmApplicationState.updateCdmlibManifestInfo();
+ Assert.notNull(CdmApplicationState.getCdmlibVersion());
+ Assert.notNull(CdmApplicationState.getCdmlibLastModified());
+ }
+}