diff options
author | Christian W. Damus | 2013-10-30 15:55:10 +0000 |
---|---|---|
committer | Christian W. Damus | 2013-11-01 21:11:31 +0000 |
commit | 886d5a746422301f5087ef10033219afb97459e1 (patch) | |
tree | ab5eedb6449deb348a83bd61fa9f115dee232fcd | |
parent | 721bc4c06d7f080669017f92ba516ce5f67ed705 (diff) | |
download | cdo-bugs/418454.tar.gz cdo-bugs/418454.tar.xz cdo-bugs/418454.zip |
[418454] [Admin] Client API and UI for managing repositories in a serverbugs/418454
https://bugs.eclipse.org/bugs/show_bug.cgi?id=418454
UI for deletion of a repository, including confirmation dialog and error handling.
UI for creation of a repository.
Both actions require authorization by providing the credentials of the admin repository's administrator user.
26 files changed, 1466 insertions, 51 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/admin/CDOAdmin.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/admin/CDOAdmin.java index be08e1cf6d..13d3bfaccd 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/admin/CDOAdmin.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/admin/CDOAdmin.java @@ -29,6 +29,12 @@ import java.util.Map; */ public interface CDOAdmin extends IContainer<CDOAdminRepository>, Closeable { + /** + * The default admin-handler type, which is guaranteed to exist on the server. + * + * @since 4.3 + */ + public static final String TYPE_DEFAULT = "default"; //$NON-NLS-1$ /** * The name of the boolean property that indicates whether to configure the diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.emf.cdo.ui.admin/.settings/org.eclipse.core.resources.prefs index dd2bd57b09..d950894767 100644 --- a/plugins/org.eclipse.emf.cdo.ui.admin/.settings/org.eclipse.core.resources.prefs +++ b/plugins/org.eclipse.emf.cdo.ui.admin/.settings/org.eclipse.core.resources.prefs @@ -1,3 +1,2 @@ -#Mon Jul 04 12:55:06 CEST 2011 eclipse.preferences.version=1 - +encoding//src/org/eclipse/emf/cdo/ui/internal/admin/messages/messages.properties=ISO-8859-1 diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.ui.admin/META-INF/MANIFEST.MF index 73c1b58dea..f85dfe7ce0 100644 --- a/plugins/org.eclipse.emf.cdo.ui.admin/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.ui.admin/META-INF/MANIFEST.MF @@ -16,4 +16,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.emf.cdo.ui.shared;bundle-version="[4.0.0,5.0.0)", org.eclipse.net4j.ui.shared;bundle-version="[4.0.0,5.0.0)" Export-Package: org.eclipse.emf.cdo.ui.internal.admin;version="4.1.200";x-internal:=true, - org.eclipse.emf.cdo.ui.internal.admin.bundle;version="4.1.200";x-internal:=true + org.eclipse.emf.cdo.ui.internal.admin.actions;version="4.1.200";x-internal:=true, + org.eclipse.emf.cdo.ui.internal.admin.bundle;version="4.1.200";x-internal:=true, + org.eclipse.emf.cdo.ui.internal.admin.messages;version="4.1.200";x-internal:=true, + org.eclipse.emf.cdo.ui.internal.admin.wizards;version="4.1.200";x-internal:=true diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/build.properties b/plugins/org.eclipse.emf.cdo.ui.admin/build.properties index 3cf0877240..549cadeee8 100644 --- a/plugins/org.eclipse.emf.cdo.ui.admin/build.properties +++ b/plugins/org.eclipse.emf.cdo.ui.admin/build.properties @@ -6,6 +6,7 @@ # # Contributors: # Eike Stepper - initial API and implementation +# Christian W. Damus (CEA LIST) - bug 418454 # NLS_MESSAGEFORMAT_VAR @@ -17,6 +18,7 @@ bin.includes = .,\ about.html,\ copyright.txt,\ .options +bin.excludes = icons/**/*.pxm jars.compile.order = . source.. = src/ output.. = bin/ diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/ctool16/create_repo.gif b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/ctool16/create_repo.gif Binary files differnew file mode 100644 index 0000000000..2a3a2bafb3 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/ctool16/create_repo.gif diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/ctool16/create_repo.pxm b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/ctool16/create_repo.pxm Binary files differnew file mode 100644 index 0000000000..fe244f6f91 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/ctool16/create_repo.pxm diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/icons/admin_view.gif b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/view16/admin_view.gif Binary files differindex fb77b5926c..fb77b5926c 100644 --- a/plugins/org.eclipse.emf.cdo.ui.admin/icons/admin_view.gif +++ b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/view16/admin_view.gif diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/wizban/new_repo.png b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/wizban/new_repo.png Binary files differnew file mode 100644 index 0000000000..a5b302fafd --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/wizban/new_repo.png diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/wizban/new_repo.pxm b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/wizban/new_repo.pxm Binary files differnew file mode 100644 index 0000000000..91ce322f46 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/icons/full/wizban/new_repo.pxm diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/plugin.xml b/plugins/org.eclipse.emf.cdo.ui.admin/plugin.xml index ac7059f080..be4092a3aa 100644 --- a/plugins/org.eclipse.emf.cdo.ui.admin/plugin.xml +++ b/plugins/org.eclipse.emf.cdo.ui.admin/plugin.xml @@ -9,6 +9,7 @@ Contributors: Eike Stepper - initial API and implementation + Christian W. Damus (CEA LIST) - bug 418454 --> <plugin> @@ -18,7 +19,7 @@ <view category="org.eclipse.emf.cdo" class="org.eclipse.emf.cdo.ui.internal.admin.CDOAdminView" - icon="icons/admin_view.gif" + icon="icons/full/view16/admin_view.gif" id="org.eclipse.emf.cdo.ui.admin.CDOAdminView" name="%view.name.0"> </view> diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/CDOAdminView.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/CDOAdminView.java index 0bee3e9f30..f833025e8f 100644 --- a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/CDOAdminView.java +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/CDOAdminView.java @@ -18,20 +18,21 @@ import org.eclipse.emf.cdo.common.admin.CDOAdminRepository; import org.eclipse.emf.cdo.common.model.CDOPackageRegistryPopulator; import org.eclipse.emf.cdo.net4j.CDONet4jSession; import org.eclipse.emf.cdo.net4j.CDONet4jSessionConfiguration; +import org.eclipse.emf.cdo.ui.internal.admin.actions.AdminAction; +import org.eclipse.emf.cdo.ui.internal.admin.actions.CreateRepositoryAction; +import org.eclipse.emf.cdo.ui.internal.admin.actions.DeleteRepositoryAction; import org.eclipse.emf.cdo.ui.internal.admin.bundle.OM; +import org.eclipse.emf.cdo.ui.internal.admin.messages.Messages; import org.eclipse.emf.cdo.ui.shared.SharedIcons; import org.eclipse.emf.internal.cdo.session.CDOSessionFactory; -import org.eclipse.net4j.signal.RemoteException; import org.eclipse.net4j.ui.Net4jItemProvider.RemoveAction; import org.eclipse.net4j.util.container.IContainer; import org.eclipse.net4j.util.container.IManagedContainer; import org.eclipse.net4j.util.security.CredentialsProviderFactory; import org.eclipse.net4j.util.security.IPasswordCredentialsProvider; -import org.eclipse.net4j.util.security.NotAuthenticatedException; import org.eclipse.net4j.util.ui.UIUtil; -import org.eclipse.net4j.util.ui.actions.LongRunningAction; import org.eclipse.net4j.util.ui.views.ContainerItemProvider; import org.eclipse.net4j.util.ui.views.ContainerView; @@ -47,6 +48,8 @@ import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; +import java.text.MessageFormat; + /** * @author Eike Stepper */ @@ -92,7 +95,8 @@ public class CDOAdminView extends ContainerView if (obj instanceof CDOAdminRepository) { CDOAdminRepository repository = (CDOAdminRepository)obj; - return repository.getName() + " [" + repository.getType() + ", " + repository.getState() + "]"; + return MessageFormat.format(Messages.CDOAdminView_0, repository.getName(), repository.getType(), + repository.getState()); } return super.getText(obj); @@ -160,12 +164,14 @@ public class CDOAdminView extends ContainerView if (obj instanceof CDOAdminClient) { CDOAdminClient admin = (CDOAdminClient)obj; + manager.add(new CreateRepositoryAction(admin)); manager.add(new RemoveConnectionAction(adminManager, admin)); } else if (obj instanceof CDOAdminClientRepository) { CDOAdminClientRepository repository = (CDOAdminClientRepository)obj; manager.add(new OpenSessionAction(repository)); + manager.add(new DeleteRepositoryAction(repository)); } } } @@ -181,7 +187,7 @@ public class CDOAdminView extends ContainerView public void run() { String lastURL = OM.getLastURL(); - InputDialog dialog = new InputDialog(getShell(), getText(), "Enter the connection URL:", lastURL, null); + InputDialog dialog = new InputDialog(getShell(), getText(), Messages.CDOAdminView_1, lastURL, null); if (dialog.open() == InputDialog.OK) { String url = dialog.getValue(); @@ -191,8 +197,8 @@ public class CDOAdminView extends ContainerView } }; - addConnectionAction.setText("Add Connection"); - addConnectionAction.setToolTipText("Add a new connection"); + addConnectionAction.setText(Messages.CDOAdminView_2); + addConnectionAction.setToolTipText(Messages.CDOAdminView_3); addConnectionAction.setImageDescriptor(org.eclipse.net4j.ui.shared.SharedIcons .getDescriptor(org.eclipse.net4j.ui.shared.SharedIcons.ETOOL_ADD)); } @@ -205,7 +211,7 @@ public class CDOAdminView extends ContainerView { IManagedContainer container = adminManager.getContainer(); String productGroup = CredentialsProviderFactory.PRODUCT_GROUP; - String factoryType = "interactive"; + String factoryType = "interactive"; //$NON-NLS-1$ IPasswordCredentialsProvider credentialsProvider = (IPasswordCredentialsProvider)container.getElement(productGroup, factoryType, null); @@ -256,58 +262,31 @@ public class CDOAdminView extends ContainerView /** * @author Eike Stepper */ - public class OpenSessionAction extends LongRunningAction implements CDOAdminClientRepository.SessionConfigurator + public class OpenSessionAction extends AdminAction<CDOAdminClientRepository> implements + CDOAdminClientRepository.SessionConfigurator { - private CDOAdminClientRepository repository; - public OpenSessionAction(CDOAdminClientRepository repository) { - super("Open Session", "Open a new session to this repository", SharedIcons - .getDescriptor(SharedIcons.ETOOL_OPEN_SESSION)); - this.repository = repository; + super(Messages.CDOAdminView_4, Messages.CDOAdminView_5, + SharedIcons.getDescriptor(SharedIcons.ETOOL_OPEN_SESSION), repository); } public CDOAdminClientRepository getRepository() { - return repository; + return target; } @Override - protected void doRun(IProgressMonitor progressMonitor) throws Exception + protected void safeRun(IProgressMonitor progressMonitor) throws Exception { - try + CDONet4jSession session = target.openSession(this); + if (session != null) { - CDONet4jSession session = repository.openSession(this); - if (session != null) - { - CDOPackageRegistryPopulator.populate(session.getPackageRegistry()); + CDOPackageRegistryPopulator.populate(session.getPackageRegistry()); - IManagedContainer container = adminManager.getContainer(); - String description = "session" + getNextSessionNumber(); - container.putElement(CDOSessionFactory.PRODUCT_GROUP, "admin", description, session); - } - } - catch (RemoteException ex) - { - if (ex.getCause() instanceof NotAuthenticatedException) - { - // Skip silently because user has canceled the authentication - } - else - { - throw ex; - } - } - catch (Exception ex) - { - if (ex instanceof NotAuthenticatedException) - { - // Skip silently because user has canceled the authentication - } - else - { - throw ex; - } + IManagedContainer container = adminManager.getContainer(); + String description = "session" + getNextSessionNumber(); //$NON-NLS-1$ + container.putElement(CDOSessionFactory.PRODUCT_GROUP, "admin", description, session); //$NON-NLS-1$ } } @@ -316,5 +295,11 @@ public class CDOAdminView extends ContainerView IPasswordCredentialsProvider credentialsProvider = getCredentialsProvider(); configuration.setCredentialsProvider(credentialsProvider); } + + @Override + protected String getErrorPattern() + { + return Messages.CDOAdminView_6; + } } } diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/StoreType.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/StoreType.java new file mode 100644 index 0000000000..187e4b9d47 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/StoreType.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.ui.internal.admin; + +import org.eclipse.emf.cdo.ui.internal.admin.messages.Messages; + +import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.util.io.IOUtil; + +import java.net.URL; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * @author Christian W. Damus (CEA LIST) + */ +public abstract class StoreType +{ + private static final List<StoreType> INSTANCES = Collections.unmodifiableList(Arrays.asList(initStoreTypes())); + + private final String id; + + private final String name; + + public StoreType(String id, String name) + { + this.id = id; + this.name = name; + } + + public static List<StoreType> getInstances() + { + return INSTANCES; + } + + public String getID() + { + return id; + } + + public String getName() + { + return name; + } + + public abstract String getStoreTypeID(); + + public String getStoreXML(Map<String, Object> storeProperties) + { + String template = getTemplate(); + return fillTemplate(template, storeProperties); + } + + protected abstract String fillTemplate(String xmlTemplate, Map<String, Object> storeProperties); + + protected String replaceVariables(String template, Map<String, String> variables) + { + String result = template; + for (Map.Entry<String, String> entry : variables.entrySet()) + { + result = result.replace("{{" + entry.getKey() + "}}", entry.getValue()); //$NON-NLS-1$ //$NON-NLS-2$ + } + return result; + } + + private String getTemplate() + { + URL url = getClass().getResource(getStoreTypeID() + ".template.xml"); //$NON-NLS-1$ + return IOUtil.readText(url); + } + + @Override + public String toString() + { + return getName(); + } + + private static StoreType[] initStoreTypes() + { + // TODO: Make these contributable by store UI plug-ins + return new StoreType[] { new Database("h2", Messages.StoreType_0, "org.h2.jdbcx.JdbcDataSource", "jdbc:h2:%s"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + }; + } + + /** + * @author Christian W. Damus (CEA LIST) + */ + public static class Database extends StoreType + { + public static final String PROPERTY_PATH = "path"; //$NON-NLS-1$ + + public static final String PROPERTY_CONNECTION_KEEP_ALIVE_PERIOD = "connectionKeepAlivePeriod"; //$NON-NLS-1$ + + public static final String DEFAULT_CONNECTION_KEEP_ALIVE_PERIOD = "60"; //$NON-NLS-1$ + + public static final String PROPERTY_READER_POOL_CAPACITY = "readerPoolCapacity"; //$NON-NLS-1$ + + public static final String DEFAULT_READER_POOL_CAPACITY = "15"; //$NON-NLS-1$ + + public static final String PROPERTY_WRITER_POOL_CAPACITY = "writerPoolCapacity"; //$NON-NLS-1$ + + public static final String DEFAULT_WRITER_POOL_CAPACITY = "15"; //$NON-NLS-1$ + + private final String adapter; + + private final String dataSourceClassName; + + private final String urlPattern; + + public Database(String id, String name, String dataSourceClassName, String urlPattern) + { + super("db." + id, name); //$NON-NLS-1$ + adapter = id; + this.dataSourceClassName = dataSourceClassName; + this.urlPattern = urlPattern; + } + + @Override + public String getStoreTypeID() + { + return "db"; //$NON-NLS-1$ + } + + public String getAdapter() + { + return adapter; + } + + public String getDataSourceClassName() + { + return dataSourceClassName; + } + + public String getDataSourceURL(String storePath) + { + return String.format(urlPattern, storePath); + } + + @Override + protected String fillTemplate(String xmlTemplate, Map<String, Object> storeProperties) + { + Map<String, String> variables = new java.util.HashMap<String, String>(); + variables.put("adapter", getAdapter()); //$NON-NLS-1$ + variables.put("dataSource.class", getDataSourceClassName()); //$NON-NLS-1$ + variables.put("dataSource.url", getDataSourceURL((String)storeProperties.get(PROPERTY_PATH))); //$NON-NLS-1$ + variables.put("keepAlive", //$NON-NLS-1$ + defaultString(storeProperties, PROPERTY_CONNECTION_KEEP_ALIVE_PERIOD, DEFAULT_CONNECTION_KEEP_ALIVE_PERIOD)); + variables.put("readerPool", //$NON-NLS-1$ + defaultString(storeProperties, PROPERTY_READER_POOL_CAPACITY, DEFAULT_READER_POOL_CAPACITY)); + variables.put("writerPool", //$NON-NLS-1$ + defaultString(storeProperties, PROPERTY_WRITER_POOL_CAPACITY, DEFAULT_WRITER_POOL_CAPACITY)); + return replaceVariables(xmlTemplate, variables); + } + + private String defaultString(Map<String, Object> storeProperties, String key, String defaultValue) + { + String value = (String)storeProperties.get(key); + return StringUtil.isEmpty(value) ? defaultValue : value; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/AdminAction.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/AdminAction.java new file mode 100644 index 0000000000..ff43f00b8e --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/AdminAction.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012-2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - bug 418454 + */ +package org.eclipse.emf.cdo.ui.internal.admin.actions; + +import org.eclipse.emf.cdo.ui.internal.admin.bundle.OM; + +import org.eclipse.net4j.signal.RemoteException; +import org.eclipse.net4j.util.security.NotAuthenticatedException; +import org.eclipse.net4j.util.ui.actions.LongRunningAction; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.resource.ImageDescriptor; + +import java.text.MessageFormat; + +/** + * @param <T> the type of the target element of the action in the CDO Administration View + * + * @author Christian W. Damus (CEA LIST) + */ +public abstract class AdminAction<T> extends LongRunningAction +{ + protected final T target; + + protected AdminAction(String label, String tooltip, ImageDescriptor imageDescriptor, T target) + { + super(label, tooltip, imageDescriptor); + this.target = target; + } + + @Override + protected final void doRun(IProgressMonitor progressMonitor) throws Exception + { + try + { + safeRun(progressMonitor); + } + catch (RemoteException e) + { + handleError(e.getCause() == null ? e : e.getCause()); + } + catch (Exception e) + { + handleError(e); + } + } + + protected abstract void safeRun(IProgressMonitor progressMonitor) throws Exception; + + protected void handleError(Throwable ex) + { + if (ex instanceof NotAuthenticatedException) + { + // Skip silently because user has canceled the authentication + } + else + { + showError(ex); + } + } + + protected void showError(final Throwable e) + { + OM.LOG.error(e); + getDisplay().asyncExec(new Runnable() + { + public void run() + { + MessageDialog.openError(getShell(), getText(), MessageFormat.format(getErrorPattern(), e.getLocalizedMessage())); + } + }); + } + + protected abstract String getErrorPattern(); +} diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/CreateRepositoryAction.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/CreateRepositoryAction.java new file mode 100644 index 0000000000..3c969b1f98 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/CreateRepositoryAction.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012-2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.ui.internal.admin.actions; + +import org.eclipse.emf.cdo.admin.CDOAdminClient; +import org.eclipse.emf.cdo.common.admin.CDOAdmin; +import org.eclipse.emf.cdo.ui.internal.admin.bundle.OM; +import org.eclipse.emf.cdo.ui.internal.admin.messages.Messages; +import org.eclipse.emf.cdo.ui.internal.admin.wizards.CreateRepositoryWizard; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardDialog; + +import java.util.Map; + +/** + * @author Christian W. Damus (CEA LIST) + */ +public class CreateRepositoryAction extends AdminAction<CDOAdminClient> +{ + private String repositoryName; + + private Map<String, Object> repositoryProperties; + + public CreateRepositoryAction(CDOAdminClient admin) + { + super(Messages.CreateRepositoryAction_0, Messages.CreateRepositoryAction_1, OM + .getImageDescriptor("icons/full/ctool16/create_repo.gif"), admin); //$NON-NLS-1$ + } + + @Override + protected void preRun() throws Exception + { + CreateRepositoryWizard wizard = new CreateRepositoryWizard(); + WizardDialog wizardDialog = new WizardDialog(getShell(), wizard); + if (wizardDialog.open() == Window.OK) + { + repositoryName = wizard.getRepositoryName(); + repositoryProperties = wizard.getRepositoryProperties(); + } + else + { + cancel(); + } + } + + @Override + protected void safeRun(IProgressMonitor progressMonitor) throws Exception + { + try + { + target.createRepository(repositoryName, CDOAdmin.TYPE_DEFAULT, repositoryProperties); + } + finally + { + repositoryName = null; + repositoryProperties = null; + } + } + + @Override + protected String getErrorPattern() + { + return Messages.CreateRepositoryAction_2; + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/DeleteRepositoryAction.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/DeleteRepositoryAction.java new file mode 100644 index 0000000000..b712b343d9 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/actions/DeleteRepositoryAction.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012-2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.ui.internal.admin.actions; + +import org.eclipse.emf.cdo.admin.CDOAdminClientRepository; +import org.eclipse.emf.cdo.common.admin.CDOAdmin; +import org.eclipse.emf.cdo.ui.internal.admin.messages.Messages; + +import org.eclipse.net4j.ui.shared.SharedIcons; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; + +import java.text.MessageFormat; + +/** + * @author Christian W. Damus (CEA LIST) + */ +public class DeleteRepositoryAction extends AdminAction<CDOAdminClientRepository> +{ + public DeleteRepositoryAction(CDOAdminClientRepository repository) + { + super(Messages.DeleteRepositoryAction_1, Messages.DeleteRepositoryAction_2, SharedIcons + .getDescriptor(SharedIcons.ETOOL_DELETE), repository); + } + + @Override + protected void preRun() throws Exception + { + final int NO_BUTTON = 1; + String message = MessageFormat.format(Messages.DeleteRepositoryAction_4, target.getName()); + MessageDialog dlg = new MessageDialog(getShell(), getText(), null, message, MessageDialog.WARNING, new String[] { + IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, NO_BUTTON); + if (dlg.open() == NO_BUTTON) + { + cancel(); + } + } + + @Override + protected void safeRun(IProgressMonitor progressMonitor) throws Exception + { + target.delete(CDOAdmin.TYPE_DEFAULT); + } + + @Override + protected String getErrorPattern() + { + return Messages.DeleteRepositoryAction_3; + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/bundle/OM.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/bundle/OM.java index c525aad657..fc236a1964 100644 --- a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/bundle/OM.java +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/bundle/OM.java @@ -8,6 +8,7 @@ * Contributors: * Eike Stepper - initial API and implementation * Victor Roldan Betancort - maintenance + * Christian W. Damus (CEA LIST) - bug 418454 */ package org.eclipse.emf.cdo.ui.internal.admin.bundle; @@ -69,6 +70,8 @@ public abstract class OM */ public static final class Activator extends UIActivator.WithState { + public static Activator INSTANCE; + public Activator() { super(BUNDLE); @@ -77,6 +80,8 @@ public abstract class OM @Override protected void doStartWithState(Object state) throws Exception { + INSTANCE = this; + LifecycleUtil.activate(adminManager); if (state instanceof List<?>) { @@ -98,6 +103,9 @@ public abstract class OM urls.add(0, lastURL); LifecycleUtil.deactivate(adminManager); + + INSTANCE = null; + return urls; } } diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/db.template.xml b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/db.template.xml new file mode 100644 index 0000000000..bc3b27a5ec --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/db.template.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<store type="db"> + + <property name="connectionKeepAlivePeriod" value="{{keepAlive}}"/> + <property name="readerPoolCapacity" value="{{readerPool}}"/> + <property name="writerPoolCapacity" value="{{writerPool}}"/> + + <mappingStrategy type="horizontal"> + <property name="qualifiedNames" value="true"/> + </mappingStrategy> + + <dbAdapter name="{{adapter}}"/> + <dataSource + class="{{dataSource.class}}" + uRL="{{dataSource.url}}"/> + +</store> diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/messages/Messages.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/messages/Messages.java new file mode 100644 index 0000000000..251f2b802f --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/messages/Messages.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2004-2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.ui.internal.admin.messages; + +import org.eclipse.osgi.util.NLS; + +/** + * @author Christian W. Damus (CEA LIST) + */ +public class Messages extends NLS +{ + private static final String BUNDLE_NAME = "org.eclipse.emf.cdo.ui.internal.admin.messages.messages"; //$NON-NLS-1$ + + public static String CDOAdminView_0; + + public static String CDOAdminView_1; + + public static String CDOAdminView_2; + + public static String CDOAdminView_3; + + public static String CDOAdminView_4; + + public static String CDOAdminView_5; + + public static String CDOAdminView_6; + + public static String CreateRepositoryAction_0; + + public static String CreateRepositoryAction_1; + + public static String CreateRepositoryAction_2; + + public static String CreateRepositoryWizard_0; + + public static String CreateRepositoryGeneralPage_0; + + public static String CreateRepositoryGeneralPage_1; + + public static String CreateRepositoryGeneralPage_10; + + public static String CreateRepositoryGeneralPage_11; + + public static String CreateRepositoryGeneralPage_12; + + public static String CreateRepositoryGeneralPage_13; + + public static String CreateRepositoryGeneralPage_14; + + public static String CreateRepositoryGeneralPage_15; + + public static String CreateRepositoryGeneralPage_2; + + public static String CreateRepositoryGeneralPage_3; + + public static String CreateRepositoryGeneralPage_4; + + public static String CreateRepositoryGeneralPage_5; + + public static String CreateRepositoryGeneralPage_6; + + public static String CreateRepositoryGeneralPage_7; + + public static String CreateRepositoryGeneralPage_8; + + public static String CreateRepositoryGeneralPage_9; + + public static String CreateRepositoryStorePage_0; + + public static String CreateRepositoryStorePage_1; + + public static String CreateRepositoryStorePage_10; + + public static String CreateRepositoryStorePage_11; + + public static String CreateRepositoryStorePage_12; + + public static String CreateRepositoryStorePage_2; + + public static String CreateRepositoryStorePage_3; + + public static String CreateRepositoryStorePage_4; + + public static String CreateRepositoryStorePage_5; + + public static String CreateRepositoryStorePage_6; + + public static String CreateRepositoryStorePage_7; + + public static String CreateRepositoryStorePage_8; + + public static String CreateRepositoryStorePage_9; + + public static String DeleteRepositoryAction_1; + + public static String DeleteRepositoryAction_2; + + public static String DeleteRepositoryAction_3; + + public static String DeleteRepositoryAction_4; + + public static String StoreType_0; + + static + { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() + { + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/messages/messages.properties b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/messages/messages.properties new file mode 100644 index 0000000000..58ca552dec --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/messages/messages.properties @@ -0,0 +1,55 @@ +# Copyright (c) 2012-2013 Eike Stepper (Berlin, Germany) and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Eike Stepper - initial API and implementation +# Christian W. Damus (CEA) - bug 418454 + +CDOAdminView_0={0} [{1}, {2}] +CDOAdminView_1=Enter the connection URL: +CDOAdminView_2=Add Connection +CDOAdminView_3=Add a new connection +CDOAdminView_4=Open Session +CDOAdminView_5=Open a new session to this repository +CDOAdminView_6=Could not open a session: {0} +CreateRepositoryAction_0=Create Repository... +CreateRepositoryAction_1=Create a repository on the server +CreateRepositoryAction_2=Could not create repository: {0} +CreateRepositoryWizard_0=Create Repository +CreateRepositoryGeneralPage_0=Enter the configuration details of the new repository. +CreateRepositoryGeneralPage_1=Name: +CreateRepositoryGeneralPage_10=Ensure referential integrity +CreateRepositoryGeneralPage_11=Allow running queries to be interrupted +CreateRepositoryGeneralPage_12=Override UUID: +CreateRepositoryGeneralPage_13=ID generation: +CreateRepositoryGeneralPage_14=Security Manager +CreateRepositoryGeneralPage_15=Store +CreateRepositoryGeneralPage_2=Enable security management +CreateRepositoryGeneralPage_3=Automatic home folders for users +CreateRepositoryGeneralPage_4=Store type: +CreateRepositoryGeneralPage_5=General Settings +CreateRepositoryGeneralPage_6=Repository Properties +CreateRepositoryGeneralPage_7=Enable auditing (version history) +CreateRepositoryGeneralPage_8=Enable branching +CreateRepositoryGeneralPage_9=Enable storage of Ecore models +CreateRepositoryStorePage_0=Store path: +CreateRepositoryStorePage_1={0} Store Settings +CreateRepositoryStorePage_10=The connection keep-alive period must be a positive integer. +CreateRepositoryStorePage_11=The reader pool size must be a positive integer. +CreateRepositoryStorePage_12=The writer pool size must be a positive integer. +CreateRepositoryStorePage_2=Enter configuration parameters for the repository store. +CreateRepositoryStorePage_3=General Properties +CreateRepositoryStorePage_4=Performance Tuning +CreateRepositoryStorePage_5=Keep-alive period (minutes): +CreateRepositoryStorePage_6=Reader pool size: +CreateRepositoryStorePage_7=Writer pool size: +CreateRepositoryStorePage_8=The store path is required. +CreateRepositoryStorePage_9=The connection keep-alive period is required. +DeleteRepositoryAction_1=Delete Repository +DeleteRepositoryAction_2=Remove this repository from the server +DeleteRepositoryAction_3=Could not delete repository: {0} +DeleteRepositoryAction_4=This action shuts down and removes the repository "{0}" on the server. It cannot be undone. You must provide your administrator credentials to complete this action. Are you certain you want to delete this repository? +StoreType_0=H2 Database diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/AbstractCreateRepositoryWizardPage.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/AbstractCreateRepositoryWizardPage.java new file mode 100644 index 0000000000..da1bc92d9e --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/AbstractCreateRepositoryWizardPage.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.ui.internal.admin.wizards; + +import org.eclipse.emf.cdo.ui.internal.admin.bundle.OM; + +import org.eclipse.net4j.util.ui.UIUtil; + +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +/** + * @author Christian W. Damus (CEA LIST) + */ +public abstract class AbstractCreateRepositoryWizardPage extends WizardPage +{ + private Whiteboard whiteboard; + + public AbstractCreateRepositoryWizardPage(String pageName) + { + super(pageName); + } + + public void createControl(Composite parent) + { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(UIUtil.createGridLayout(2)); + createContents(composite); + setControl(composite); + + loadSettings(getDialogSettings()); + hookListeners(); + } + + protected abstract void createContents(Composite parent); + + protected void hookListeners() + { + hookListeners(new Listener() + { + + public void handleEvent(Event event) + { + updateEnablement(false); + } + }); + + updateEnablement(true); + } + + protected void hookListeners(Listener updateListener) + { + } + + protected void updateEnablement(boolean firstTime) + { + setPageComplete(true); + } + + boolean performFinish(Map<String, Object> repositoryProperties) + { + boolean result = collectRepositoryProperties(repositoryProperties); + saveSettings(getDialogSettings()); + return result; + } + + protected abstract boolean collectRepositoryProperties(Map<String, Object> repositoryProperties); + + protected void loadSettings(IDialogSettings pageSettings) + { + } + + @Override + protected IDialogSettings getDialogSettings() + { + IDialogSettings wizardSettings = super.getDialogSettings(); + + return wizardSettings == null ? null : DialogSettings.getOrCreateSection(wizardSettings, getName()); + } + + protected String getSetting(IDialogSettings pageSettings, String key, String defaultValue) + { + return pageSettings.get(key) == null ? defaultValue : pageSettings.get(key); + } + + protected boolean getSetting(IDialogSettings pageSettings, String key, boolean defaultValue) + { + return pageSettings.get(key) == null ? defaultValue : pageSettings.getBoolean(key); + } + + protected void saveSettings(IDialogSettings pageSettings) + { + } + + protected Group group(Composite parent, String label) + { + Group result = new Group(parent, SWT.BORDER); + result.setText(label); + result.setLayoutData(UIUtil.createGridData(true, false)); + result.setLayout(new GridLayout(2, false)); + return result; + } + + protected Text text(Composite parent, String label) + { + new Label(parent, SWT.NONE).setText(label); + Text result = new Text(parent, SWT.BORDER); + result.setLayoutData(UIUtil.createGridData(true, false)); + return result; + } + + protected Button checkbox(Composite parent, String label) + { + Button result = new Button(parent, SWT.CHECK); + result.setText(label); + result.setLayoutData(UIUtil.createGridData(2, 1)); + return result; + } + + protected ComboViewer combo(Composite parent, String label, Object input) + { + new Label(parent, SWT.NONE).setText(label); + ComboViewer result = new ComboViewer(parent, SWT.READ_ONLY | SWT.DROP_DOWN); + result.setContentProvider(new ArrayContentProvider()); + result.setInput(input); + return result; + } + + protected boolean checked(Button checkbox) + { + return checkbox.isEnabled() && checkbox.getSelection(); + } + + protected String text(Text text) + { + return text.getText().trim(); + } + + protected boolean positiveInteger(String value) + { + try + { + return Integer.parseInt(value) > 0; + } + catch (NumberFormatException e) + { + return false; + } + } + + protected final void publish(Object topic) + { + if (whiteboard != null && topic != null) + { + whiteboard.publish(topic); + } + } + + final void bind(Whiteboard whiteboard) + { + if (this.whiteboard != null) + { + throw new IllegalStateException("already bound to a whiteboard"); //$NON-NLS-1$ + } + this.whiteboard = whiteboard; + whiteboard.subscribe(this); + } + + /** + * @author Christian W. Damus (CEA LIST) + */ + @Target({ ElementType.METHOD }) + @Retention(RetentionPolicy.RUNTIME) + public static @interface Subscribe + { + } + + /** + * @author Christian W. Damus (CEA LIST) + */ + public static final class Whiteboard + { + private List<Object> subscribers = new java.util.ArrayList<Object>(); + + /** + * Publish a topic to interested subscribers. + */ + public void publish(Object topic) + { + for (Object subscriber : subscribers) + { + Method handler = getHandler(subscriber, topic.getClass()); + if (handler != null) + { + try + { + handler.invoke(subscriber, topic); + } + catch (Exception e) + { + OM.LOG.error(e); + } + } + } + } + + void subscribe(Object subscriber) + { + subscribers.add(subscriber); + } + + private Method getHandler(Object subscriber, Class<?> topicType) + { + for (Method method : subscriber.getClass().getMethods()) + { + if (method.isAnnotationPresent(Subscribe.class)) + { + Class<?>[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(topicType)) + { + return method; + } + } + } + + return null; + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryGeneralPage.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryGeneralPage.java new file mode 100644 index 0000000000..bf67bf975f --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryGeneralPage.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.ui.internal.admin.wizards; + +import org.eclipse.emf.cdo.common.CDOCommonRepository.IDGenerationLocation; +import org.eclipse.emf.cdo.common.admin.CDOAdmin; +import org.eclipse.emf.cdo.ui.internal.admin.StoreType; +import org.eclipse.emf.cdo.ui.internal.admin.messages.Messages; + +import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.util.ui.UIUtil; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +import java.util.List; +import java.util.Map; + +/** + * @author Christian W. Damus (CEA LIST) + */ +public class CreateRepositoryGeneralPage extends AbstractCreateRepositoryWizardPage +{ + public static final String PROPERTY_NAME = "name"; //$NON-NLS-1$ + + private final Map<String, StoreType> storeTypes; + + private Text nameText; + + private Button enableAuditingCheckbox; + + private Button enableBranchingCheckbox; + + private Button enableEcoreModelsCheckbox; + + private Button referentialIntegrityCheckbox; + + private Button allowInterruptQueriesCheckbox; + + private Text overrideUUIDText; + + private ComboViewer idGenerationLocationCombo; + + private Button securityCheckbox; + + private Button homeFoldersCheckbox; + + private ComboViewer storeCombo; + + private StoreType storeType; + + public CreateRepositoryGeneralPage(String pageName, List<StoreType> storeTypes) + { + super(pageName); + setTitle(Messages.CreateRepositoryGeneralPage_5); + setMessage(Messages.CreateRepositoryGeneralPage_0); + this.storeTypes = mapStoreTypes(storeTypes); + } + + @Override + protected void createContents(Composite parent) + { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(UIUtil.createGridData()); + composite.setLayout(new GridLayout()); + + Group properties = group(composite, Messages.CreateRepositoryGeneralPage_6); + nameText = text(properties, Messages.CreateRepositoryGeneralPage_1); + enableAuditingCheckbox = checkbox(properties, Messages.CreateRepositoryGeneralPage_7); + enableBranchingCheckbox = checkbox(properties, Messages.CreateRepositoryGeneralPage_8); + enableEcoreModelsCheckbox = checkbox(properties, Messages.CreateRepositoryGeneralPage_9); + referentialIntegrityCheckbox = checkbox(properties, Messages.CreateRepositoryGeneralPage_10); + allowInterruptQueriesCheckbox = checkbox(properties, Messages.CreateRepositoryGeneralPage_11); + overrideUUIDText = text(properties, Messages.CreateRepositoryGeneralPage_12); + idGenerationLocationCombo = combo(properties, Messages.CreateRepositoryGeneralPage_13, IDGenerationLocation.values()); + + Group security = group(composite, Messages.CreateRepositoryGeneralPage_14); + securityCheckbox = checkbox(security, Messages.CreateRepositoryGeneralPage_2); + homeFoldersCheckbox = checkbox(security, Messages.CreateRepositoryGeneralPage_3); + + Group store = group(composite, Messages.CreateRepositoryGeneralPage_15); + storeCombo = combo(store, Messages.CreateRepositoryGeneralPage_4, storeTypes.values()); + } + + @Override + protected void hookListeners(Listener updateListener) + { + enableAuditingCheckbox.addListener(SWT.Selection, updateListener); + securityCheckbox.addListener(SWT.Selection, updateListener); + nameText.addListener(SWT.Modify, updateListener); + storeCombo.getCombo().addListener(SWT.Selection, updateListener); + } + + @Override + protected void updateEnablement(boolean firstTime) + { + homeFoldersCheckbox.setEnabled(securityCheckbox.getSelection()); + enableBranchingCheckbox.setEnabled(enableAuditingCheckbox.getSelection()); + + StoreType newStoreType = UIUtil.getElement(storeCombo.getSelection(), StoreType.class); + if (storeType != newStoreType) + { + storeType = newStoreType; + publish(storeType); + } + + boolean nameOK = !StringUtil.isEmpty(nameText.getText().trim()); + boolean storeTypeOK = storeType != null; + + setPageComplete(nameOK && storeTypeOK); + } + + protected IDGenerationLocation getIDGenerationLocation() + { + return UIUtil.getElement(idGenerationLocationCombo.getSelection(), IDGenerationLocation.class); + } + + @Override + protected boolean collectRepositoryProperties(Map<String, Object> repositoryProperties) + { + repositoryProperties.put(PROPERTY_NAME, nameText.getText().trim()); + + // Additional properties that are standard across store types + repositoryProperties.put("supportingAudits", checked(enableAuditingCheckbox)); //$NON-NLS-1$ + repositoryProperties.put("supportingBranches", checked(enableBranchingCheckbox)); //$NON-NLS-1$ + repositoryProperties.put("supportingEcore", checked(enableEcoreModelsCheckbox)); //$NON-NLS-1$ + repositoryProperties.put("ensureReferentialIntegrity", checked(referentialIntegrityCheckbox)); //$NON-NLS-1$ + repositoryProperties.put("allowInterruptRunningQueries", checked(allowInterruptQueriesCheckbox)); //$NON-NLS-1$ + repositoryProperties.put("overrideUUID", text(overrideUUIDText)); //$NON-NLS-1$ + repositoryProperties.put("idGenerationLocation", getIDGenerationLocation().name()); //$NON-NLS-1$ + + repositoryProperties.put(CDOAdmin.PROPERTY_SECURITY_MANAGER, checked(securityCheckbox)); + repositoryProperties.put(CDOAdmin.PROPERTY_SECURITY_HOME_FOLDERS, checked(homeFoldersCheckbox)); + + return true; + } + + @Override + protected void loadSettings(IDialogSettings pageSettings) + { + // The repository names and override-UUIDs are unique, so we don't remember them + + enableAuditingCheckbox.setSelection(getSetting(pageSettings, "enableAuditing", true)); //$NON-NLS-1$ + enableBranchingCheckbox.setSelection(getSetting(pageSettings, "enableBranching", true)); //$NON-NLS-1$ + enableEcoreModelsCheckbox.setSelection(getSetting(pageSettings, "enableEcore", true)); //$NON-NLS-1$ + referentialIntegrityCheckbox.setSelection(getSetting(pageSettings, "referentialIntegrity", false)); //$NON-NLS-1$ + allowInterruptQueriesCheckbox.setSelection(getSetting(pageSettings, "allowInterruptQueries", true)); //$NON-NLS-1$ + + IDGenerationLocation idGen = IDGenerationLocation.valueOf(getSetting(pageSettings, "idGeneration", //$NON-NLS-1$ + IDGenerationLocation.STORE.name())); + idGenerationLocationCombo.setSelection(new StructuredSelection(idGen)); + + securityCheckbox.setSelection(getSetting(pageSettings, "security", true)); //$NON-NLS-1$ + homeFoldersCheckbox.setSelection(getSetting(pageSettings, "homeFolders", true)); //$NON-NLS-1$ + + StoreType storeType = storeTypes.get(getSetting(pageSettings, "storeType", null)); //$NON-NLS-1$ + if (storeType != null) + { + storeCombo.setSelection(new StructuredSelection(storeType)); + } + else + { + storeCombo.getCombo().select(0); + } + } + + @Override + protected void saveSettings(IDialogSettings pageSettings) + { + // The repository names and override-UUIDs are unique, so we don't remember them + + pageSettings.put("enableAuditing", enableAuditingCheckbox.getSelection()); //$NON-NLS-1$ + pageSettings.put("enableBranching", enableBranchingCheckbox.getSelection()); //$NON-NLS-1$ + pageSettings.put("enableEcore", enableEcoreModelsCheckbox.getSelection()); //$NON-NLS-1$ + pageSettings.put("referentialIntegrity", referentialIntegrityCheckbox.getSelection()); //$NON-NLS-1$ + pageSettings.put("allowInterruptQueries", allowInterruptQueriesCheckbox.getSelection()); //$NON-NLS-1$ + pageSettings.put("idGeneration", getIDGenerationLocation().name()); //$NON-NLS-1$ + + pageSettings.put("security", securityCheckbox.getSelection()); //$NON-NLS-1$ + pageSettings.put("homeFolders", homeFoldersCheckbox.getSelection()); //$NON-NLS-1$ + + pageSettings.put("storeType", storeType.getID()); //$NON-NLS-1$ + } + + private static Map<String, StoreType> mapStoreTypes(List<StoreType> storeTypes) + { + Map<String, StoreType> result = new java.util.HashMap<String, StoreType>(); + + for (StoreType storeType : storeTypes) + { + result.put(storeType.getID(), storeType); + } + + return result; + } + +} diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryStorePage.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryStorePage.java new file mode 100644 index 0000000000..bbc9d2539f --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryStorePage.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.ui.internal.admin.wizards; + +import static org.eclipse.emf.cdo.ui.internal.admin.StoreType.Database.DEFAULT_CONNECTION_KEEP_ALIVE_PERIOD; +import static org.eclipse.emf.cdo.ui.internal.admin.StoreType.Database.DEFAULT_READER_POOL_CAPACITY; +import static org.eclipse.emf.cdo.ui.internal.admin.StoreType.Database.DEFAULT_WRITER_POOL_CAPACITY; +import static org.eclipse.emf.cdo.ui.internal.admin.StoreType.Database.PROPERTY_CONNECTION_KEEP_ALIVE_PERIOD; +import static org.eclipse.emf.cdo.ui.internal.admin.StoreType.Database.PROPERTY_PATH; +import static org.eclipse.emf.cdo.ui.internal.admin.StoreType.Database.PROPERTY_READER_POOL_CAPACITY; +import static org.eclipse.emf.cdo.ui.internal.admin.StoreType.Database.PROPERTY_WRITER_POOL_CAPACITY; + +import org.eclipse.emf.cdo.common.admin.CDOAdmin; +import org.eclipse.emf.cdo.ui.internal.admin.StoreType; +import org.eclipse.emf.cdo.ui.internal.admin.messages.Messages; + +import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.util.ui.UIUtil; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +import java.text.MessageFormat; +import java.util.Map; + +/** + * @author Christian W. Damus (CEA LIST) + */ +public class CreateRepositoryStorePage extends AbstractCreateRepositoryWizardPage +{ + private static final String TITLE_PATTERN = Messages.CreateRepositoryStorePage_1; + + private Text storePathText; + + private Text connectionKeepAlivePeriodText; + + private Text readerPoolCapacityText; + + private Text writerPoolCapacityText; + + private StoreType storeType; + + public CreateRepositoryStorePage(String pageName) + { + super(pageName); + setTitle(TITLE_PATTERN); + setMessage(Messages.CreateRepositoryStorePage_2); + } + + @Subscribe + public void setStoreType(StoreType storeType) + { + this.storeType = storeType; + setTitle(MessageFormat.format(TITLE_PATTERN, storeType.getName())); + // TODO: When we support multiple store types, change a paged UI + } + + @Override + protected void createContents(Composite parent) + { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(UIUtil.createGridData()); + composite.setLayout(new GridLayout()); + + Group general = group(composite, Messages.CreateRepositoryStorePage_3); + storePathText = text(general, Messages.CreateRepositoryStorePage_0); + + Group performance = group(composite, Messages.CreateRepositoryStorePage_4); + connectionKeepAlivePeriodText = text(performance, Messages.CreateRepositoryStorePage_5); + readerPoolCapacityText = text(performance, Messages.CreateRepositoryStorePage_6); + writerPoolCapacityText = text(performance, Messages.CreateRepositoryStorePage_7); + } + + @Override + protected void hookListeners(Listener updateListener) + { + storePathText.addListener(SWT.Modify, updateListener); + connectionKeepAlivePeriodText.addListener(SWT.Modify, updateListener); + readerPoolCapacityText.addListener(SWT.Modify, updateListener); + writerPoolCapacityText.addListener(SWT.Modify, updateListener); + } + + @Override + protected void updateEnablement(boolean firstTime) + { + boolean storePathOK = !StringUtil.isEmpty(text(storePathText)); + + if (firstTime) + { + setPageComplete(storePathOK); + return; + } + + if (!storePathOK) + { + setErrorMessage(Messages.CreateRepositoryStorePage_8); + setPageComplete(false); + return; + } + + // Don't need to worry about other properties the first time because they have defaults + + String keepAlive = text(connectionKeepAlivePeriodText); + String readerPool = text(readerPoolCapacityText); + String writerPool = text(writerPoolCapacityText); + + if (StringUtil.isEmpty(keepAlive)) + { + setErrorMessage(Messages.CreateRepositoryStorePage_9); + setPageComplete(false); + return; + } + + if (!positiveInteger(keepAlive)) + { + setErrorMessage(Messages.CreateRepositoryStorePage_10); + setPageComplete(false); + return; + } + + if (!StringUtil.isEmpty(readerPool) && !positiveInteger(readerPool)) + { + setErrorMessage(Messages.CreateRepositoryStorePage_11); + setPageComplete(false); + return; + } + + if (!StringUtil.isEmpty(writerPool) && !positiveInteger(writerPool)) + { + setErrorMessage(Messages.CreateRepositoryStorePage_12); + setPageComplete(false); + return; + } + + setErrorMessage(null); + setPageComplete(true); + } + + @Override + protected void loadSettings(IDialogSettings pageSettings) + { + connectionKeepAlivePeriodText.setText(getSetting(pageSettings, PROPERTY_CONNECTION_KEEP_ALIVE_PERIOD, + DEFAULT_CONNECTION_KEEP_ALIVE_PERIOD)); + readerPoolCapacityText + .setText(getSetting(pageSettings, PROPERTY_READER_POOL_CAPACITY, DEFAULT_READER_POOL_CAPACITY)); + writerPoolCapacityText + .setText(getSetting(pageSettings, PROPERTY_WRITER_POOL_CAPACITY, DEFAULT_WRITER_POOL_CAPACITY)); + } + + @Override + protected void saveSettings(IDialogSettings pageSettings) + { + pageSettings.put(PROPERTY_CONNECTION_KEEP_ALIVE_PERIOD, text(connectionKeepAlivePeriodText)); + pageSettings.put(PROPERTY_READER_POOL_CAPACITY, text(readerPoolCapacityText)); + pageSettings.put(PROPERTY_WRITER_POOL_CAPACITY, text(writerPoolCapacityText)); + } + + @Override + protected boolean collectRepositoryProperties(Map<String, Object> repositoryProperties) + { + repositoryProperties.put(CDOAdmin.PROPERTY_STORE_XML_CONFIG, createStoreXML(storeType)); + return true; + } + + protected String createStoreXML(StoreType storeType) + { + Map<String, Object> storeProperties = new java.util.HashMap<String, Object>(); + + storeProperties.put(PROPERTY_PATH, text(storePathText)); + storeProperties.put(PROPERTY_CONNECTION_KEEP_ALIVE_PERIOD, text(connectionKeepAlivePeriodText)); + storeProperties.put(PROPERTY_READER_POOL_CAPACITY, text(readerPoolCapacityText)); + storeProperties.put(PROPERTY_WRITER_POOL_CAPACITY, text(writerPoolCapacityText)); + + return storeType.getStoreXML(storeProperties); + } + +} diff --git a/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryWizard.java b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryWizard.java new file mode 100644 index 0000000000..589319c2cc --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui.admin/src/org/eclipse/emf/cdo/ui/internal/admin/wizards/CreateRepositoryWizard.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Christian W. Damus (CEA LIST) - initial API and implementation + */ +package org.eclipse.emf.cdo.ui.internal.admin.wizards; + +import org.eclipse.emf.cdo.ui.internal.admin.StoreType; +import org.eclipse.emf.cdo.ui.internal.admin.bundle.OM; +import org.eclipse.emf.cdo.ui.internal.admin.messages.Messages; +import org.eclipse.emf.cdo.ui.internal.admin.wizards.AbstractCreateRepositoryWizardPage.Whiteboard; + +import org.eclipse.jface.wizard.Wizard; + +import java.util.Map; + +/** + * @author Christian W. Damus (CEA LIST) + */ +public class CreateRepositoryWizard extends Wizard +{ + private CreateRepositoryGeneralPage generalPage; + + private CreateRepositoryStorePage storePage; + + private String repositoryName; + + private Map<String, Object> repositoryProperties; + + public CreateRepositoryWizard() + { + setWindowTitle(Messages.CreateRepositoryWizard_0); + setDefaultPageImageDescriptor(OM.getImageDescriptor("icons/full/wizban/new_repo.png")); //$NON-NLS-1$ + setDialogSettings(OM.Activator.INSTANCE.getDialogSettings(getClass())); + setHelpAvailable(false); + } + + @Override + public void addPages() + { + super.addPages(); + + final Whiteboard whiteboard = new Whiteboard(); + generalPage = new CreateRepositoryGeneralPage("general", StoreType.getInstances()); //$NON-NLS-1$ + generalPage.bind(whiteboard); + addPage(generalPage); + storePage = new CreateRepositoryStorePage("store"); //$NON-NLS-1$ + storePage.bind(whiteboard); + addPage(storePage); + } + + @Override + public boolean performFinish() + { + Map<String, Object> repositoryProperties = new java.util.HashMap<String, Object>(); + boolean result = generalPage.performFinish(repositoryProperties); + result = result && storePage.performFinish(repositoryProperties); + + if (result) + { + repositoryName = (String)repositoryProperties.remove(CreateRepositoryGeneralPage.PROPERTY_NAME); + this.repositoryProperties = repositoryProperties; + } + + return result; + } + + public String getRepositoryName() + { + return repositoryName; + } + + public Map<String, Object> getRepositoryProperties() + { + return repositoryProperties; + } + +} diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/UIActivator.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/UIActivator.java index e36b50215c..c92eda69d5 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/UIActivator.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/UIActivator.java @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - bug 418454 */ package org.eclipse.net4j.util.ui; @@ -15,6 +16,8 @@ import org.eclipse.net4j.util.om.OMBundle; import org.eclipse.net4j.util.om.OSGiActivator; import org.eclipse.net4j.util.om.OSGiActivator.StateHandler; +import org.eclipse.jface.dialogs.DialogSettings; +import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.plugin.AbstractUIPlugin; @@ -50,6 +53,22 @@ public class UIActivator extends AbstractUIPlugin return imageDescriptorFromPlugin(omBundle.getBundleID(), path); } + /** + * @since 3.4 + */ + public IDialogSettings getDialogSettings(Class<?> clazz) + { + return getDialogSettings(clazz.getName()); + } + + /** + * @since 3.4 + */ + public IDialogSettings getDialogSettings(String section) + { + return DialogSettings.getOrCreateSection(getDialogSettings(), section); + } + @Override public final void start(BundleContext context) throws Exception { diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/UIUtil.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/UIUtil.java index 69de2b690b..4ce619ecd2 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/UIUtil.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/UIUtil.java @@ -8,6 +8,7 @@ * Contributors: * Eike Stepper - initial API and implementation * Victor Roldan Betancort - maintenance + * Christian W. Damus (CEA LIST) - bug 418454 */ package org.eclipse.net4j.util.ui; @@ -338,6 +339,17 @@ public final class UIUtil } /** + * @since 3.4 + */ + public static GridData createGridData(int horizontalSpan, int verticalSpan) + { + GridData result = new GridData(); + result.horizontalSpan = horizontalSpan; + result.verticalSpan = verticalSpan; + return result; + } + + /** * @since 3.0 */ public static GridData createEmptyGridData() diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java index 448c68edcd..4bfca63d10 100644 --- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java +++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/io/IOUtil.java @@ -7,6 +7,7 @@ * * Contributors: * Eike Stepper - initial API and implementation + * Christian W. Damus (CEA LIST) - bug 418454 */ package org.eclipse.net4j.util.io; @@ -32,10 +33,14 @@ import java.io.FileWriter; import java.io.Flushable; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.io.Reader; import java.io.Writer; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -633,6 +638,54 @@ public final class IOUtil } /** + * @since 3.4 + */ + public static String readText(URL url) throws IORuntimeException + { + Reader input = null; + + try + { + URLConnection connection = url.openConnection(); + connection.setDoInput(true); + connection.setUseCaches(true); + connection.connect(); + + Charset charset; + String encoding = connection.getContentEncoding(); + if (encoding == null) + { + charset = Charset.defaultCharset(); + } + else + { + charset = Charset.forName(encoding); + } + + input = new InputStreamReader(connection.getInputStream(), charset); + } + catch (IOException ex) + { + throw new IORuntimeException(ex); + } + + try + { + CharArrayWriter output = new CharArrayWriter(); + copyCharacter(input, output); + return output.toString(); + } + catch (IOException ex) + { + throw new IORuntimeException(ex); + } + finally + { + closeSilent(input); + } + } + + /** * @since 3.1 */ public static String readTextFile(File file) throws IORuntimeException |