eu.etaxonomy.taxeditor.store/hibernate.log
eu.etaxonomy.taxeditor.store/target
eu.etaxonomy.taxeditor.test/screenshots/*.jpeg
+eu.etaxonomy.taxeditor.test/src/test/resources/.cdm-server-ehcache
+eu.etaxonomy.taxeditor.test/src/test/resources/.cdmLibrary/remote-webapp
eu.etaxonomy.taxeditor.test/target
eu.etaxonomy.taxeditor/.settings
eu.etaxonomy.taxeditor/target
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/test/java"/>
+ <classpathentry kind="src" path="src/main/resources/"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
URL fileURL = bundle.getEntry(jar);
File file = null;
try {
- String urlString = FileLocator.resolve(fileURL).toExternalForm().replace(" ", "%20");;
+ String urlString = FileLocator.resolve(fileURL).toExternalForm().replace(" ", "%20");
file = new File(new URI(urlString));
JarFile jarFile = new JarFile(file);
Manifest manifest = jarFile.getManifest();
cache = new Cache(getEntityCacheConfiguration(cacheId));
+ CacheManager.create().removeCache(cache.getName());
CacheManager.create().addCache(cache);
this.cdmEntitySessionManager = cdmEntitySessionManager;
--- /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.remoting.server;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringEscapeUtils;
+
+import eu.etaxonomy.cdm.api.application.CdmApplicationUtils;
+import eu.etaxonomy.cdm.config.CdmPersistentXMLSource.CdmSourceProperties;
+import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
+
+/**
+ * @author cmathew
+ * @date 11 Nov 2015
+ *
+ */
+public class CDMServerUtils {
+
+
+ public static String convertEditorToServerConfig() {
+ StringBuilder configStringBuilder = new StringBuilder();
+ configStringBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?> " + System.lineSeparator());
+ configStringBuilder.append("<!-- DO NOT EDIT THIS FILE MANUALLY. -->");
+ configStringBuilder.append("<!-- It is created by the Taxonomic Editor for launching a managed CDM Server. -->");
+ configStringBuilder.append("<beans xmlns=\"http://www.springframework.org/schema/beans\"" + System.lineSeparator());
+ configStringBuilder.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + System.lineSeparator());
+ configStringBuilder.append(" xmlns:tx=\"http://www.springframework.org/schema/tx\"" + System.lineSeparator());
+ configStringBuilder.append(" xmlns:context=\"http://www.springframework.org/schema/context\"" + System.lineSeparator());
+ configStringBuilder.append(" xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" + System.lineSeparator());
+ configStringBuilder.append(" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" + System.lineSeparator());
+ configStringBuilder.append(" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" + System.lineSeparator());
+ configStringBuilder.append("\">" + System.lineSeparator());
+ configStringBuilder.append(" <bean id=\"dataSourceProperties\" class=\"eu.etaxonomy.cdm.remote.config.DataSourceProperties\">" + System.lineSeparator());
+ configStringBuilder.append(" <property name=\"propsMap\">" + System.lineSeparator());
+ configStringBuilder.append(" <map/>" + System.lineSeparator());
+ configStringBuilder.append(" </property>" + System.lineSeparator());
+ configStringBuilder.append(" </bean>" + System.lineSeparator());
+
+ for(CdmPersistentDataSource dataSource : CdmPersistentDataSource.getAllDataSources()) {
+ String beanId = dataSource.getName();
+ String user = dataSource.getUsername();
+ String password = dataSource.getPassword();
+ String driverClass = dataSource.getCdmSourceProperty(CdmSourceProperties.DRIVER_CLASS);
+ String jdbcUrl = StringEscapeUtils.escapeXml(dataSource.getCdmSourceProperty(CdmSourceProperties.URL));
+ configStringBuilder.append(" <bean id=\"" + beanId + "\" lazy-init=\"true\" class=\"com.mchange.v2.c3p0.ComboPooledDataSource\">" + System.lineSeparator());
+ configStringBuilder.append(" <property name=\"driverClass\" value=\"" + driverClass + "\"/>" + System.lineSeparator());
+ configStringBuilder.append(" <property name=\"user\" value=\"" + user + "\"/>" + System.lineSeparator());
+ configStringBuilder.append(" <property name=\"password\" value=\"" + password + "\"/>" + System.lineSeparator());
+ configStringBuilder.append(" <property name=\"jdbcUrl\" value=\"" + jdbcUrl + "\"/>" + System.lineSeparator());
+ configStringBuilder.append(" </bean>" + System.lineSeparator());
+
+ }
+ configStringBuilder.append("</beans>" + System.lineSeparator());
+
+ return configStringBuilder.toString();
+ }
+
+ public static File writeManagedServerConfig(String config, String fileName) throws IOException {
+ File managedConfigFile = new File(CdmApplicationUtils.getWritableResourceDir(), fileName);
+ if(managedConfigFile.exists()) {
+ managedConfigFile.delete();
+ }
+ if(managedConfigFile.createNewFile()) {
+ FileUtils.writeStringToFile(managedConfigFile, config);
+ }
+ return managedConfigFile;
+ }
+
+}
private final static int PORT_LOCALHOST_DEV = 8080;
private final static String BASEPATH_LOCALHOST_DEV = "";
+ public final static int NULL_PORT = -1;
+ public final static String NULL_PORT_STRING = "N/A";
+
+
private final String name;
private final String server;
- private final int port;
+ private int port;
private final List<CdmInstanceInfo> instances;
private static List<CdmServerInfo> cdmServerInfoList;
public CdmInstanceInfo addInstance(String name, String basePath) {
- CdmInstanceInfo cii = new CdmInstanceInfo(name, basePath);
+ String _basePath = basePath;
+ if(isLocalhostMgd()) {
+ _basePath = "";
+ }
+ CdmInstanceInfo cii = new CdmInstanceInfo(name, _basePath);
instances.add(cii);
return cii;
}
public void addInstancesFromDataSourcesConfig() {
-
for(ICdmDataSource dataSource : CdmPersistentDataSource.getAllDataSources()){
- logger.warn("Adding local instance " + dataSource.getName());
+ logger.info("Adding local instance " + dataSource.getName());
addInstance(dataSource.getName(), dataSource.getName());
}
-
}
public String toString(String instanceName, int port) {
}
public boolean pingServer() {
+ if(isLocalhostMgd()) {
+ return true;
+ }
try {
Socket s = new Socket(server, port);
logger.info("[CDM-Server] Available @ " + server + ":" + port );
cdmServerInfoList.add(new CdmServerInfo(NAME_DEMO_2, SERVER_DEMO_2, 80));
cdmServerInfoList.add(new CdmServerInfo(NAME_TEST, SERVER_TEST, 80));
cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST, SERVER_LOCALHOST, 8080));
- cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST_MGD, SERVER_LOCALHOST,8080));
+ cdmServerInfoList.add(new CdmServerInfo(NAME_LOCALHOST_MGD, SERVER_LOCALHOST,NULL_PORT));
}
return cdmServerInfoList;
}
return port;
}
+ public void setPort(int port) {
+ this.port = port;
+ }
public List<CdmInstanceInfo> getInstances() throws CDMServerException {
if(instances.isEmpty()) {
/**
* The full path of the instance including the the prefix (if any).
* E.g. for an EDIT instance this would be something like "cdmserver/remoting"
- * For a managed local server this would simply be "remoting"
+ * For a managed local server this would simply be ""
*/
private final String basePath;
org.eclipse.core.databinding.observable,
org.eclipse.core.databinding.property,
org.eclipse.jface.databinding
-Import-Package: org.eclipse.core.commands,
+Import-Package: eu.etaxonomy.taxeditor.webapp,
+ org.eclipse.core.commands,
org.eclipse.core.commands.operations,
org.eclipse.core.expressions,
org.eclipse.core.runtime,
import eu.etaxonomy.taxeditor.ui.dialog.RemotingLoginDialog;
import eu.etaxonomy.taxeditor.util.ProgressMonitorClientManager;
import eu.etaxonomy.taxeditor.view.datasource.CdmDataSourceViewPart;
+import eu.etaxonomy.taxeditor.webapp.CDMServer;
/**
* This implementation of ICdmDataRepository depends on hibernate sessions to
private static CdmStoreConnector job;
+ private static CDMServer managedServer;
+
private Language language;
private ICdmSource cdmSource;
return cdmSource;
}
+
+ public static void setManagedServer(CDMServer server) {
+ managedServer = server;
+ }
+
+ public static CDMServer getManagedServer() {
+ return managedServer;
+ }
+
}
*/
package eu.etaxonomy.taxeditor.ui.dialog;
+import java.io.File;
+import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.events.IExpansionListener;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.progress.IProgressConstants;
import org.eclipse.wb.swt.SWTResourceManager;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
+import eu.etaxonomy.taxeditor.remoting.server.CDMServerUtils;
import eu.etaxonomy.taxeditor.remoting.source.CdmRemoteSource;
import eu.etaxonomy.taxeditor.remoting.source.CdmServerInfo;
import eu.etaxonomy.taxeditor.remoting.source.CdmServerInfo.CdmInstanceInfo;
import eu.etaxonomy.taxeditor.remoting.source.ICdmRemoteSource;
import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
+import eu.etaxonomy.taxeditor.webapp.CDMEmbeddedServerException;
+import eu.etaxonomy.taxeditor.webapp.CDMServer;
+import eu.etaxonomy.taxeditor.webapp.ICDMServerError;
+
/**
* @author cmathew
* @date 20 Jan 2015
*
*/
-public class RemotingLoginDialog extends Dialog {
+public class RemotingLoginDialog extends Dialog implements ICDMServerError {
protected Object result;
protected Shell shlConnect;
private final static String STATUS_AVAILABLE = "Available";
private final static String STATUS_NOT_AVAILABLE = "Not Available";
+ private final static String STATUS_STARTED = "Started";
+ private final static String STATUS_NOT_STARTED = "Not Started";
private final static String STATUS_RETRIEVING = "Retrieving ...";
private final static String STATUS_CHECKING_AVAILABILITY = "Checking ...";
private final static String STATUS_NO_INSTANCES = "No Instances Found";
private final static String LAST_SERVER_KEY = "lastServerKey";
private final static String LAST_INSTANCE_KEY = "lastInstanceKey";
+ private final static String REFRESH_LABEL = "Refresh";
private Composite remotingComposite;
private CdmServerInfo selectedCsii;
private CdmInstanceInfo selectedCdmInstance;
private Button btnCdmServerRefresh;
+ private Button btnCdmInstanceRefresh;
+ private Button btnStopServer;
private Composite loginComposite;
private Label lblLogin;
private Text txtLogin;
private boolean autoConnect = false;
private boolean loadLoginPrefs = true;
private boolean isDevRemoteSource = false;
-
+ private Job serverJob;
/**
* Create the dialog.
* @param parent
* @return the result
*/
public Object open() {
- // ICdmRemoteSource devRemoteSource = CdmServerInfo.getDevServerRemoteSource();
- // if(devRemoteSource != null) {
- // connect(devRemoteSource);
- // } else {
+
createContents();
if(serverName == null && instanceName == null) {
readPrefLastServerInstance();
display.sleep();
}
}
- //}
+
return result;
}
comboCdmInstance.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- updateSelectedCdmInstance();
- checkSelectedCdmInstance();
+ refreshCdmInstance();
}
});
GridData gd_comboCdmInstance = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
gd_txtCdmInstanceStatus.widthHint = 100;
txtCdmInstanceStatus.setLayoutData(gd_txtCdmInstanceStatus);
- Button btnCdmInstanceRefresh = new Button(cdmServerComposite, SWT.FLAT);
+ btnCdmInstanceRefresh = new Button(cdmServerComposite, SWT.FLAT);
btnCdmInstanceRefresh.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
btnConnect.addMouseListener(new MouseAdapter() {
@Override
public void mouseUp(MouseEvent e) {
- connect();
+ if(selectedCsii.isLocalhostMgd() && !isSelectedCdmInstanceRunningInManagedServer()) {
+ startManagedServer();
+ } else {
+ connect();
+ }
}
});
btnConnect.setText("Connect");
txtServerVersion = new Text(compAdvanced, SWT.BORDER);
txtServerVersion.setEditable(false);
txtServerVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
- new Label(compAdvanced, SWT.NONE);
- new Label(compAdvanced, SWT.NONE);
+ btnStopServer = new Button(compAdvanced, SWT.FLAT);
+ btnStopServer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+ btnStopServer.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseUp(MouseEvent e) {
+ stopManagedServer();
+ }
+ });
+ btnStopServer.setText("Stop Managed Server");
lblEditorVersion = new Label(compAdvanced, SWT.CENTER);
lblEditorVersion.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
private void updatePort() {
txtPort.setText("");
if(selectedCsii != null) {
- txtPort.setText(String.valueOf(selectedCsii.getPort()));
+ int port = selectedCsii.getPort();
+ if(port == CdmServerInfo.NULL_PORT) {
+ txtPort.setText(CdmServerInfo.NULL_PORT_STRING);
+ } else {
+ txtPort.setText(String.valueOf(port));
+ }
}
}
private int getPort() {
- int port = 0;
+ int port = CdmServerInfo.NULL_PORT;
try {
port = Integer.valueOf(txtPort.getText());
} catch (NumberFormatException nfe) {
- setMessage("Port should be an integer");
+ if(!CdmServerInfo.NULL_PORT_STRING.equals(txtPort.getText())) {
+ setMessage("Port should be an integer");
+ }
}
return port;
}
if(selectedCsii.pingServer()) {
txtCdmServerStatus.setText(STATUS_AVAILABLE);
populateCdmInstanceCombo(true);
- txtServerVersion.setText(selectedCsii.getCdmlibServicesVersion());
- txtServerVersion.setToolTipText(generateLastModifiedTooltip(selectedCsii.getCdmlibLastModified()));
-
+ String serverVersionTimestamp = generateLastModifiedTooltip(selectedCsii.getCdmlibLastModified());
+ txtServerVersion.setText(selectedCsii.getCdmlibServicesVersion() + ":" + serverVersionTimestamp);
} else {
txtCdmServerStatus.setText(STATUS_NOT_AVAILABLE);
comboCdmInstance.removeAll();
txtCdmInstanceStatus.setText(STATUS_RETRIEVING);
txtCdmInstanceStatus.setToolTipText("");
- Job job = new Job("Retrieve Server Instances") {
+ serverJob = new Job("Retrieve Server Instances") {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
} else {
comboCdmInstance.select(instanceIndex);
}
- updateSelectedCdmInstance();
- checkSelectedCdmInstance();
+ refreshCdmInstance();
comboCdmInstance.setEnabled(true);
if(autoConnect) {
connect();
if(txtCdmServerStatus.getText().equals(STATUS_AVAILABLE) && !isDevRemoteSource) {
// Start the Job
- job.schedule();
+ serverJob.schedule();
}
+
}
private void refreshCdmInstance() {
clearOnInstanceChange();
updateSelectedCdmInstance();
checkSelectedCdmInstance();
+ updateManagedServerControls();
}
private void updateSelectedCdmInstance() {
int selIndex = comboCdmInstance.getSelectionIndex();
if(selIndex != -1) {
selectedCdmInstance = selectedCsii.getInstanceFromName(comboCdmInstance.getItem(selIndex));
+
if(loadLoginPrefs && !isDevRemoteSource) {
readPrefCredentials();
}
}
}
+ private void updateManagedServerControls() {
+ if(selectedCsii.isLocalhostMgd()) {
+ if(isSelectedCdmInstanceRunningInManagedServer()) {
+ txtCdmInstanceStatus.setText(STATUS_STARTED);
+ } else {
+ txtCdmInstanceStatus.setText(STATUS_NOT_STARTED);
+ }
+ btnConnect.setEnabled(true);
+ selectedCsii.setPort(getManagedServerPort());
+ updatePort();
+ }
+
+
+ if(isManagedServerRunning()) {
+ btnStopServer.setEnabled(true);
+ } else {
+ btnStopServer.setEnabled(false);
+ }
+ }
+
+ private boolean isManagedServerRunning() {
+ return CdmStore.getManagedServer() != null && CdmStore.getManagedServer().isAlive();
+ }
+
+ private boolean isSelectedCdmInstanceRunningInManagedServer() {
+ return CdmStore.getManagedServer() != null &&
+ CdmStore.getManagedServer().isAlive() &&
+ selectedCsii.isLocalhostMgd() &&
+ CdmStore.getManagedServer().getDataSourceName().equals(selectedCdmInstance.getName());
+ }
+
+ private boolean isActiveCdmInstanceRunningInManagedServer() {
+ return CdmStore.getManagedServer() != null &&
+ CdmStore.getManagedServer().isAlive() &&
+ CdmStore.isActive() &&
+ CdmServerInfo.NAME_LOCALHOST_MGD.equals(CdmStore.getActiveCdmSource().getName());
+ }
+
+
+ private void startManagedServer() {
+ if(isManagedServerRunning()) {
+ if(CdmStore.getManagedServer().getDataSourceName().equals(selectedCdmInstance.getName())) {
+ return;
+ } else {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ stopManagedServer();
+ }
+ });
+ }
+ }
+
+
+ Job job = new Job("Managed CDM Server Launch") {
+
+ @Override
+ public IStatus run(IProgressMonitor monitor) {
+ String mgdServerConfigFileName = "mgd.datasources.xml";
+ String config = CDMServerUtils.convertEditorToServerConfig();
+ File managedServerConfigFile;
+ int maxUnits = 50;
+ monitor.beginTask("Launching Managed CDM Server", maxUnits);
+ try {
+ monitor.subTask("Generating datasources config file for " + selectedCdmInstance.getName());
+ managedServerConfigFile = CDMServerUtils.writeManagedServerConfig(config, mgdServerConfigFileName);
+ monitor.worked(1);
+ CdmStore.setManagedServer(new CDMServer(selectedCdmInstance.getName(), managedServerConfigFile));
+ monitor.subTask("Starting Managed CDM Server. This may take a while.");
+ CdmStore.getManagedServer().start(false, RemotingLoginDialog.this);
+ int serverUnits = 0;
+
+ // the following loop is a 'fake' progress monitoring where the progress
+ // bar is advanced by one unit every second until maxUnits -2
+ while(!CdmStore.getManagedServer().isStarted()) {
+ if(serverUnits < maxUnits - 2) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ monitor.worked(1);
+ serverUnits++;
+ }
+ }
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ hide(false);
+ updateManagedServerControls();
+ connect();
+ }
+ });
+ } catch (IOException ioe) {
+ MessagingUtils.errorDialog("Error generating server config file",
+ this,
+ ioe.getMessage(),
+ TaxeditorStorePlugin.PLUGIN_ID,
+ ioe,
+ true);
+ } catch (CDMEmbeddedServerException cse) {
+ MessagingUtils.errorDialog("Error starting managed server",
+ this,
+ cse.getMessage(),
+ TaxeditorStorePlugin.PLUGIN_ID,
+ cse,
+ true);
+ } finally {
+ monitor.done();
+ }
+ return Status.OK_STATUS;
+ }
+ };
+
+ // configure the job
+ job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
+ job.setUser(true);
+ // schedule job
+ hide(true);
+ job.schedule();
+ }
+
+ private void stopManagedServer() {
+ try {
+ CdmStore.getManagedServer().stop();
+ } catch (Exception e) {
+ MessagingUtils.errorDialog("Error stopping managed server",
+ this,
+ "Could not stop managed server running at port " + CdmStore.getManagedServer().getPort() + ". Please stop it manually",
+ TaxeditorStorePlugin.PLUGIN_ID,
+ e,
+ true);
+ }
+ CdmStore.setManagedServer(null);
+ updateManagedServerControls();
+ }
+
+ private int getManagedServerPort() {
+ return CdmStore.getManagedServer() == null ? CdmServerInfo.NULL_PORT : CdmStore.getManagedServer().getPort();
+ }
+
private void checkSelectedCdmInstance() {
boolean available = false;
String status = STATUS_NOT_AVAILABLE;
setMessage(message);
}
}
-
}
-
}
private void connect() {
}
private String generateLastModifiedTooltip(String cdmlibLastModified) {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd 'at' HH:mm:ss z");
+ if(StringUtils.isBlank(cdmlibLastModified)) {
+ return "";
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.z");
Date cdmlibLastModifiedDate;
String cdmlibLastModifiedTimestamp = "";
cdmlibLastModifiedDate = new Date(Long.valueOf(cdmlibLastModified));
cdmlibLastModifiedTimestamp = sdf.format(cdmlibLastModifiedDate);
- return "last modified : " + cdmlibLastModifiedTimestamp;
+ return cdmlibLastModifiedTimestamp;
}
private void setEditorInfo() {
txtEditorCDMVersion.setText(CdmMetaData.getDbSchemaVersion());
- txtEditorVersion.setText(CdmApplicationState.getCdmlibVersion());
- txtEditorVersion.setToolTipText(generateLastModifiedTooltip(CdmApplicationState.getCdmlibLastModified()));
+ String editorVersionTimestamp = generateLastModifiedTooltip(CdmApplicationState.getCdmlibLastModified());
+ txtEditorVersion.setText(CdmApplicationState.getCdmlibVersion() + ":" + editorVersionTimestamp);
}
private void clearOnServerChange() {
txtServerCDMVersion.setText("");
}
- private void updateOnServerChange(String serverVersion, String serverVersionTooltip) {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleError(final Throwable t) {
+
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ serverJob.cancel();
+ String title = "CDM Server launch error";
+ String message = t.getMessage();
+
+
+ MessagingUtils.errorDialog(title,
+ this,
+ message,
+ TaxeditorStorePlugin.PLUGIN_ID,
+ t,
+ true);
+ }
+ });
}
+
}
org.apache.log4j,
org.hamcrest,
org.eclipse.swtbot.eclipse.core,
- org.eclipse.swtbot.eclipse.finder
+ org.eclipse.swtbot.eclipse.finder,
+ eu.etaxonomy.taxeditor.webapp;bundle-version="3.12.0"
Eclipse-RegisterBuddy: org.apache.log4j, org.eclipse.swtbot.swt.finder
Bundle-ClassPath: .,
lib/byte-buddy-0.5.1.jar,
*/
package eu.etaxonomy.taxeditor.httpinvoker;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
import java.lang.reflect.Field;
-import java.net.URL;
import java.util.Map;
-import java.util.Properties;
import net.sf.ehcache.CacheManager;
import org.apache.log4j.Logger;
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Platform;
import org.junit.Assert;
import org.junit.BeforeClass;
-import org.osgi.framework.Bundle;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public abstract class BaseRemotingTest extends ThreadedTest {
private static final Logger logger = Logger.getLogger(BaseRemotingTest.class);
-
- public static final Resource SERVER_PROPERTIES_FILE =
- new ClassPathResource("server.properties");
-
private static ICdmRemoteSource cdmRemoteSource;
private static CdmPersistentRemoteSource remotePersistentSource;
-
- public static boolean useManagedServer = true;
-
-
protected static ICdmEntitySessionManager cdmEntitySessionManager;
- private final static String DEFAULT_USER = "admin";
- private final static String DEFAULT_PASSWORD = "00000";
-
- private static String userHomeKey = "user.home";
-
- private static String user = DEFAULT_USER;
- private static String password = DEFAULT_PASSWORD;
-
-
- protected static CDMServer cdmServer;
-
@BeforeClass
public static void initializeBaseRemotingTest() {
DatabaseUnitils.disableConstraints();
try {
- String userHomeDirPath;
- Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.test");
-
- URL userHomeDirURL = bundle.getEntry("src/test/resources");
- File userHomeDir = new File(FileLocator.resolve(userHomeDirURL).toURI());
- userHomeDirPath = userHomeDir.getAbsolutePath();
-
- URL serverPropertiesURL = bundle.getEntry("src/test/resources/server.properties");
- File serverPropertiesFile = new File(FileLocator.resolve(serverPropertiesURL).toURI());
- InputStream inputStream = new FileInputStream(serverPropertiesFile);
-
- Properties prop = new Properties();
- if (inputStream != null) {
- prop.load(inputStream);
- inputStream.close();
- }
-
- logger.info("Setting user.home to " + userHomeDirPath);
- System.setProperty(userHomeKey, userHomeDirPath);
-
-
- cdmServer = new CDMServer("cdmTest", serverPropertiesURL);
-
-
- if(prop.getProperty("user") != null) {
- user = prop.getProperty("user");
- }
-
- if(prop.getProperty("password") != null) {
- password = prop.getProperty("password");
- }
-
- initializeController(cdmServer.getName(),
- cdmServer.getHost(),
- cdmServer.getPort(),
- cdmServer.getContextPath(),
+ initializeController(sourceName,
+ host,
+ httpPort,
+ contextPath,
NomenclaturalCode.ICNAFP,
user,
password);
+++ /dev/null
-// $Id$
-/**
- * Copyright (C) 2014 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.httpinvoker;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.Properties;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.sql.DataSource;
-
-import org.apache.log4j.Logger;
-import org.eclipse.core.runtime.FileLocator;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-import org.unitils.database.annotations.TestDataSource;
-
-import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
-import eu.etaxonomy.cdm.database.ICdmDataSource;
-import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
-import eu.etaxonomy.taxeditor.remoting.source.CdmRemoteSourceBase;
-
-/**
- *
- * (Singleton) Server instance which manages a compatible cdmlib-webapp-war.
- * This is done by launching a jetty instance (using jetty-runner) as an
- * executed process. The choice of the external process over a more
- * preferable 'embedded jetty' instance is due to problems arising from the
- * class loading of classes (e.g. from hibernate core) which are needed
- * for both the webapp as well as the remoting client.
- *
- * @author cmathew
- * @date 23 Sep 2014
- *
- */
-
-public class CDMServer {
-
- public static final Logger logger = Logger.getLogger(CDMServer.class);
-
- @TestDataSource
- protected DataSource dataSource;
-
- private final String name = "default";
- private final String host = "127.0.0.1";
- private int httpPort = 9090;
- private int stopPort = 9191;
- private String stopKey = "jetty-cdm-server";
- private final String contextPath = "";
-
- public static final Resource DEFAULT_CDM_WEBAPP_RESOURCE =
- new ClassPathResource("/etc/jetty/cdmlib-remote-webapp.war");
-
- public static final Resource DEFAULT_DATASOURCE_FILE =
- new ClassPathResource("datasources.xml");
-
- public static final Resource DEFAULT_JETTY_RUNNER_RESOURCE =
- new ClassPathResource("/etc/jetty/jetty-runner-9.2.3.v20140905.jar");
-
- public static final Resource DEFAULT_JETTY_RESOURCE =
- new ClassPathResource("/etc/jetty/start-9.2.3.v20140905.jar");
-
- private static CDMServer cdmServer = null;
- private static CDMServerException cdmse = null;
-
- private boolean serverAlreadyRunning = false;
-
- private File dataSourcesFile;
- private final String dataSourceName;
-
- public CDMServer(String dataSourceName, URL serverPropertiesURL) throws CDMServerException {
- this.dataSourceName = dataSourceName;
- Properties prop = new Properties();
-
- try {
- File serverPropertiesFile = new File(FileLocator.resolve(serverPropertiesURL).toURI());
- InputStream inputStream = new FileInputStream(serverPropertiesFile);
-
- prop.load(inputStream);
- inputStream.close();
-
- } catch (FileNotFoundException e) {
- throw new CDMServerException(e);
- } catch (URISyntaxException e) {
- throw new CDMServerException(e);
- } catch (IOException e) {
- throw new CDMServerException(e);
- }
-
-
-
- if(prop.getProperty("httpPort") != null) {
- setHttpPort(Integer.valueOf(prop.getProperty("httpPort")));
- }
-
- if(prop.getProperty("stopPort") != null) {
- setStopPort(Integer.valueOf(prop.getProperty("stopPort")));
- }
-
- if(prop.getProperty("stopKey") != null) {
- setStopKey(prop.getProperty("stopKey"));
- }
-
- }
-
-
-
- public String getName() {
- return name;
- }
-
- public String getHost() {
- return host;
- }
-
- public int getPort() {
- return httpPort;
- }
-
- public String getContextPath() {
- return contextPath;
- }
-
- public void setHttpPort(int port) {
- this.httpPort = port;
- }
-
- public void setStopPort(int stopPort) {
- this.stopPort = stopPort;
- }
-
- public void setStopKey(String stopKey) {
- this.stopKey = stopKey;
- }
-
-
- public static boolean isRunningInEclipse() {
- return (System.getProperty("sun.java.command") != null &&
- System.getProperty("sun.java.command").startsWith("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner"));
- }
-
- private String getVMArgs() throws IOException {
- StringBuilder sb = new StringBuilder();
- sb.append(" -Dspring.profiles.active=remoting");
- sb.append(" -Dcdm.beanDefinitionFile=" + DEFAULT_DATASOURCE_FILE.getFile().getAbsolutePath());
- sb.append(" -Dcdm.datasource=cdmTest");
- return sb.toString();
- }
-
- private String getStartServerArgs() throws IOException {
- StringBuilder sb = new StringBuilder();
- sb.append(" --port " + httpPort);
- return sb.toString();
- }
-
- private String getStopServerSettings() {
- StringBuilder sb = new StringBuilder();
- sb.append(" --stop-port ");
- sb.append(stopPort);
- sb.append(" --stop-key ");
- sb.append(stopKey);
- return sb.toString();
- }
-
- private String getStopServerArgs() {
- StringBuilder sb = new StringBuilder();
- sb.append(" STOP.PORT=");
- sb.append(stopPort);
- sb.append(" STOP.KEY=");
- sb.append(stopKey);
- return sb.toString();
- }
-
-
- public void start() throws CDMServerException {
-
- /**
- * First check if the CDM server responds to a service request, which implies that
- * the server has started properly. If no response is received then check if the
- * server is listening on specific host / port, which implies that the server
- * has started but incorrectly, in which case we try to force stop it (if we can)
- * and start a new server.
- */
- if(isStarted(1)) {
- logger.info("[CDM-Server] Server already running @ " + host + ":" + httpPort );
- serverAlreadyRunning = true;
- return;
- }
-
- Thread t = new Thread() {
- @Override
- public void run() {
-
- StringBuffer output = new StringBuffer();
- try{
- Process p;
- String command = "java "
- + getVMArgs()
- + " -jar "
- + DEFAULT_JETTY_RUNNER_RESOURCE.getFile().getAbsolutePath()
- + getStartServerArgs()
- + getStopServerSettings()
- + " "
- + DEFAULT_CDM_WEBAPP_RESOURCE.getFile().getAbsolutePath();
- logger.info("[CDM-Server] Starting server with Command : " + command);
- p = Runtime.getRuntime().exec(command);
-
- BufferedReader inpReader =
- new BufferedReader(new InputStreamReader(p.getInputStream()));
-
- BufferedReader errReader =
- new BufferedReader(new InputStreamReader(p.getErrorStream()));
-
- String line = "";
- while ((line = inpReader.readLine())!= null) {
- logger.info("[CDM-Server Start] : " + line);
- }
-
- while ((line = errReader.readLine())!= null) {
- logger.info("[CDM-Server Start] : " + line);
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- cdmse = new CDMServerException(e);
- }
- }
- };
-
- t.setDaemon(true);
- cdmse = null;
- t.start();
-
- if(isStarted(50)) {
- logger.info("[CDM-Server] Server running @ " + host + ":" + httpPort );
- } else {
- logger.info("[CDM-Server] Server not started within given interval");
- // making sure to kill server if it is not started correctly
- try {
- stop(true);
- } catch (Exception e) {
- throw new CDMServerException("CDM Server could not be stopped : " + e.getMessage());
- }
- throw new CDMServerException("CDM Server not started : ");
- }
-
- }
-
-
- public boolean isStarted(int checkingIntervals) throws CDMServerException {
- CdmRemoteSourceBase crsb = new CdmRemoteSourceBase("local-cdm-server",
- host,
- httpPort,
- contextPath,
- null);
- int intervalsCount = 0;
- do {
- try {
- if(cdmse != null) {
- return false;
- }
- boolean check = crsb.checkConnection();
- if(check) {
- logger.info("[CDM-Server] Running @ " + host + ":" + httpPort );
- return true;
- }
- } catch (Exception e) {
-
- }
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ie) {
- throw new CDMServerException("Error checking CDM Server status", ie);
- }
- intervalsCount++;
- } while (intervalsCount < checkingIntervals);
- return false;
- }
-
- public void stop() throws Exception {
- stop(false);
- }
-
- public void stop(boolean force) throws Exception {
-
- if(!force) {
- if(!cdmServer.isStarted(1)) {
- logger.info("[CDM-Server] Server already stopped @ " + host + ":" + httpPort );
- return;
- }
- }
-
- if(serverAlreadyRunning) {
- return;
- }
- Thread t = new Thread() {
- @Override
- public void run() {
- StringBuffer output = new StringBuffer();
- try{
- Process p;
- String command = "java -jar " + DEFAULT_JETTY_RESOURCE.getFile().getAbsolutePath()
- + getStopServerArgs() + " --stop ";
- logger.info("[CDM-Server] Stop Command : " + command);
- p = Runtime.getRuntime().exec(command);
-
- BufferedReader inpReader =
- new BufferedReader(new InputStreamReader(p.getInputStream()));
-
- BufferedReader errReader =
- new BufferedReader(new InputStreamReader(p.getErrorStream()));
-
- String line = "";
- while ((line = inpReader.readLine())!= null) {
- logger.info("[CDM-Server Stop] : " + line);
- }
-
- while ((line = errReader.readLine())!= null) {
- logger.info("[CDM-Server Stop] : " + line);
- }
- logger.info("CDM-Server Stopped : ");
- } catch (Exception e) {
- logger.info("[CDM-Server] Could not stop @ " + host + ":" + httpPort + ". Please kill it manually");
-
- }
-
- }
- };
-
- t.setDaemon(true);
- t.start();
-
- }
-
- public static void stopServerViaJMX(int jmxPort) throws CDMServerException {
- String JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:" + jmxPort + "/jmxrmi";
- logger.warn("Shutting down Jetty instance ... ");
-
- try {
- JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), null);
- connector.connect(null);
- MBeanServerConnection connection = connector.getMBeanServerConnection();
- ObjectName objectName = new ObjectName("org.eclipse.jetty.server:type=server,id=0");
- connection.invoke(objectName, "stop", null, null);
- logger.warn("Shutdown command sent");
- } catch (InstanceNotFoundException e) {
- throw new CDMServerException(e);
- } catch (MBeanException e) {
- throw new CDMServerException(e);
- } catch (ReflectionException e) {
- throw new CDMServerException(e);
- } catch (IOException e) {
- throw new CDMServerException(e);
- } catch (MalformedObjectNameException e) {
- throw new CDMServerException(e);
- }
- }
-
- public void convertEditorToServerConfig() {
- String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " + System.lineSeparator() +
- "<beans xmlns=\"http://www.springframework.org/schema/beans\"" + System.lineSeparator() +
- "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + System.lineSeparator() +
- "xmlns:tx=\"http://www.springframework.org/schema/tx\"" + System.lineSeparator() +
- "xmlns:context=\"http://www.springframework.org/schema/context\"" + System.lineSeparator() +
- "xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" + System.lineSeparator() +
- "http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" + System.lineSeparator() +
- "http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" + System.lineSeparator() +
- ">" + System.lineSeparator() +
- "<bean id=\"dataSourceProperties\" class=\"eu.etaxonomy.cdm.remote.config.DataSourceProperties\">" + System.lineSeparator() +
- " <property name=\"propsMap\">" + System.lineSeparator() +
- " <map/>" + System.lineSeparator() +
- " </property>" + System.lineSeparator() +
- "</bean>";
-
- for(ICdmDataSource dataSource : CdmPersistentDataSource.getAllDataSources()) {
-
- }
- }
-}
public void whenConnectingToInactiveServerThenFailToConnect() {
// check if non-active server throws the right exception
- CdmRemoteSource inactiveCrs = CdmRemoteSource.NewInstance(cdmServer.getName(),
- cdmServer.getHost(),
+ CdmRemoteSource inactiveCrs = CdmRemoteSource.NewInstance(sourceName,
+ host,
808080,
- cdmServer.getContextPath(),
+ contextPath,
NomenclaturalCode.ICNAFP);
try {
inactiveCrs.getDbSchemaVersion();
@Test
public void whenConnectingToAnActiveServerThenConnectSuccessfully() {
// check if active server throws the right exception
- CdmRemoteSource activeCrs = CdmRemoteSource.NewInstance(cdmServer.getName(),
- cdmServer.getHost(),
- cdmServer.getPort(),
- cdmServer.getContextPath(),
+ CdmRemoteSource activeCrs = CdmRemoteSource.NewInstance(sourceName,
+ host,
+ httpPort,
+ contextPath,
NomenclaturalCode.ICNAFP);
String dbSchemaVersion = "";
try {
*/
package eu.etaxonomy.taxeditor.httpinvoker;
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
import java.net.URL;
import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
import org.osgi.framework.Bundle;
-import org.unitils.UnitilsJUnit4;
-import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
+import eu.etaxonomy.taxeditor.remoting.server.CDMServerUtils;
+import eu.etaxonomy.taxeditor.webapp.CDMEmbeddedServerException;
+import eu.etaxonomy.taxeditor.webapp.CDMServer;
+import eu.etaxonomy.taxeditor.webapp.ICDMServerError;
+
/**
* @author cmathew
* @date 6 Oct 2014
*
*/
-public class CdmServerTest extends UnitilsJUnit4 {
+public class CdmServerTest extends TestConfig {
private static final Logger logger = Logger.getLogger(CdmServerTest.class);
- @Ignore // this should be targetting integration or production
+
+
@Test
- public void startCdmServer() throws CDMServerException {
+ public void generateConfigFile() throws IOException {
+ String mgdServerConfigFileName = "test.mgd.datasources.xml";
+ String config = CDMServerUtils.convertEditorToServerConfig();
+ CDMServerUtils.writeManagedServerConfig(config, mgdServerConfigFileName);
+ }
+
+ @Test
+ public void manageCdmServer() throws IOException, URISyntaxException, CDMEmbeddedServerException {
Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.test");
- URL serverPropertiesURL = bundle.getEntry("src/test/resources/server.properties");
- CDMServer cdmServer = new CDMServer("cdmTest", serverPropertiesURL);
- cdmServer .start();
+ URL mgdDatasourcesConfigURL = bundle.getEntry("src/test/resources/.cdmLibrary/writableResources/mgd.datasources.xml");
+ File mgdDatasourcesConfigFile = new File(FileLocator.resolve(mgdDatasourcesConfigURL).toURI());
+ CDMServer cdmServer = new CDMServer("cdmTest", mgdDatasourcesConfigFile);
+ cdmServer.start(new ICDMServerError() {
+ @Override
+ public void handleError(Throwable t) {
+ Assert.fail("Error starting server. Reason : " + t.getMessage());
+ }
+ });
try {
- cdmServer.stop(true);
+ cdmServer.stop();
} catch (Exception e) {
e.printStackTrace();
- Assert.fail("Server could not be stopped. Reason : " + e.getMessage());
+ Assert.fail("Error stopping server. Reason : " + e.getMessage());
}
}
-
}
--- /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.httpinvoker;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.junit.BeforeClass;
+import org.osgi.framework.Bundle;
+import org.unitils.UnitilsJUnit4;
+
+/**
+ * @author cmathew
+ * @date 11 Nov 2015
+ *
+ */
+public class TestConfig extends UnitilsJUnit4 {
+
+ private static final Logger logger = Logger.getLogger(TestConfig.class);
+
+ private final static String DEFAULT_USER = "admin";
+ private final static String DEFAULT_PASSWORD = "00000";
+ private final static int DEFAULT_HTTP_PORT = 9090;
+ private final static String DEFAULT_CONTEXT_PATH = "";
+ private final static String DEFAULT_SOURCE_NAME = "default";
+ private final static String DEFAULT_HOST = "localhost";
+
+ private static String userHomeKey = "user.home";
+
+ protected static String user = DEFAULT_USER;
+ protected static String password = DEFAULT_PASSWORD;
+ protected static int httpPort = DEFAULT_HTTP_PORT;
+ protected static String contextPath = DEFAULT_CONTEXT_PATH;
+ protected static String sourceName = DEFAULT_SOURCE_NAME;
+ protected static String host = DEFAULT_HOST;
+
+ @BeforeClass
+ public static void initializeTestConfig() {
+ try {
+ String userHomeDirPath;
+ Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.test");
+
+ URL userHomeDirURL = bundle.getEntry("src/test/resources");
+ File userHomeDir = new File(FileLocator.resolve(userHomeDirURL).toURI());
+ userHomeDirPath = userHomeDir.getAbsolutePath();
+
+ URL serverPropertiesURL = bundle.getEntry("src/test/resources/server.properties");
+ File serverPropertiesFile = new File(FileLocator.resolve(serverPropertiesURL).toURI());
+ InputStream inputStream = new FileInputStream(serverPropertiesFile);
+
+ Properties prop = new Properties();
+
+ prop.load(inputStream);
+ inputStream.close();
+
+
+ logger.warn("Setting user.home to " + userHomeDirPath);
+ System.setProperty(userHomeKey, userHomeDirPath);
+
+
+ if(prop.getProperty("user") != null) {
+ user = prop.getProperty("user");
+ }
+
+ if(prop.getProperty("password") != null) {
+ password = prop.getProperty("password");
+ }
+
+ if(prop.getProperty("httpPort") != null) {
+ httpPort = Integer.valueOf(prop.getProperty("httpPort"));
+ }
+
+ if(prop.getProperty("contextPath") != null) {
+ contextPath = prop.getProperty("contextPath");
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ // Assert.fail("Server failed to start. Reason : " + e.getMessage());
+ }
+ }
+
+}
import java.util.Set;
import org.junit.After;
-import org.unitils.UnitilsJUnit4;
/**
* @author cmathew
* @date 16 Oct 2015
*
*/
-public abstract class ThreadedTest extends UnitilsJUnit4 {
+public abstract class ThreadedTest extends TestConfig {
private Set<TestThread> threadPool = new HashSet<TestThread>();
<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
- <bean id="defaultRemoteSource">
- <property name="server" value="127.0.0.1" />
- <property name="port" value="9090" />
- <property name="contextPath" value="" />
- </bean>
- <bean id="incompleteRemoteSource">
- <property name="port" value="9090" />
- <property name="contextPath" value="" />
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">ls
+ <bean id="cdmTestDataSource" class="eu.etaxonomy.cdm.database.LocalH2" lazy-init="true">
+ <property name="driverClassName" value="org.h2.Driver" />
+ <property name="url" value="jdbc:h2:file:./target/classes/h2/cdmTest;AUTO_SERVER=TRUE" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ <property name="mode" value="embedded" />
+ <property name="nomenclaturalCode" value="ICNAFP" />
</bean>
</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
+">
+ <bean id="dataSourceProperties" class="eu.etaxonomy.cdm.remote.config.DataSourceProperties">
+ <property name="propsMap">
+ <map/>
+ </property>
+ </bean>
+ <bean id="cdmTest" lazy-init="true" class="com.mchange.v2.c3p0.ComboPooledDataSource">
+ <property name="driverClass" value="org.h2.Driver"/>
+ <property name="user" value="sa"/>
+ <property name="password" value=""/>
+ <property name="jdbcUrl" value="jdbc:h2:file:./target/classes/h2/cdmTest;AUTO_SERVER=TRUE"/>
+ </bean>
+</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- DO NOT EDIT THIS FILE MANUALLY. --><!-- It is created by the Taxonomic Editor for launching a managed CDM Server. --><beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
+">
+ <bean id="dataSourceProperties" class="eu.etaxonomy.cdm.remote.config.DataSourceProperties">
+ <property name="propsMap">
+ <map/>
+ </property>
+ </bean>
+ <bean id="cdmTest" lazy-init="true" class="com.mchange.v2.c3p0.ComboPooledDataSource">
+ <property name="driverClass" value="org.h2.Driver"/>
+ <property name="user" value="sa"/>
+ <property name="password" value=""/>
+ <property name="jdbcUrl" value="jdbc:h2:file:/exthd1/home/Development/EDIT/taxeditor/eu.etaxonomy.taxeditor.test/src/test/resources/.cdmLibrary/writableResources/h2/LocalH2/cdmTest;AUTO_SERVER=TRUE"/>
+ </bean>
+</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
- <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
- <param name="Target" value="System.out"/>
- <layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %p [%c] - %m%n"/>
- </layout>
- <filter class="org.apache.log4j.filter.ExpressionFilter">
- <param name="expression" value="msg like '.*has a maxElementsInMemory of 0. This might lead to performance degradation or OutOfMemoryError at Terracotta client.*'" />
- <param name="acceptOnMatch" value="false"/>
- </filter>
- </appender>
- <root>
- <priority value ="WARN" />
- <appender-ref ref="CONSOLE"/>
- </root>
- <logger name="org.hibernate.proxy.AbstractLazyInitializer">
- <level value="info"/>
- </logger>
- <logger name="org.hibernate.collection.internal.AbstractPersistentCollection">
- <level value="info"/>
- </logger>
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
+ debug="false">
+ <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+ <param name="Target" value="System.out" />
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %p [%c] - %m%n" />
+ </layout>
+ </appender>
+ <root>
+ <priority value="WARN" />
+ <appender-ref ref="CONSOLE" />
+ </root>
</log4j:configuration>
\ No newline at end of file
stopKey=jetty-cdm-server
user=admin
password=00000
+contextPath=
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry exported="true" kind="lib" path="lib/mysql-connector-java-5.1.24.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/javax.servlet-api-3.1.0.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jetty-all-9.2.9.v20150224.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/log4j-1.2.17.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/main/resources"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>eu.etaxonomy.taxeditor.webapp</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Webapp
+Bundle-SymbolicName: eu.etaxonomy.taxeditor.webapp;singleton:=true
+Bundle-Version: 3.12.0.qualifier
+Require-Bundle: org.eclipse.core.runtime
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
+Export-Package: eu.etaxonomy.taxeditor.webapp
+Bundle-ClassPath: .,
+ lib/log4j-1.2.17.jar,
+ lib/jetty-all-9.2.9.v20150224.jar,
+ lib/javax.servlet-api-3.1.0.jar,
+ lib/mysql-connector-java-5.1.24.jar
+Bundle-Vendor: EDIT
+Import-Package: org.eclipse.jface.resource,
+ org.eclipse.ui.plugin
+Bundle-Activator: eu.etaxonomy.taxeditor.webapp.TaxeditorWebappPlugin
--- /dev/null
+source.. = src/main/java/,\
+ src/main/resources/
+bin.includes = META-INF/,\
+ .,\
+ lib/log4j-1.2.17.jar,\
+ lib/jetty-all-9.2.9.v20150224.jar,\
+ lib/javax.servlet-api-3.1.0.jar,\
+ lib/mysql-connector-java-5.1.24.jar,\
+ lib/cdmlib-remote-webapp.war
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>eu.etaxonomy</groupId>
+ <artifactId>taxeditor-parent</artifactId>
+ <version>3.12.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>eu.etaxonomy.taxeditor.webapp</artifactId>
+ <packaging>eclipse-plugin</packaging>
+ <name>CDM Library Webapp Plugin</name>
+ <description>CDM Library webapp as a plugin</description>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.7</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <id>copy-dependency-war</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <includeArtifactIds>
+ cdmlib-remote-webapp
+ </includeArtifactIds>
+ <outputDirectory>
+ ${basedir}/lib
+ </outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <excludeTransitive>true</excludeTransitive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.7</version>
+ <executions>
+ <execution>
+ <id>update-snapshot-jar-names</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <echo>Anonymizing war</echo>
+ <move todir="./lib">
+ <fileset dir="./lib" />
+ <mapper type="regexp"
+ from="(^cdmlib\-remote\-webapp).*(\.war)" to="\1\2" />
+ </move>
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <repositories>
+ <repository>
+ <id>SpringSource Enterprise Bundle Repository - External Bundle
+ Milestones
+ </id>
+ <url>http://repository.springsource.com/maven/bundles/milestone
+ </url>
+ </repository>
+ <repository>
+ <id>SpringSource Enterprise Bundle Repository - SpringSource
+ Bundle
+ Releases
+ </id>
+ <url>http://repository.springsource.com/maven/bundles/release
+ </url>
+ </repository>
+ <repository>
+ <id>SpringSource Enterprise Bundle Repository - External Bundle
+ Releases
+ </id>
+ <url>http://repository.springsource.com/maven/bundles/external
+ </url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>eu.etaxonomy</groupId>
+ <artifactId>cdmlib-remote-webapp</artifactId>
+ <version>${cdmlib.version}</version>
+ <type>war</type>
+ </dependency>
+ </dependencies>
+</project>
+
--- /dev/null
+// $Id$
+/**
+* Copyright (C) 2014 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.webapp;
+
+/**
+ * @author cmathew
+ * @date 23 Sep 2014
+ *
+ */
+public class CDMEmbeddedServerException extends Exception {
+
+ public CDMEmbeddedServerException(String message) {
+ super(message);
+ }
+
+ public CDMEmbeddedServerException(Exception e) {
+ super(e);
+ }
+
+ public CDMEmbeddedServerException(String message,Exception e) {
+ super(message,e);
+ }
+
+}
--- /dev/null
+// $Id$
+/**
+ * Copyright (C) 2014 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.webapp;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServerConnection;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.preventers.AppContextLeakPreventer;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.osgi.framework.Bundle;
+
+/**
+ *
+ * (Singleton) Server instance which manages a compatible cdmlib-webapp-war.
+ * This is done by launching a jetty instance (using jetty-runner) as an
+ * executed process. The choice of the external process over a more
+ * preferable 'embedded jetty' instance is due to problems arising from the
+ * class loading of classes (e.g. from hibernate core) which are needed
+ * for both the webapp as well as the remoting client.
+ *
+ * @author cmathew
+ * @date 23 Sep 2014
+ *
+ */
+
+public class CDMServer {
+
+ public static final Logger logger = Logger.getLogger(CDMServer.class);
+
+
+ private final String dataSourceName;
+ private final String host = "127.0.0.1";
+ private int httpPort = 9090;
+ private final String contextPath = "/";
+
+ private File warFile;
+ private Server server;
+
+
+ public CDMServer(String dataSourceName, File dataSourcesFile) throws CDMEmbeddedServerException {
+ if(StringUtil.isBlank(dataSourceName)) {
+ throw new CDMEmbeddedServerException("DataSource name is not valid");
+ }
+
+ if(dataSourcesFile == null || !dataSourcesFile.exists()) {
+ throw new CDMEmbeddedServerException("DataSource config file does not exist");
+ }
+ this.dataSourceName = dataSourceName;
+ Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.webapp");
+ URL warURL = bundle.getEntry("lib/cdmlib-remote-webapp.war");
+
+ try {
+ URL resolvedWarURL = FileLocator.toFileURL(warURL);
+ // We need to use the 3-arg constructor of URI in order to properly escape file system chars
+ URI resolvedURI = new URI(resolvedWarURL.getProtocol(), resolvedWarURL.getPath(), null);
+ warFile = new File(resolvedURI);
+ System.out.println("war url : " + warFile.getAbsolutePath());
+
+ if(warFile == null || !warFile.exists()) {
+ throw new CDMEmbeddedServerException("Cdmlib War file does not exist");
+ }
+ } catch (URISyntaxException use) {
+ throw new CDMEmbeddedServerException(use);
+ } catch (IOException ioe) {
+ throw new CDMEmbeddedServerException(ioe);
+ }
+
+ System.setProperty("spring.profiles.active", "remoting");
+ System.setProperty("cdm.beanDefinitionFile", dataSourcesFile.getAbsolutePath());
+ System.setProperty("cdm.datasource", dataSourceName);
+
+ httpPort = findFreePort();
+
+ logger.warn("Starting server on port : " + httpPort);
+
+ server = new Server(httpPort);
+
+ server.addBean(new AppContextLeakPreventer());
+
+ WebAppContext webapp = new WebAppContext();
+ webapp.setContextPath(contextPath);
+ webapp.setWar(warFile.getAbsolutePath());
+
+ server.setHandler(webapp);
+ }
+
+ public String getDataSourceName() {
+ return dataSourceName;
+ }
+ public String getHost() {
+ return host;
+ }
+
+ public int getPort() {
+ return httpPort;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ private static int findFreePort() throws CDMEmbeddedServerException {
+ ServerSocket socket = null;
+ try {
+ socket = new ServerSocket(0);
+ socket.setReuseAddress(true);
+ int port = socket.getLocalPort();
+ try {
+ socket.close();
+ } catch (IOException e) {
+
+ }
+ return port;
+ } catch (IOException e) {
+ } finally {
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ throw new CDMEmbeddedServerException("Could not find a free TCP/IP port to start embedded Jetty HTTP Server on");
+ }
+
+ public void start(ICDMServerError cdmServerError) throws CDMEmbeddedServerException {
+ start(true, cdmServerError);
+ }
+
+ public void start(boolean wait, final ICDMServerError cdmServerError) throws CDMEmbeddedServerException {
+
+ if(server == null) {
+ throw new CDMEmbeddedServerException("Server is already disposed");
+ }
+
+ if(server.isStarting()) {
+ throw new CDMEmbeddedServerException("Server is starting");
+ }
+
+ if(server.isStarted()) {
+ throw new CDMEmbeddedServerException("Server has started");
+ }
+
+ if(server.isRunning()) {
+ throw new CDMEmbeddedServerException("Server is running");
+ }
+
+ if(server.isStopping()) {
+ throw new CDMEmbeddedServerException("Server is currently stopping. Please re-try in about 10 seconds");
+ }
+
+ Thread serverThread = new Thread() {
+
+ @Override
+ public void run() {
+ try {
+ server.start();
+ server.join();
+ } catch (Throwable t) {
+ cdmServerError.handleError(t);
+ }
+ }
+ };
+
+ serverThread.start();
+
+ if(wait) {
+ while(!server.isStarted()) {}
+
+ }
+ }
+
+ public boolean isAlive() {
+ return server.isRunning() || server.isStarting() || server.isStarted();
+ }
+
+ public boolean isStarted() {
+ return server.isStarted();
+ }
+
+ public void stop() throws Exception {
+ server.stop();
+ server.destroy();
+ server = null;
+ }
+
+
+
+
+ public static void stopServerViaJMX(int jmxPort) throws CDMEmbeddedServerException {
+ String JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:" + jmxPort + "/jmxrmi";
+ logger.warn("Shutting down Jetty instance ... ");
+
+ try {
+ JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), null);
+ connector.connect(null);
+ MBeanServerConnection connection = connector.getMBeanServerConnection();
+ ObjectName objectName = new ObjectName("org.eclipse.jetty.server:type=server,id=0");
+ connection.invoke(objectName, "stop", null, null);
+ logger.warn("Shutdown command sent");
+ } catch (InstanceNotFoundException e) {
+ throw new CDMEmbeddedServerException(e);
+ } catch (MBeanException e) {
+ throw new CDMEmbeddedServerException(e);
+ } catch (ReflectionException e) {
+ throw new CDMEmbeddedServerException(e);
+ } catch (IOException e) {
+ throw new CDMEmbeddedServerException(e);
+ } catch (MalformedObjectNameException e) {
+ throw new CDMEmbeddedServerException(e);
+ }
+ }
+
+
+}
--- /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.webapp;
+
+/**
+ * @author cmathew
+ * @date 16 Nov 2015
+ *
+ */
+public interface ICDMServerError {
+
+ public void handleError(Throwable t);
+
+}
--- /dev/null
+package eu.etaxonomy.taxeditor.webapp;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ *
+ * @author n.hoffmann
+ * @version $Id: $
+ */
+public class TaxeditorWebappPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ /** Constant <code>PLUGIN_ID="eu.etaxonomy.taxeditor.editor"</code> */
+ public static final String PLUGIN_ID = "eu.etaxonomy.taxeditor.editor";
+
+ // The shared instance
+ private static TaxeditorWebappPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public TaxeditorWebappPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ /** {@inheritDoc} */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ /** {@inheritDoc} */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static TaxeditorWebappPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns an image descriptor for the image file at the given
+ * plug-in relative path
+ *
+ * @param path the path
+ * @return the image descriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+
+
+ /**
+ * Exposes this normally protected method.
+ *
+ * @return a {@link org.eclipse.jface.resource.ImageRegistry} object.
+ */
+ @Override
+ public ImageRegistry createImageRegistry(){
+ return super.createImageRegistry();
+ }
+}
<module>eu.etaxonomy.taxeditor.help</module>
<module>eu.etaxonomy.taxeditor.molecular</module>
<module>eu.etaxonomy.taxeditor.molecular.lib</module>
+ <module>eu.etaxonomy.taxeditor.webapp</module>
<module>eu.etaxonomy.taxeditor.application</module>
<module>eu.etaxonomy.taxeditor.feature.platform</module>
<module>eu.etaxonomy.taxeditor.feature</module>