diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java index 7bd6a13610a7a8574f4aa683b4fb0ec3fd6c25a0..f32262e11da25ef650d363635c418282e45b9432 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java @@ -318,17 +318,20 @@ public interface ICommonClientService extends IClientService * Registers given {@link Vocabulary}. */ public void registerVocabulary(final Vocabulary vocabulary) throws UserFailureException; - - /** Adds specified terms to the specified vocabulary. */ + + /** Adds specified terms to the specified vocabulary. */ public void addVocabularyTerms(String vocabularyCode, List<String> vocabularyTerms) throws UserFailureException; - + /** - * Deletes the specified terms of the specified vocabulary. Terms in use will be replaced. + * Deletes the specified terms of the specified vocabulary. Terms in use will be replaced. */ public void deleteVocabularyTerms(String vocabularyCode, List<VocabularyTerm> termsToBeDeleted, List<VocabularyTermReplacement> termsToBeReplaced) throws UserFailureException; - + + /** Lists terms of a specified vocabulary */ + public List<VocabularyTerm> listVocabularyTerms(Vocabulary vocabulary); + /** * Registers given {@link Project}. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java index a3267b5828d39ceea03de44d4e60fad01da32924..d5292bc55bea3e70739cfa85c8edd37810b82833 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java @@ -283,7 +283,11 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync /** @see ICommonClientService#deleteVocabularyTerms(String, List, List) */ public void deleteVocabularyTerms(String vocabularyCode, List<VocabularyTerm> termsToBeDeleted, List<VocabularyTermReplacement> termsToBeReplaced, AsyncCallback<Void> callback); - + + /** @see ICommonClientService#listVocabularyTerms(Vocabulary) */ + public void listVocabularyTerms(Vocabulary vocabulary, + AsyncCallback<List<VocabularyTerm>> callback); + /** @see ICommonClientService#registerProject(Project) */ public void registerProject(Project project, final AsyncCallback<Void> projectRegistrationCallback); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchableEntitySelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchableEntitySelectionWidget.java index a7f41029eb1bf5ab98ba7fd29e37f5c15b9223e0..335300df7e1299d73718b4106694b7745a543a2e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchableEntitySelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchableEntitySelectionWidget.java @@ -26,6 +26,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.Mode import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.SearchableEntityModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SearchableEntity; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; /** * A {@link ComboBox} extension for searching entities. @@ -88,4 +89,8 @@ final class SearchableEntitySelectionWidget extends .listSearchableEntities(new ListSearchableEntities(commonContext)); } + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.EMPTY_ARRAY; + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java index 7bb8aa3e13081e7499f44305c510877fc919dc8e..7d7cbb91cf8940d08a1121ce205439a1e023c8ad 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java @@ -73,6 +73,13 @@ public final class ComponentProvider return DefaultTabItem.create(title, component, viewContext); } + // creates a tab which requires confirmation before it can be closed + private ITabItem createRegistrationTab(final String titleMessageKey, + DatabaseModificationAwareComponent component) + { + return DefaultTabItem.create(getMessage(titleMessageKey), component, viewContext, true); + } + // TODO 2009-03-26, Tomasz Pylak: add db modification observer support private ITabItem createTab(String dictionaryMsgKey, Component component, boolean isCloseConfirmationNeeded) @@ -186,8 +193,9 @@ public final class ComponentProvider { public ITabItem create() { - Component component = new SampleRegistrationPanel(viewContext); - return createTab(Dict.SAMPLE_REGISTRATION, component, true); + DatabaseModificationAwareComponent component = + SampleRegistrationPanel.create(viewContext); + return createRegistrationTab(Dict.SAMPLE_REGISTRATION, component); } public String getId() @@ -203,8 +211,9 @@ public final class ComponentProvider { public ITabItem create() { - Component component = new ExperimentRegistrationPanel(viewContext); - return createTab(Dict.EXPERIMENT_REGISTRATION, component, true); + DatabaseModificationAwareComponent component = + ExperimentRegistrationPanel.create(viewContext); + return createRegistrationTab(Dict.EXPERIMENT_REGISTRATION, component); } public String getId() @@ -414,8 +423,9 @@ public final class ComponentProvider { public ITabItem create() { - Component component = new PropertyTypeAssignmentForm(viewContext, entityKind); - return new DefaultTabItem(getMessage(messageKey), component, true); + DatabaseModificationAwareComponent component = + PropertyTypeAssignmentForm.create(viewContext, entityKind); + return createRegistrationTab(messageKey, component); } public String getId() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/CompositeDatabaseModificationObserver.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/CompositeDatabaseModificationObserver.java new file mode 100644 index 0000000000000000000000000000000000000000..1a49ee4b543437c1c42d14d929d2f9f5d5d93d67 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/CompositeDatabaseModificationObserver.java @@ -0,0 +1,77 @@ +/* + * Copyright 2009 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.client.web.client.application.framework; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.SetUtils; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; + +/** + * Composite class to implement {@link IDatabaseModificationObserver} interface for a collection of + * observers. + * + * @author Tomasz Pylak + */ +public class CompositeDatabaseModificationObserver implements IDatabaseModificationObserver +{ + private final List<IDatabaseModificationObserver> registeredObservers; + + public CompositeDatabaseModificationObserver() + { + this.registeredObservers = new ArrayList<IDatabaseModificationObserver>(); + } + + public void addObservers(List<? extends IDatabaseModificationObserver> observers) + { + for (IDatabaseModificationObserver observer : observers) + { + addObserver(observer); + } + } + + public void addObserver(IDatabaseModificationObserver observer) + { + registeredObservers.add(observer); + } + + public DatabaseModificationKind[] getRelevantModifications() + { + List<DatabaseModificationKind> relevantModifications = + new ArrayList<DatabaseModificationKind>(); + for (IDatabaseModificationObserver observer : registeredObservers) + { + SetUtils.addAll(relevantModifications, observer.getRelevantModifications()); + } + return relevantModifications.toArray(DatabaseModificationKind.EMPTY_ARRAY); + } + + public void update(Set<DatabaseModificationKind> observedModifications) + { + for (IDatabaseModificationObserver observer : registeredObservers) + { + if (SetUtils.containsAny(observedModifications, observer.getRelevantModifications())) + { + observer.update(observedModifications); + } + } + + } + +} \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareComponent.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareComponent.java new file mode 100644 index 0000000000000000000000000000000000000000..c394d116f2d722a8f93b6b666026e54b5b25b075 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareComponent.java @@ -0,0 +1,34 @@ +/* + * Copyright 2009 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.client.web.client.application.framework; + +import com.extjs.gxt.ui.client.widget.Component; + +/** + * Component which is aware of database modifications. + * + * @author Tomasz Pylak + */ +public class DatabaseModificationAwareComponent extends DatabaseModificationAwareObject<Component> +{ + public DatabaseModificationAwareComponent(Component holder, + IDatabaseModificationObserver modificationObserver) + { + super(holder, modificationObserver); + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareField.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareField.java new file mode 100644 index 0000000000000000000000000000000000000000..87ad8a99aef331d4aa10fda04c2b7b384c1f8f5c --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareField.java @@ -0,0 +1,43 @@ +/* + * Copyright 2009 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.client.web.client.application.framework; + +import com.extjs.gxt.ui.client.widget.form.Field; + +/** + * A field which is aware of database modifications. + * + * @author Tomasz Pylak + */ +public class DatabaseModificationAwareField<T> extends DatabaseModificationAwareObject<Field<T>> +{ + /** + * Creates a mock with a dummy database modification observer. Use this method if your field + * does not need to be refreshed when the database changes. + */ + public static <T> DatabaseModificationAwareField<T> wrapUnaware(Field<T> field) + { + return new DatabaseModificationAwareField<T>(field, createDummyModificationObserver()); + } + + public DatabaseModificationAwareField(Field<T> holder, + IDatabaseModificationObserver modificationObserver) + { + super(holder, modificationObserver); + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareObject.java new file mode 100644 index 0000000000000000000000000000000000000000..4977e7640545f9e5301936cceea37a215464db19 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareObject.java @@ -0,0 +1,85 @@ +/* + * Copyright 2009 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.client.web.client.application.framework; + +import java.util.Set; + +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; + +/** + * Stores an object and its database modification observer. + * <p> + * This class is useful when you cannot modify some class T to extend + * {@link IDatabaseModificationObserver} interface (because e.g. this class comes from a library). + * </p> + * + * @author Tomasz Pylak + */ +public class DatabaseModificationAwareObject<T> implements IDatabaseModificationObserver +{ + private final T object; + + private final IDatabaseModificationObserver modificationObserver; + + public static <T> DatabaseModificationAwareObject<T> createUnaware(T object) + { + IDatabaseModificationObserver dummyObserver = createDummyModificationObserver(); + return new DatabaseModificationAwareObject<T>(object, dummyObserver); + } + + protected static IDatabaseModificationObserver createDummyModificationObserver() + { + return new IDatabaseModificationObserver() + { + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.EMPTY_ARRAY; + } + + public void update(Set<DatabaseModificationKind> observedModifications) + { + // do nothing + } + + }; + } + + public DatabaseModificationAwareObject(T holder, + IDatabaseModificationObserver modificationObserver) + { + this.object = holder; + this.modificationObserver = modificationObserver; + } + + public DatabaseModificationKind[] getRelevantModifications() + { + return modificationObserver.getRelevantModifications(); + } + + public void update(Set<DatabaseModificationKind> observedModifications) + { + modificationObserver.update(observedModifications); + } + + /** @return the stored object */ + public T get() + { + return object; + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareWidget.java new file mode 100644 index 0000000000000000000000000000000000000000..c8bec91ac2a95f70e7535077c2bdebbd251aecf7 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DatabaseModificationAwareWidget.java @@ -0,0 +1,43 @@ +/* + * Copyright 2009 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.client.web.client.application.framework; + +import com.google.gwt.user.client.ui.Widget; + +/** + * Widget which is aware of database modifications. + * + * @author Tomasz Pylak + */ +public class DatabaseModificationAwareWidget extends DatabaseModificationAwareObject<Widget> +{ + /** + * Creates a mock with a dummy database modification observer. Use this method if your field + * does not need to be refreshed when the database changes. + */ + public static DatabaseModificationAwareWidget wrapUnaware(Widget widget) + { + return new DatabaseModificationAwareWidget(widget, createDummyModificationObserver()); + } + + public DatabaseModificationAwareWidget(Widget holder, + IDatabaseModificationObserver modificationObserver) + { + super(holder, modificationObserver); + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DefaultTabItem.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DefaultTabItem.java index 37e36fa5fcf37b7c34b96d6f7e41a39207426e3f..9d1d7eb798a17352b6ce27ad8c904169884148c0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DefaultTabItem.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/DefaultTabItem.java @@ -16,7 +16,6 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.framework; - import com.extjs.gxt.ui.client.widget.Component; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; @@ -47,17 +46,34 @@ public class DefaultTabItem implements ITabItem this(title, component, null, null, isCloseConfirmationNeeded); } + public static ITabItem create(final String title, + final DatabaseModificationAwareComponent component, IViewContext<?> viewContext, + boolean isCloseConfirmationNeeded) + { + return create(title, component.get(), viewContext, component, null, + isCloseConfirmationNeeded); + } + public static ITabItem create(final String title, final DisposableComponent component, IViewContext<?> viewContext) { boolean isCloseConfirmationNeeded = false; - LastModificationStateUpdater updater = - new LastModificationStateUpdater(viewContext, component); IDelegatedAction disposer = createDisposer(component); - return new DefaultTabItem(title, component.getComponent(), updater, disposer, + return create(title, component.getComponent(), viewContext, component, disposer, isCloseConfirmationNeeded); } + private static DefaultTabItem create(final String title, final Component component, + IViewContext<?> viewContext, IDatabaseModificationObserver modificationObserver, + IDelegatedAction disposerActionOrNull, boolean isCloseConfirmationNeeded) + { + LastModificationStateUpdater updater = + new LastModificationStateUpdater(viewContext, modificationObserver); + return new DefaultTabItem(title, component, updater, disposerActionOrNull, + isCloseConfirmationNeeded); + + } + private static IDelegatedAction createDisposer(final DisposableComponent disposableComponent) { return new IDelegatedAction() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/IDatabaseModificationObserver.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/IDatabaseModificationObserver.java index d8a97a94ca680f05377be0140825c6c5f8a39261..e1a5af9fd35ebac07a21e51934946a0ea499d500 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/IDatabaseModificationObserver.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/IDatabaseModificationObserver.java @@ -26,10 +26,10 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKin public interface IDatabaseModificationObserver { /** - * Informs about new modifications in the database. + * Informs about new modifications in the database. This method is called only if at least one + * observed modification is the relevant one. * - * @param observedModifications The new database modifications which have occurred. This is a - * subset of the modifications in which this observer is interested. + * @param observedModifications The new database modifications which have occurred. */ void update(Set<DatabaseModificationKind> observedModifications); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/ClientPluginAdapter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/ClientPluginAdapter.java index f6a6d16f4020a3b9fa8ee2e85c0c20ec493b7f15..53e666943d8543bb814d4a90dbc81eaa19018ae5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/ClientPluginAdapter.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/ClientPluginAdapter.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin; import com.google.gwt.user.client.ui.Widget; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.ITabItemFactory; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.IEditableEntity; import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder; @@ -49,7 +50,7 @@ public class ClientPluginAdapter<E extends EntityType, S extends EntityTypePrope throw new UnsupportedOperationException("Not yet implemented."); } - public Widget createRegistrationForEntityType(final E entityType) + public DatabaseModificationAwareWidget createRegistrationForEntityType(final E entityType) { throw new UnsupportedOperationException("Not yet implemented."); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/IClientPlugin.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/IClientPlugin.java index 8e805c69d80f7d686d5bda6a02686d263561f05b..d98a21b75ee0ca3cbbacab7260714c25a5239bd3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/IClientPlugin.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/plugin/IClientPlugin.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin; import com.google.gwt.user.client.ui.Widget; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.ITabItemFactory; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.IEditableEntity; import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder; @@ -47,7 +48,7 @@ public interface IClientPlugin<T extends EntityType, S extends EntityTypePropert /** * Shows a registration form for entities of given <var>entityType</var>. */ - public Widget createRegistrationForEntityType(final T entityType); + public DatabaseModificationAwareWidget createRegistrationForEntityType(final T entityType); /** * Shows a batch registration form for entities of given <var>entityType</var>. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/GroupSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/GroupSelectionWidget.java index 11eb52b5fd7b5a9aa36b03c45c28aa195e1da405..143a5912a43d2e80838f2415e449c8ea32a49cb4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/GroupSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/GroupSelectionWidget.java @@ -31,6 +31,8 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample. import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SessionContext; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.User; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * {@link ComboBox} containing list of groups loaded from the server. @@ -145,6 +147,10 @@ public final class GroupSelectionWidget extends DropDownList<GroupModel, Group> protected void loadData(AbstractAsyncCallback<List<Group>> callback) { viewContext.getCommonService().listGroups(null, new ListGroupsCallback(viewContext)); - + } + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.GROUP); } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetSearchFieldsSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetSearchFieldsSelectionWidget.java index ac6f4de5f05e9e1adbd33fe5c2c7e11cd70fabdc..5eae8a05bf997f02f10b9f589c0926b0894d5cca 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetSearchFieldsSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetSearchFieldsSelectionWidget.java @@ -20,6 +20,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.extjs.gxt.ui.client.store.ListStore; +import com.extjs.gxt.ui.client.widget.form.ComboBox; + import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; @@ -32,11 +35,10 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetCo import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchField; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchFieldKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; - -import com.extjs.gxt.ui.client.store.ListStore; -import com.extjs.gxt.ui.client.widget.form.ComboBox; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * {@link ComboBox} containing list of search fields loaded from the server (property types) and @@ -306,4 +308,9 @@ public final class DataSetSearchFieldsSelectionWidget extends new ListPropertyTypesCallback(viewContext)); } } + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.PROPERTY_TYPE); + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetTypeSelectionWidget.java index 53cafc3c3b265a817996f6e1ec4347baef30b703..8fae71ae861e32ac14600e2e85c86382d527acd0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetTypeSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetTypeSelectionWidget.java @@ -18,6 +18,8 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data; import java.util.List; +import com.extjs.gxt.ui.client.widget.form.ComboBox; + import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; @@ -26,44 +28,52 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.Data import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; - -import com.extjs.gxt.ui.client.widget.form.ComboBox; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * {@link ComboBox} containing list of data set types loaded from the server. * * @author Izabela Adamczyk */ -public final class DataSetTypeSelectionWidget extends - DropDownList<DataSetTypeModel, DataSetType> { - public static final String SUFFIX = "data-set-type"; +public final class DataSetTypeSelectionWidget extends DropDownList<DataSetTypeModel, DataSetType> +{ + public static final String SUFFIX = "data-set-type"; + + private final IViewContext<ICommonClientServiceAsync> viewContext; - private final IViewContext<ICommonClientServiceAsync> viewContext; + public DataSetTypeSelectionWidget(final IViewContext<ICommonClientServiceAsync> viewContext, + final String idSuffix) + { + super(viewContext, SUFFIX + idSuffix, Dict.DATA_SET_TYPE, ModelDataPropertyNames.CODE, + "data set type", "data set types"); + this.viewContext = viewContext; + } - public DataSetTypeSelectionWidget( - final IViewContext<ICommonClientServiceAsync> viewContext, - final String idSuffix) { - super(viewContext, SUFFIX + idSuffix, Dict.DATA_SET_TYPE, - ModelDataPropertyNames.CODE, "data set type", "data set types"); - this.viewContext = viewContext; - } + /** + * Returns the {@link DataSetType} currently selected. + * + * @return <code>null</code> if nothing is selected yet. + */ + public final DataSetType tryGetSelectedDataSetType() + { + return super.tryGetSelected(); + } - /** - * Returns the {@link DataSetType} currently selected. - * - * @return <code>null</code> if nothing is selected yet. - */ - public final DataSetType tryGetSelectedDataSetType() { - return super.tryGetSelected(); - } + @Override + protected List<DataSetTypeModel> convertItems(List<DataSetType> result) + { + return DataSetTypeModel.convert(result); + } - @Override - protected List<DataSetTypeModel> convertItems(List<DataSetType> result) { - return DataSetTypeModel.convert(result); - } + @Override + protected void loadData(AbstractAsyncCallback<List<DataSetType>> callback) + { + viewContext.getService().listDataSetTypes(callback); + } - @Override - protected void loadData(AbstractAsyncCallback<List<DataSetType>> callback) { - viewContext.getService().listDataSetTypes(callback); - } + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.DATASET_TYPE); + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java index b4cfcbea9a298fa6943efcfbaef73a7e8ecb5d7d..7ae930dbfb88ca4a391777b3e9d40b2bb22b6f38 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java @@ -19,7 +19,10 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experi import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.createOrDelete; import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.edit; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.widget.LayoutContainer; @@ -44,6 +47,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractBrowserGrid; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ColumnDefsAndConfigs; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.DisposableEntityChooser; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.SetUtils; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group; @@ -261,11 +265,30 @@ public class ExperimentBrowserGrid extends AbstractBrowserGrid<Experiment, Exper public DatabaseModificationKind[] getRelevantModifications() { - return new DatabaseModificationKind[] - { createOrDelete(ObjectKind.EXPERIMENT_TYPE), createOrDelete(ObjectKind.PROJECT), - createOrDelete(ObjectKind.SAMPLE), createOrDelete(ObjectKind.EXPERIMENT), - createOrDelete(ObjectKind.DATA_SET), edit(ObjectKind.SAMPLE), - edit(ObjectKind.EXPERIMENT), edit(ObjectKind.DATA_SET), - createOrDelete(ObjectKind.PROPERTY_TYPE_ASSIGNMENT) }; + List<DatabaseModificationKind> relevantModifications = + new ArrayList<DatabaseModificationKind>(); + SetUtils.addAll(relevantModifications, topToolbar.getRelevantModifications()); + relevantModifications.addAll(getGridRelevantModifications()); + return relevantModifications.toArray(DatabaseModificationKind.EMPTY_ARRAY); } + + private static Set<DatabaseModificationKind> getGridRelevantModifications() + { + Set<DatabaseModificationKind> result = new HashSet<DatabaseModificationKind>(); + result.add(createOrDelete(ObjectKind.EXPERIMENT)); + result.add(edit(ObjectKind.EXPERIMENT)); + result.add(createOrDelete(ObjectKind.PROPERTY_TYPE_ASSIGNMENT)); + return result; + } + + @Override + public void update(Set<DatabaseModificationKind> observedModifications) + { + topToolbar.update(observedModifications); + if (SetUtils.containsAny(observedModifications, getGridRelevantModifications())) + { + refreshGridSilently(); + } + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java index 64e3003d3aebbf5cc60552ae1ed8dd58020c137c..14640f93fc4a2a88066ea42266135a5c3cb7d527 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java @@ -16,6 +16,10 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment; +import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.createOrDelete; + +import java.util.Set; + import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem; import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem; @@ -27,10 +31,13 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCriteria; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Project; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * The toolbar of experiment browser. @@ -38,7 +45,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; * @author Izabela Adamczyk * @author Christian Ribeaud */ -class ExperimentBrowserToolbar extends ToolBar +class ExperimentBrowserToolbar extends ToolBar implements IDatabaseModificationObserver { public static final String ID = "experiment-browser-toolbar"; @@ -102,4 +109,21 @@ class ExperimentBrowserToolbar extends ToolBar super.onRender(parent, pos); } + public DatabaseModificationKind[] getRelevantModifications() + { + return new DatabaseModificationKind[] + { createOrDelete(ObjectKind.EXPERIMENT_TYPE), createOrDelete(ObjectKind.PROJECT) }; + } + + public void update(Set<DatabaseModificationKind> observedModifications) + { + if (observedModifications.contains(createOrDelete(ObjectKind.EXPERIMENT_TYPE))) + { + selectExperimentTypeCombo.refreshStore(); + } + if (observedModifications.contains(createOrDelete(ObjectKind.PROJECT))) + { + selectProjectCombo.refreshStore(); + } + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentRegistrationPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentRegistrationPanel.java index e214230804e9f5a6870c4f49d91bf8dfc86bf68e..8e6a77d898f5ac0d5d86a701fa897b2935869af5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentRegistrationPanel.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentRegistrationPanel.java @@ -1,22 +1,23 @@ /* -* Copyright 2008 ETH Zuerich, CISD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment; import ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ExperimentTypeModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.EntityRegistrationPanel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; @@ -32,10 +33,16 @@ public final class ExperimentRegistrationPanel extends public static final String ID = EntityRegistrationPanel.createId(EntityKind.EXPERIMENT); - public ExperimentRegistrationPanel(final CommonViewContext viewContext) + public static final DatabaseModificationAwareComponent create( + final CommonViewContext viewContext) + { + ExperimentRegistrationPanel panel = new ExperimentRegistrationPanel(viewContext); + return new DatabaseModificationAwareComponent(panel, panel); + } + + private ExperimentRegistrationPanel(final CommonViewContext viewContext) { super(viewContext, EntityKind.EXPERIMENT, new ExperimentTypeSelectionWidget(viewContext, EntityRegistrationPanel.createId(EntityKind.EXPERIMENT))); } - } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentTypeSelectionWidget.java index 0c400efa275824481d5f7e2b7ff15a67ddbba941..723f34ee7ccbaa8164c6dbd68a77b2ec01711864 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentTypeSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentTypeSelectionWidget.java @@ -27,7 +27,9 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ExperimentTypeModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * {@link ComboBox} containing list of experiment types loaded from the server. @@ -70,4 +72,9 @@ public final class ExperimentTypeSelectionWidget extends { viewContext.getService().listExperimentTypes(callback); } + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.EXPERIMENT_TYPE); + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ProjectSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ProjectSelectionWidget.java index 1174e8c7dbd1a05d51433670336be6389f388ef6..4867610bb701fcbeea34aa624b4c80a7af4a36e0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ProjectSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ProjectSelectionWidget.java @@ -34,6 +34,8 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetCo import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Project; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * {@link ComboBox} containing list of projects loaded from the server. @@ -187,4 +189,10 @@ public final class ProjectSelectionWidget extends GWTUtils .setSelectedItem(this, ModelDataPropertyNames.PROJECT_IDENTIFIER, projectIdentifier); } + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.PROJECT); + } + } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/PropertyFieldFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/PropertyFieldFactory.java index 76acff7e1e9185e6e59dcdcd9163d4d8606b2a14..ca34e6faef2239c04c3d4f1d226317cf0b0559cf 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/PropertyFieldFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/PropertyFieldFactory.java @@ -22,6 +22,7 @@ import com.extjs.gxt.ui.client.widget.form.Field; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.VocabularyTermModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.DateRenderer; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; @@ -32,47 +33,53 @@ public class PropertyFieldFactory /** * Creates a field for given data type. */ - public static Field<?> createField(final PropertyType pt, boolean isMandatory, String label, - String fieldId, String originalRawValue, + public static DatabaseModificationAwareField<?> createField(final PropertyType pt, + boolean isMandatory, String label, String fieldId, String originalRawValue, IViewContext<ICommonClientServiceAsync> viewContext) { - final Field<?> field = + final DatabaseModificationAwareField<?> fieldHolder = doCreateField(pt, isMandatory, label, fieldId, originalRawValue, viewContext); + Field<?> field = fieldHolder.get(); field.setId(fieldId); if (originalRawValue != null) { setValue(field, originalRawValue); } - return field; + return fieldHolder; } - private static Field<?> doCreateField(final PropertyType pt, boolean isMandatory, String label, - String fieldId, String originalRawValue, + private static DatabaseModificationAwareField<?> doCreateField(final PropertyType pt, + boolean isMandatory, String label, String fieldId, String originalRawValue, IViewContext<ICommonClientServiceAsync> viewContext) { final DataTypeCode dataType = pt.getDataType().getCode(); switch (dataType) { case BOOLEAN: - return new CheckBoxField(label, isMandatory); + return wrapUnaware(new CheckBoxField(label, isMandatory)); case VARCHAR: - return new VarcharField(label, isMandatory); + return wrapUnaware(new VarcharField(label, isMandatory)); case TIMESTAMP: - return new DateFormField(label, isMandatory); + return wrapUnaware(new DateFormField(label, isMandatory)); case CONTROLLEDVOCABULARY: - return new VocabularyTermSelectionWidget(fieldId, label, pt.getVocabulary() - .getTerms(), isMandatory); + return VocabularyTermSelectionWidget.create(fieldId, label, pt.getVocabulary(), + isMandatory, viewContext); case INTEGER: - return new IntegerField(label, isMandatory); + return wrapUnaware(new IntegerField(label, isMandatory)); case REAL: - return new RealField(label, isMandatory); + return wrapUnaware(new RealField(label, isMandatory)); case MATERIAL: - return MaterialChooserField.create(label, isMandatory, pt.getMaterialType(), - originalRawValue, viewContext); + return wrapUnaware(MaterialChooserField.create(label, isMandatory, pt + .getMaterialType(), originalRawValue, viewContext)); } throw new IllegalStateException("unknown enum " + dataType); } + private static DatabaseModificationAwareField<?> wrapUnaware(Field<?> field) + { + return DatabaseModificationAwareField.wrapUnaware(field); + } + private static <T> void setValue(final Field<T> field, String originalRawValue) { field.setValue(field.getPropertyEditor().convertStringValue(originalRawValue)); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/VocabularyTermSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/VocabularyTermSelectionWidget.java index 53c4607863377e08792e47db4811cd19b96403a8..da434ade147f35c712625863d89ab2c7687de634 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/VocabularyTermSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/VocabularyTermSelectionWidget.java @@ -19,17 +19,24 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field; import java.util.ArrayList; import java.util.List; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.VocabularyTermModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SimpleDropDownList; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * @author Izabela Adamczyk */ -public class VocabularyTermSelectionWidget extends SimpleDropDownList<VocabularyTermModel, String> +public class VocabularyTermSelectionWidget extends + SimpleDropDownList<VocabularyTermModel, VocabularyTerm> { private static final String CHOOSE_MSG = "Choose..."; @@ -38,18 +45,80 @@ public class VocabularyTermSelectionWidget extends SimpleDropDownList<Vocabulary private static final String EMPTY_MSG = "- No terms found -"; + private final Vocabulary vocabularyOrNull; + + private final IViewContext<?> viewContextOrNull; + + /** + * Allows to choose one of the specified vocabulary's terms, is able to refresh the available + * terms by calling the server. + */ + public static DatabaseModificationAwareField<VocabularyTermModel> create(String idSuffix, + String label, Vocabulary vocabulary, final boolean mandatory, + IViewContext<?> viewContext) + { + return new VocabularyTermSelectionWidget(idSuffix, label, vocabulary.getTerms(), mandatory, + vocabulary, viewContext).asDatabaseModificationAware(); + } + + /** + * Allows to choose one of the specified vocabulary terms. + */ public VocabularyTermSelectionWidget(String idSuffix, String label, List<VocabularyTerm> terms, final boolean mandatory) + { + this(idSuffix, label, terms, mandatory, null, null); + } + + private VocabularyTermSelectionWidget(String idSuffix, String label, + List<VocabularyTerm> terms, boolean mandatory, Vocabulary vocabularyOrNull, + IViewContext<?> viewContextOrNull) { super(idSuffix, ModelDataPropertyNames.CODE, label, CHOOSE_MSG, EMPTY_MSG, VALUE_NOT_IN_LIST_MSG, mandatory); + this.viewContextOrNull = viewContextOrNull; + this.vocabularyOrNull = vocabularyOrNull; + FieldUtil.setMandatoryFlag(this, mandatory); setAllowBlank(mandatory == false); + setTerms(terms); + } + + private void setTerms(List<VocabularyTerm> terms) + { final List<VocabularyTermModel> models = new ArrayList<VocabularyTermModel>(); models.add(new VocabularyTermModel(GWTUtils.NONE_LIST_ITEM)); - models.addAll(VocabularyTermModel.convert(terms)); + models.addAll(convertItems(terms)); updateStore(models); getPropertyEditor().setList(store.getModels()); } + @Override + public void refreshStore() + { + if (viewContextOrNull != null) + { + refreshStore(viewContextOrNull); + } + } + + @Override + protected List<VocabularyTermModel> convertItems(List<VocabularyTerm> result) + { + return VocabularyTermModel.convert(result); + } + + @Override + protected void loadData(AbstractAsyncCallback<List<VocabularyTerm>> callback) + { + if (viewContextOrNull != null && vocabularyOrNull != null) + { + viewContextOrNull.getCommonService().listVocabularyTerms(vocabularyOrNull, callback); + } + } + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.VOCABULARY_TERM); + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java index 15dce9c941d055e2d6384b0cead7796fb8119d21..b95c19434cefa7cdc722d5738f8edb3d49301373 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java @@ -211,7 +211,13 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod // !!!!!!!!!!!!!!!!!!!!!!!!! public void update(Set<DatabaseModificationKind> observedModifications) { - System.out.println("grid refresh requested: " + observedModifications); + System.out.println("generic grid refresh requested: " + observedModifications); + refreshGridSilently(); + } + + /** Refreshes the grid without showing the loading progress bar */ + protected void refreshGridSilently() + { grid.setLoadMask(false); refresh(); grid.setLoadMask(true); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialRegistrationPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialRegistrationPanel.java deleted file mode 100644 index 0aff0510697c05b274af9ed308fb954fd0a32e2f..0000000000000000000000000000000000000000 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialRegistrationPanel.java +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Copyright 2008 ETH Zuerich, CISD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material; - -import ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.MaterialTypeModel; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.EntityRegistrationPanel; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; - -/** - * The {@link EntityRegistrationPanel} extension for registering an material. - * - * @author Izabela Adamczyk - */ -public final class MaterialRegistrationPanel extends - EntityRegistrationPanel<MaterialTypeModel, MaterialTypeSelectionWidget> -{ - - public static final String ID = EntityRegistrationPanel.createId(EntityKind.MATERIAL); - - public MaterialRegistrationPanel(final CommonViewContext viewContext) - { - super(viewContext, EntityKind.MATERIAL, new MaterialTypeSelectionWidget(viewContext, - EntityRegistrationPanel.createId(EntityKind.MATERIAL))); - } - -} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java index 48fb6e3ac9af929792d49c78c28747f885779aff..ad50c16ed5174c24b621a449adfa1055af9f2ac5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java @@ -27,7 +27,9 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.MaterialTypeModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * {@link ComboBox} containing list of material types loaded from the server. @@ -122,4 +124,9 @@ public final class MaterialTypeSelectionWidget extends { viewContext.getService().listMaterialTypes(callback); } + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.MATERIAL_TYPE); + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/DataTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/DataTypeSelectionWidget.java index a089b1f87ed69928a5394a874a7f386de8e424a7..e4459dbb61c2772c9af777965f305f4c569a9ad4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/DataTypeSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/DataTypeSelectionWidget.java @@ -30,6 +30,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.Mode import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; /** * A {@link ComboBox} extension for selecting a {@link DataType}. @@ -102,4 +103,9 @@ public final class DataTypeSelectionWidget extends DropDownList<DataTypeModel, D { viewContext.getService().listDataTypes(new ListDataTypesCallback(viewContext)); } + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.EMPTY_ARRAY; + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeAssignmentForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeAssignmentForm.java index 477b7f569bd0a4164a477ca4dc79cb90a3287336..e496eab18e6e8ad50dbf496282b799e0d04cb321 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeAssignmentForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeAssignmentForm.java @@ -16,322 +16,375 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type; +import java.util.Set; + +import com.extjs.gxt.ui.client.Events; +import com.extjs.gxt.ui.client.Style.HorizontalAlignment; +import com.extjs.gxt.ui.client.Style.Scroll; +import com.extjs.gxt.ui.client.event.BaseEvent; +import com.extjs.gxt.ui.client.event.ButtonEvent; +import com.extjs.gxt.ui.client.event.Listener; +import com.extjs.gxt.ui.client.event.SelectionListener; +import com.extjs.gxt.ui.client.widget.LayoutContainer; +import com.extjs.gxt.ui.client.widget.button.Button; +import com.extjs.gxt.ui.client.widget.form.CheckBox; +import com.extjs.gxt.ui.client.widget.form.Field; +import com.extjs.gxt.ui.client.widget.form.FormPanel; +import com.extjs.gxt.ui.client.widget.layout.FlowLayout; +import com.google.gwt.user.client.Element; + import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCallbackListener; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.CompositeDatabaseModificationObserver; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm.InfoBoxResetListener; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.DataSetTypeSelectionWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.ExperimentTypeSelectionWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.PropertyFieldFactory; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.MaterialTypeSelectionWidget; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleTypeSelectionWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.InfoBox; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; -import com.extjs.gxt.ui.client.Events; -import com.extjs.gxt.ui.client.Style.HorizontalAlignment; -import com.extjs.gxt.ui.client.Style.Scroll; -import com.extjs.gxt.ui.client.event.BaseEvent; -import com.extjs.gxt.ui.client.event.ButtonEvent; -import com.extjs.gxt.ui.client.event.Listener; -import com.extjs.gxt.ui.client.event.SelectionListener; -import com.extjs.gxt.ui.client.widget.LayoutContainer; -import com.extjs.gxt.ui.client.widget.button.Button; -import com.extjs.gxt.ui.client.widget.form.CheckBox; -import com.extjs.gxt.ui.client.widget.form.ComboBox; -import com.extjs.gxt.ui.client.widget.form.Field; -import com.extjs.gxt.ui.client.widget.form.FormPanel; -import com.extjs.gxt.ui.client.widget.layout.FlowLayout; -import com.google.gwt.user.client.Element; - /** * The property type assignment panel. * * @author Izabela Adamczyk */ -public final class PropertyTypeAssignmentForm extends LayoutContainer { - private static final String UNSUPPORTED_ENTITY_KIND = "Unsupported entity kind"; +public final class PropertyTypeAssignmentForm extends LayoutContainer implements + IDatabaseModificationObserver +{ + private static final String UNSUPPORTED_ENTITY_KIND = "Unsupported entity kind"; + + private static final int LABEL_WIDTH = 130; + + private static final int FIELD_WIDTH = 400; + + private static final String PREFIX = "property-type-assignment_"; + + public static final String ID_PREFIX = GenericConstants.ID_PREFIX + PREFIX; - private static final int LABEL_WIDTH = 130; + public static final String PROPERTY_TYPE_ID_SUFFIX = "property_type"; - private static final int FIELD_WIDTH = 400; + public static final String SAMPLE_TYPE_ID_SUFFIX = ID_PREFIX + "sample_type"; - private static final String PREFIX = "property-type-assignment_"; + public static final String EXPERIMENT_TYPE_ID_SUFFIX = ID_PREFIX + "experiment_type"; - public static final String ID_PREFIX = GenericConstants.ID_PREFIX + PREFIX; + public static final String MATERIAL_TYPE_ID_SUFFIX = ID_PREFIX + "material_type"; - public static final String PROPERTY_TYPE_ID_SUFFIX = "property_type"; + public static final String DATA_SET_TYPE_ID_SUFFIX = ID_PREFIX + "data_set_type"; - public static final String SAMPLE_TYPE_ID_SUFFIX = ID_PREFIX - + "sample_type"; + public static final String MANDATORY_CHECKBOX_ID_SUFFIX = "mandatory_checkbox"; - public static final String EXPERIMENT_TYPE_ID_SUFFIX = ID_PREFIX - + "experiment_type"; + public static final String SAVE_BUTTON_ID_SUFFIX = "save-button"; - public static final String MATERIAL_TYPE_ID_SUFFIX = ID_PREFIX - + "material_type"; - - public static final String DATA_SET_TYPE_ID_SUFFIX = ID_PREFIX - + "data_set_type"; - - public static final String MANDATORY_CHECKBOX_ID_SUFFIX = "mandatory_checkbox"; - - public static final String SAVE_BUTTON_ID_SUFFIX = "save-button"; - - protected static final String DEFAULT_VALUE_ID_PART = "default_value"; - - private final IViewContext<ICommonClientServiceAsync> viewContext; - - private SampleTypeSelectionWidget sampleTypeSelectionWidget; - - private ExperimentTypeSelectionWidget experimentTypeSelectionWidget; - - private MaterialTypeSelectionWidget materialTypeSelectionWidget; - - private DataSetTypeSelectionWidget dataSetTypeSelectionWidget; - - private PropertyTypeSelectionWidget propertyTypeSelectionWidget; - - private Field<?> defaultValueField; - - private CheckBox mandatoryCheckbox; - - private final InfoBox infoBox; - - private final FormPanel formPanel; - - private final EntityKind entityKind; - - public PropertyTypeAssignmentForm( - final IViewContext<ICommonClientServiceAsync> viewContext, - EntityKind entityKind) { - this.entityKind = entityKind; - setLayout(new FlowLayout(5)); - setId(createId(entityKind)); - this.viewContext = viewContext; - setScrollMode(Scroll.AUTO); - add(infoBox = createInfoBox()); - add(formPanel = createFormPanel()); - } - - public static final String createId(EntityKind entityKind) { - return ID_PREFIX + entityKind.name(); - } - - private String createChildId(String childSuffix) { - return getId() + childSuffix; - } - - private final static InfoBox createInfoBox() { - final InfoBox infoBox = new InfoBox(); - return infoBox; - } - - private PropertyTypeSelectionWidget getPropertyTypeWidget() { - if (propertyTypeSelectionWidget == null) { - propertyTypeSelectionWidget = new PropertyTypeSelectionWidget( - viewContext, createChildId(PROPERTY_TYPE_ID_SUFFIX)); - propertyTypeSelectionWidget.addListener(Events.Focus, - new InfoBoxResetListener(infoBox)); - FieldUtil.markAsMandatory(propertyTypeSelectionWidget); - propertyTypeSelectionWidget.addListener(Events.SelectionChange, - new Listener<BaseEvent>() { - public void handleEvent(BaseEvent be) { - updateDefaultField(); - } - }); - } - return propertyTypeSelectionWidget; - } - - private ComboBox<?> getTypeSelectionWidget() { - switch (entityKind) { - case EXPERIMENT: - if (experimentTypeSelectionWidget == null) { - experimentTypeSelectionWidget = new ExperimentTypeSelectionWidget( - viewContext, EXPERIMENT_TYPE_ID_SUFFIX); - experimentTypeSelectionWidget.addListener(Events.Focus, - new InfoBoxResetListener(infoBox)); - FieldUtil.markAsMandatory(experimentTypeSelectionWidget); - } - return experimentTypeSelectionWidget; - case SAMPLE: - if (sampleTypeSelectionWidget == null) { - sampleTypeSelectionWidget = new SampleTypeSelectionWidget( - viewContext, SAMPLE_TYPE_ID_SUFFIX, false); - sampleTypeSelectionWidget.addListener(Events.Focus, - new InfoBoxResetListener(infoBox)); - FieldUtil.markAsMandatory(sampleTypeSelectionWidget); - } - return sampleTypeSelectionWidget; - case MATERIAL: - if (materialTypeSelectionWidget == null) { - materialTypeSelectionWidget = new MaterialTypeSelectionWidget( - viewContext, MATERIAL_TYPE_ID_SUFFIX); - materialTypeSelectionWidget.addListener(Events.Focus, - new InfoBoxResetListener(infoBox)); - FieldUtil.markAsMandatory(materialTypeSelectionWidget); - } - return materialTypeSelectionWidget; - case DATA_SET: - if (dataSetTypeSelectionWidget == null) { - dataSetTypeSelectionWidget = new DataSetTypeSelectionWidget( - viewContext, DATA_SET_TYPE_ID_SUFFIX); - dataSetTypeSelectionWidget.addListener(Events.Focus, - new InfoBoxResetListener(infoBox)); - FieldUtil.markAsMandatory(dataSetTypeSelectionWidget); - } - return dataSetTypeSelectionWidget; - } - throw new IllegalArgumentException(UNSUPPORTED_ENTITY_KIND); - } - - private CheckBox getMandatoryCheckbox() { - if (mandatoryCheckbox == null) { - mandatoryCheckbox = new CheckBox(); - mandatoryCheckbox - .setId(createChildId(MANDATORY_CHECKBOX_ID_SUFFIX)); - mandatoryCheckbox.setFieldLabel(viewContext - .getMessage(Dict.MANDATORY)); - mandatoryCheckbox.setValue(false); - mandatoryCheckbox.addListener(Events.Change, - new InfoBoxResetListener(infoBox)); - } - return mandatoryCheckbox; - } - - private final FormPanel createFormPanel() { - final FormPanel panel = new FormPanel(); - panel.setHeaderVisible(false); - panel.setBodyBorder(false); - panel.setWidth(LABEL_WIDTH + FIELD_WIDTH + 40); - panel.setLabelWidth(LABEL_WIDTH); - panel.setFieldWidth(FIELD_WIDTH); - panel.setButtonAlign(HorizontalAlignment.RIGHT); - final Button saveButton = new Button(viewContext - .getMessage(Dict.BUTTON_SAVE)); - saveButton.setStyleAttribute("marginRight", "20px"); - saveButton.setId(createChildId(SAVE_BUTTON_ID_SUFFIX)); - saveButton.addSelectionListener(new SelectionListener<ButtonEvent>() { - @Override - public final void componentSelected(final ButtonEvent ce) { - submitForm(); - } - }); - final Button resetButton = new Button(viewContext - .getMessage(Dict.BUTTON_RESET)); - resetButton.addSelectionListener(new SelectionListener<ButtonEvent>() { - @Override - public final void componentSelected(final ButtonEvent ce) { - resetForm(); - } - }); - panel.addButton(resetButton); - panel.addButton(saveButton); - return panel; - } - - private String getDefaultValue() { - if (defaultValueField != null) { - return PropertyFieldFactory.valueToString(defaultValueField - .getValue()); - } - return null; - } - - private String getSelectedEntityCode() { - switch (entityKind) { - case EXPERIMENT: - return experimentTypeSelectionWidget.tryGetSelectedExperimentType() - .getCode(); - case SAMPLE: - return sampleTypeSelectionWidget.tryGetSelectedSampleType() - .getCode(); - case MATERIAL: - return materialTypeSelectionWidget.tryGetSelectedMaterialType() - .getCode(); - case DATA_SET: - return dataSetTypeSelectionWidget.tryGetSelectedDataSetType() - .getCode(); - } - throw new IllegalArgumentException(UNSUPPORTED_ENTITY_KIND); - } - - private final void addFormFields() { - formPanel.add(getPropertyTypeWidget()); - formPanel.add(getTypeSelectionWidget()); - formPanel.add(getMandatoryCheckbox()); - updateDefaultField(); - } - - @Override - protected final void onRender(final Element target, final int index) { - super.onRender(target, index); - addFormFields(); - } - - public final class AssignPropertyTypeCallback extends - AbstractAsyncCallback<String> { - AssignPropertyTypeCallback(final IViewContext<?> viewContext) { - super(viewContext, new InfoBoxCallbackListener<String>(infoBox)); - } - - @Override - protected final void process(final String result) { - infoBox.displayInfo(result); - resetForm(); - } - } - - private void updateDefaultField() { - hideDefaultField(); - final PropertyType propertyType = propertyTypeSelectionWidget - .tryGetSelectedPropertyType(); - if (propertyType != null) { - String fieldId = createChildId(DEFAULT_VALUE_ID_PART - + propertyType.isInternalNamespace() - + propertyType.getSimpleCode()); - Field<?> field = PropertyFieldFactory.createField(propertyType, - false, viewContext.getMessage(Dict.DEFAULT_VALUE), fieldId, - null, viewContext); - field - .setToolTip(viewContext - .getMessage(Dict.DEFAULT_VALUE_TOOLTIP)); - defaultValueField = field; - defaultValueField.show(); - formPanel.add(defaultValueField); - } - layout(); - } - - private void hideDefaultField() { - if (defaultValueField != null) { - defaultValueField.hide(); - formPanel.remove(defaultValueField); - defaultValueField = null; - } - } - - private final void submitForm() { - if (formPanel.isValid()) { - viewContext.getService().assignPropertyType( - entityKind, - propertyTypeSelectionWidget - .tryGetSelectedPropertyTypeCode(), - getSelectedEntityCode(), getMandatoryCheckbox().getValue(), - getDefaultValue(), - new AssignPropertyTypeCallback(viewContext)); - } - } - - private void resetForm() { - formPanel.reset(); - updateDefaultField(); - } + protected static final String DEFAULT_VALUE_ID_PART = "default_value"; + + private final IViewContext<ICommonClientServiceAsync> viewContext; + + private SampleTypeSelectionWidget sampleTypeSelectionWidget; + + private ExperimentTypeSelectionWidget experimentTypeSelectionWidget; + + private MaterialTypeSelectionWidget materialTypeSelectionWidget; + + private DataSetTypeSelectionWidget dataSetTypeSelectionWidget; + + private PropertyTypeSelectionWidget propertyTypeSelectionWidget; + + private DatabaseModificationAwareField<?> defaultValueField; + + private CheckBox mandatoryCheckbox; + + private final InfoBox infoBox; + + private final FormPanel formPanel; + + private final CompositeDatabaseModificationObserver modificationManager; + + private final EntityKind entityKind; + + public static DatabaseModificationAwareComponent create( + final IViewContext<ICommonClientServiceAsync> viewContext, EntityKind entityKind) + { + PropertyTypeAssignmentForm form = new PropertyTypeAssignmentForm(viewContext, entityKind); + return new DatabaseModificationAwareComponent(form, form.modificationManager); + } + + private PropertyTypeAssignmentForm(final IViewContext<ICommonClientServiceAsync> viewContext, + EntityKind entityKind) + { + this.entityKind = entityKind; + this.modificationManager = new CompositeDatabaseModificationObserver(); + setLayout(new FlowLayout(5)); + setId(createId(entityKind)); + this.viewContext = viewContext; + setScrollMode(Scroll.AUTO); + add(infoBox = createInfoBox()); + add(formPanel = createFormPanel()); + } + + public static final String createId(EntityKind entityKind) + { + return ID_PREFIX + entityKind.name(); + } + + private String createChildId(String childSuffix) + { + return getId() + childSuffix; + } + + private final static InfoBox createInfoBox() + { + final InfoBox infoBox = new InfoBox(); + return infoBox; + } + + private PropertyTypeSelectionWidget getPropertyTypeWidget() + { + if (propertyTypeSelectionWidget == null) + { + propertyTypeSelectionWidget = + new PropertyTypeSelectionWidget(viewContext, + createChildId(PROPERTY_TYPE_ID_SUFFIX)); + propertyTypeSelectionWidget + .addListener(Events.Focus, new InfoBoxResetListener(infoBox)); + FieldUtil.markAsMandatory(propertyTypeSelectionWidget); + propertyTypeSelectionWidget.addListener(Events.SelectionChange, + new Listener<BaseEvent>() + { + public void handleEvent(BaseEvent be) + { + updateDefaultField(); + } + }); + } + return propertyTypeSelectionWidget; + } + + private DropDownList<?, ?> getTypeSelectionWidget() + { + switch (entityKind) + { + case EXPERIMENT: + if (experimentTypeSelectionWidget == null) + { + experimentTypeSelectionWidget = + new ExperimentTypeSelectionWidget(viewContext, + EXPERIMENT_TYPE_ID_SUFFIX); + experimentTypeSelectionWidget.addListener(Events.Focus, + new InfoBoxResetListener(infoBox)); + FieldUtil.markAsMandatory(experimentTypeSelectionWidget); + } + return experimentTypeSelectionWidget; + case SAMPLE: + if (sampleTypeSelectionWidget == null) + { + sampleTypeSelectionWidget = + new SampleTypeSelectionWidget(viewContext, SAMPLE_TYPE_ID_SUFFIX, false); + sampleTypeSelectionWidget.addListener(Events.Focus, new InfoBoxResetListener( + infoBox)); + FieldUtil.markAsMandatory(sampleTypeSelectionWidget); + } + return sampleTypeSelectionWidget; + case MATERIAL: + if (materialTypeSelectionWidget == null) + { + materialTypeSelectionWidget = + new MaterialTypeSelectionWidget(viewContext, MATERIAL_TYPE_ID_SUFFIX); + materialTypeSelectionWidget.addListener(Events.Focus, new InfoBoxResetListener( + infoBox)); + FieldUtil.markAsMandatory(materialTypeSelectionWidget); + } + return materialTypeSelectionWidget; + case DATA_SET: + if (dataSetTypeSelectionWidget == null) + { + dataSetTypeSelectionWidget = + new DataSetTypeSelectionWidget(viewContext, DATA_SET_TYPE_ID_SUFFIX); + dataSetTypeSelectionWidget.addListener(Events.Focus, new InfoBoxResetListener( + infoBox)); + FieldUtil.markAsMandatory(dataSetTypeSelectionWidget); + } + return dataSetTypeSelectionWidget; + } + throw new IllegalArgumentException(UNSUPPORTED_ENTITY_KIND); + } + + private CheckBox getMandatoryCheckbox() + { + if (mandatoryCheckbox == null) + { + mandatoryCheckbox = new CheckBox(); + mandatoryCheckbox.setId(createChildId(MANDATORY_CHECKBOX_ID_SUFFIX)); + mandatoryCheckbox.setFieldLabel(viewContext.getMessage(Dict.MANDATORY)); + mandatoryCheckbox.setValue(false); + mandatoryCheckbox.addListener(Events.Change, new InfoBoxResetListener(infoBox)); + } + return mandatoryCheckbox; + } + + private final FormPanel createFormPanel() + { + final FormPanel panel = new FormPanel(); + panel.setHeaderVisible(false); + panel.setBodyBorder(false); + panel.setWidth(LABEL_WIDTH + FIELD_WIDTH + 40); + panel.setLabelWidth(LABEL_WIDTH); + panel.setFieldWidth(FIELD_WIDTH); + panel.setButtonAlign(HorizontalAlignment.RIGHT); + final Button saveButton = new Button(viewContext.getMessage(Dict.BUTTON_SAVE)); + saveButton.setStyleAttribute("marginRight", "20px"); + saveButton.setId(createChildId(SAVE_BUTTON_ID_SUFFIX)); + saveButton.addSelectionListener(new SelectionListener<ButtonEvent>() + { + @Override + public final void componentSelected(final ButtonEvent ce) + { + submitForm(); + } + }); + final Button resetButton = new Button(viewContext.getMessage(Dict.BUTTON_RESET)); + resetButton.addSelectionListener(new SelectionListener<ButtonEvent>() + { + @Override + public final void componentSelected(final ButtonEvent ce) + { + resetForm(); + } + }); + panel.addButton(resetButton); + panel.addButton(saveButton); + return panel; + } + + private String getDefaultValue() + { + if (defaultValueField != null) + { + return PropertyFieldFactory.valueToString(defaultValueField.get().getValue()); + } + return null; + } + + private String getSelectedEntityCode() + { + switch (entityKind) + { + case EXPERIMENT: + return experimentTypeSelectionWidget.tryGetSelectedExperimentType().getCode(); + case SAMPLE: + return sampleTypeSelectionWidget.tryGetSelectedSampleType().getCode(); + case MATERIAL: + return materialTypeSelectionWidget.tryGetSelectedMaterialType().getCode(); + case DATA_SET: + return dataSetTypeSelectionWidget.tryGetSelectedDataSetType().getCode(); + } + throw new IllegalArgumentException(UNSUPPORTED_ENTITY_KIND); + } + + private final void addFormFields() + { + PropertyTypeSelectionWidget propertyTypeWidget = getPropertyTypeWidget(); + DropDownList<?, ?> typeSelectionWidget = getTypeSelectionWidget(); + formPanel.add(propertyTypeWidget); + formPanel.add(typeSelectionWidget); + formPanel.add(getMandatoryCheckbox()); + updateDefaultField(); + + // TODO 2009-03-30, Tomasz Pylak: add auto-refreshing of the initial value field + modificationManager.addObserver(propertyTypeWidget); + modificationManager.addObserver(typeSelectionWidget); + } + + @Override + protected final void onRender(final Element target, final int index) + { + super.onRender(target, index); + addFormFields(); + } + + public final class AssignPropertyTypeCallback extends AbstractAsyncCallback<String> + { + AssignPropertyTypeCallback(final IViewContext<?> viewContext) + { + super(viewContext, new InfoBoxCallbackListener<String>(infoBox)); + } + + @Override + protected final void process(final String result) + { + infoBox.displayInfo(result); + resetForm(); + } + } + + private void updateDefaultField() + { + hideDefaultField(); + final PropertyType propertyType = propertyTypeSelectionWidget.tryGetSelectedPropertyType(); + if (propertyType != null) + { + String fieldId = + createChildId(DEFAULT_VALUE_ID_PART + propertyType.isInternalNamespace() + + propertyType.getSimpleCode()); + DatabaseModificationAwareField<?> fieldHolder = + PropertyFieldFactory.createField(propertyType, false, viewContext + .getMessage(Dict.DEFAULT_VALUE), fieldId, null, viewContext); + fieldHolder.get().setToolTip(viewContext.getMessage(Dict.DEFAULT_VALUE_TOOLTIP)); + defaultValueField = fieldHolder; + defaultValueField.get().show(); + formPanel.add(defaultValueField.get()); + } + layout(); + } + + private void hideDefaultField() + { + if (defaultValueField != null) + { + Field<?> field = defaultValueField.get(); + field.hide(); + formPanel.remove(field); + defaultValueField = null; + } + } + + private final void submitForm() + { + if (formPanel.isValid()) + { + viewContext.getService().assignPropertyType(entityKind, + propertyTypeSelectionWidget.tryGetSelectedPropertyTypeCode(), + getSelectedEntityCode(), getMandatoryCheckbox().getValue(), getDefaultValue(), + new AssignPropertyTypeCallback(viewContext)); + } + } + + private void resetForm() + { + formPanel.reset(); + updateDefaultField(); + } + + public DatabaseModificationKind[] getRelevantModifications() + { + return modificationManager.getRelevantModifications(); + } + + public void update(Set<DatabaseModificationKind> observedModifications) + { + modificationManager.update(observedModifications); + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeSelectionWidget.java index 66baaf0ed4dce817238b5100d8c76c03948b4e9c..4da48e6c96bfd630b3e0911bad85172c91a2d9fd 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeSelectionWidget.java @@ -31,7 +31,9 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.Mode import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * {@link ComboBox} containing list of property type codes loaded from the server. @@ -130,4 +132,9 @@ public final class PropertyTypeSelectionWidget extends viewContext.getService().listPropertyTypes(config, new ListPropertyTypesCallback(viewContext)); } + + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.PROPERTY_TYPE); + } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/DropDownList.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/DropDownList.java index bcfc961ac424c33d8702daaf3747ed60ea41a603..b5e873fd58ac11b546641ba7a5c1376521e10a36 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/DropDownList.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/DropDownList.java @@ -16,13 +16,10 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample; -import java.util.List; - import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.widget.form.ComboBox; import com.google.gwt.user.client.Element; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; @@ -46,31 +43,17 @@ public abstract class DropDownList<M extends ModelData, E> extends SimpleDropDow this.viewContext = viewContext; } - abstract protected void loadData(AbstractAsyncCallback<List<E>> callback); - - abstract protected List<M> convertItems(final List<E> result); - @Override protected void onRender(final Element parent, final int pos) { super.onRender(parent, pos); - loadData(new ListItemsCallback(viewContext)); + refreshStore(); } - public class ListItemsCallback extends AbstractAsyncCallback<List<E>> + @Override + public void refreshStore() { - - protected ListItemsCallback(final IViewContext<?> viewContext) - { - super(viewContext); - } - - @Override - public void process(final List<E> result) - { - List<M> convertedItems = convertItems(result); - updateStore(convertedItems); - } + refreshStore(viewContext); } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleRegistrationPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleRegistrationPanel.java index f74227588ea8e71112cfc083880c2efc5474a74f..0ce250feb4559d61674f3fc51f61a4e42b5c323f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleRegistrationPanel.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleRegistrationPanel.java @@ -1,22 +1,23 @@ /* -* Copyright 2008 ETH Zuerich, CISD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2008 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample; import ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.SampleTypeModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.EntityRegistrationPanel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; @@ -32,7 +33,14 @@ public final class SampleRegistrationPanel extends public static final String ID = EntityRegistrationPanel.createId(EntityKind.SAMPLE); - public SampleRegistrationPanel(final CommonViewContext viewContext) + public static final DatabaseModificationAwareComponent create( + final CommonViewContext viewContext) + { + SampleRegistrationPanel panel = new SampleRegistrationPanel(viewContext); + return new DatabaseModificationAwareComponent(panel, panel); + } + + private SampleRegistrationPanel(final CommonViewContext viewContext) { super(viewContext, EntityKind.SAMPLE, new SampleTypeSelectionWidget(viewContext, EntityRegistrationPanel.createId(EntityKind.SAMPLE), false)); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleTypeSelectionWidget.java index 74725886f973d06f2fce39ca05f5bfeb856670df..2b8d3fe0624a5ccfcacff2205c2cc0477526956f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleTypeSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleTypeSelectionWidget.java @@ -25,7 +25,9 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.SampleTypeModel; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind; /** * {@link ComboBox} containing list of sample types loaded from the server. @@ -69,6 +71,10 @@ public final class SampleTypeSelectionWidget extends DropDownList<SampleTypeMode protected void loadData(AbstractAsyncCallback<List<SampleType>> callback) { viewContext.getCommonService().listSampleTypes(callback); + } + public DatabaseModificationKind[] getRelevantModifications() + { + return DatabaseModificationKind.any(ObjectKind.SAMPLE_TYPE); } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SimpleDropDownList.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SimpleDropDownList.java index c329b8f1cad4244b0537a01a533787a58e059a90..76f11f4f2fef8258948eb0e82f94ca69266f0566 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SimpleDropDownList.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SimpleDropDownList.java @@ -16,20 +16,44 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.Set; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.store.ListStore; +import com.extjs.gxt.ui.client.store.Store; import com.extjs.gxt.ui.client.widget.form.ComboBox; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; /** * @author Izabela Adamczyk */ -public class SimpleDropDownList<M extends ModelData, E> extends ComboBox<M> +abstract public class SimpleDropDownList<M extends ModelData, E> extends ComboBox<M> implements + IDatabaseModificationObserver { + + /** + * Refreshes the whole store of the combobox. If the previously chosen value is no longer + * present in the store, it will be changed to empty. Otherwise the previous selection will be + * preserved. + */ + abstract public void refreshStore(); + + abstract protected void loadData(AbstractAsyncCallback<List<E>> callback); + + abstract protected List<M> convertItems(final List<E> result); + + // ---------- + private static final int DEFAULT_WIDTH = 150; private static final String PREFIX = "select_"; @@ -61,7 +85,38 @@ public class SimpleDropDownList<M extends ModelData, E> extends ComboBox<M> setStore(new ListStore<M>()); } - public void updateStore(final List<M> models) + public DatabaseModificationAwareField<M> asDatabaseModificationAware() + { + return new DatabaseModificationAwareField<M>(this, this); + } + + public void update(Set<DatabaseModificationKind> observedModifications) + { + refreshStore(); + } + + protected void refreshStore(final IViewContext<?> viewContext) + { + loadData(new ListItemsCallback(viewContext)); + } + + public class ListItemsCallback extends AbstractAsyncCallback<List<E>> + { + + protected ListItemsCallback(final IViewContext<?> viewContext) + { + super(viewContext); + } + + @Override + public void process(final List<E> result) + { + List<M> convertedItems = convertItems(result); + updateStore(convertedItems); + } + } + + protected void updateStore(final List<M> models) { final ListStore<M> termsStore = getStore(); termsStore.removeAll(); @@ -70,6 +125,11 @@ public class SimpleDropDownList<M extends ModelData, E> extends ComboBox<M> { setEmptyText(chooseMsg); setReadOnly(false); + if (getValue() != null && getSelection().size() == 0) + { + validate(); // maybe the value became a valid selection + } + restoreSelection(getSelection()); } else { setEmptyText(emptyMsg); @@ -78,6 +138,74 @@ public class SimpleDropDownList<M extends ModelData, E> extends ComboBox<M> applyEmptyText(); } + private void restoreSelection(List<M> previousSelection) + { + List<M> newSelection = cleanSelection(previousSelection, getStore()); + if (previousSelection.size() != newSelection.size()) + { + setSelection(newSelection); + } + } + + // removes the no longer existing items from the selection + private static <M extends ModelData> List<M> cleanSelection(List<M> previousSelection, + Store<M> newStore) + { + List<M> newSelection = new ArrayList<M>(); + for (M prevItem : previousSelection) + { + if (containsModel(newStore, prevItem)) + { + newSelection.add(prevItem); + } + } + return newSelection; + } + + private static <M extends ModelData> boolean containsModel(Store<M> store, M item) + { + for (M elem : store.getModels()) + { + if (equalsModel(elem, item)) + { + return true; + } + } + return false; + } + + private static <M extends ModelData> boolean equalsModel(M model1, M model2) + { + Collection<String> props1 = model1.getPropertyNames(); + Collection<String> props2 = model1.getPropertyNames(); + if (props1.equals(props2) == false) + { + return false; + } + for (String propName : props1) + { + Object val1 = model1.get(propName); + Object val2 = model2.get(propName); + if (val1 == null) + { + if (val2 != null) + { + return false; + } else + { + continue; + } + } else + { + if (val1.equals(val2) == false) + { + return false; + } + } + } + return true; + } + @Override public String getRawValue() { @@ -149,8 +277,7 @@ public class SimpleDropDownList<M extends ModelData, E> extends ComboBox<M> { clearInvalid(); markInvalidIfNotFromList(); - return super.isValid() && valueNotInTheList() == false - ; + return super.isValid() && valueNotInTheList() == false; } @Override @@ -158,8 +285,7 @@ public class SimpleDropDownList<M extends ModelData, E> extends ComboBox<M> { clearInvalid(); markInvalidIfNotFromList(); - return super.validate() && valueNotInTheList() == false - ; + return super.validate() && valueNotInTheList() == false; } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/EntityRegistrationPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/EntityRegistrationPanel.java index dcebf1b34f2a6f08a03b8b7cbaa436836f2dba52..2efee3840d4fd54eea0290b8ce9b181a7b5b7e7b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/EntityRegistrationPanel.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/EntityRegistrationPanel.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget import java.util.ArrayList; import java.util.List; +import java.util.Set; import com.extjs.gxt.ui.client.Style.Scroll; import com.extjs.gxt.ui.client.data.ModelData; @@ -25,18 +26,21 @@ import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.LayoutContainer; -import com.extjs.gxt.ui.client.widget.form.ComboBox; import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem; import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; -import com.google.gwt.user.client.ui.Widget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.CompositeDatabaseModificationObserver; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareWidget; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin.IClientPlugin; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SimpleDropDownList; import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; @@ -47,11 +51,19 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityTypePropertyType; * * @author Izabela Adamczyk */ -abstract public class EntityRegistrationPanel<T extends ModelData, S extends ComboBox<T>> extends - ContentPanel +abstract public class EntityRegistrationPanel<T extends ModelData, S extends SimpleDropDownList<T, ?>> + extends ContentPanel implements IDatabaseModificationObserver { private final S entityTypeSelection; + private final CommonViewContext viewContext; + + private final EntityKind entityKind; + + private DatabaseModificationAwareWidget registrationWidget; + + private PreviousSelection previousSelection = new PreviousSelection(); + protected static String createId(EntityKind entityKind) { return GenericConstants.ID_PREFIX + entityKind.name().toLowerCase() + "-registration"; @@ -61,6 +73,9 @@ abstract public class EntityRegistrationPanel<T extends ModelData, S extends Com S entityTypeSelection) { this.entityTypeSelection = entityTypeSelection; + this.viewContext = viewContext; + this.entityKind = entityKind; + setHeaderVisible(false); setId(createId(entityKind)); setScrollMode(Scroll.AUTO); @@ -69,90 +84,103 @@ abstract public class EntityRegistrationPanel<T extends ModelData, S extends Com + GenericConstants.LABEL_SEPARATOR)); toolBar.add(new AdapterToolItem(entityTypeSelection)); setTopComponent(toolBar); - entityTypeSelection.addSelectionChangedListener(new EntityTypeSelectionChangeListener( - viewContext, entityKind)); + entityTypeSelection.addSelectionChangedListener(createSelectionChangedListener()); } - private class EntityTypeSelectionChangeListener extends SelectionChangedListener<T> + private SelectionChangedListener<T> createSelectionChangedListener() { + return new SelectionChangedListener<T>() + { + @Override + public void selectionChanged(final SelectionChangedEvent<T> se) + { + final T entityTypeModel = se.getSelectedItem(); + if (entityTypeModel != null) + { + onSelectionChanged(entityTypeModel); + } + } + }; + } - private Widget registrationWidget; + private void onSelectionChanged(final T entityTypeModel) + { + final EntityType entityType = entityTypeModel.get(ModelDataPropertyNames.OBJECT); + if (registrationWidget == null) - private final CommonViewContext viewContext; + { + showRegistrationForm(entityType); + previousSelection.update(entityTypeModel); + } else + { + new ConfirmationDialog(viewContext.getMessage(Dict.CONFIRM_TITLE), viewContext + .getMessage(Dict.CONFIRM_CLOSE_MSG)) + { + @Override + protected void onYes() + { + showRegistrationForm(entityType); + previousSelection.update(entityTypeModel); + } + + @Override + protected void onNo() + { + List<T> selection = new ArrayList<T>(); + selection.add(previousSelection.getValue()); + entityTypeSelection.disableEvents(true); + entityTypeSelection.setSelection(selection); + entityTypeSelection.disableEvents(false); + } + }.show(); + } + } - private PreviousSelection previousSelection = new PreviousSelection(); + private void showRegistrationForm(final EntityType entityType) + { + removeAll(); + final IClientPlugin<EntityType, EntityTypePropertyType<EntityType>, EntityProperty<EntityType, EntityTypePropertyType<EntityType>>, IIdentifierHolder, ?> clientPlugin = + viewContext.getClientPluginFactoryProvider().getClientPluginFactory(entityKind, + entityType).createClientPlugin(entityKind); + registrationWidget = clientPlugin.createRegistrationForEntityType(entityType); + add(registrationWidget.get()); + layout(); + } - private final EntityKind entityKind; + private class PreviousSelection + { + T value; - public EntityTypeSelectionChangeListener(CommonViewContext viewContext, - EntityKind entityKind) + void update(T newValue) { - this.viewContext = viewContext; - this.entityKind = entityKind; + this.value = newValue; } - @Override - public void selectionChanged(final SelectionChangedEvent<T> se) + T getValue() { - final T entityTypeModel = se.getSelectedItem(); - if (entityTypeModel != null) - { - final EntityType entityType = entityTypeModel.get(ModelDataPropertyNames.OBJECT); - if (registrationWidget == null) - - { - showRegistrationForm(entityType); - previousSelection.update(entityTypeModel); - } else - { - new ConfirmationDialog(viewContext.getMessage(Dict.CONFIRM_TITLE), viewContext - .getMessage(Dict.CONFIRM_CLOSE_MSG)) - { - @Override - protected void onYes() - { - showRegistrationForm(entityType); - previousSelection.update(entityTypeModel); - } - - @Override - protected void onNo() - { - List<T> selection = new ArrayList<T>(); - selection.add(previousSelection.getValue()); - entityTypeSelection.disableEvents(true); - entityTypeSelection.setSelection(selection); - entityTypeSelection.disableEvents(false); - } - }.show(); - } - } + return value; } + } - private void showRegistrationForm(final EntityType entityType) + private IDatabaseModificationObserver createCompositeDatabaseModificationObserver() + { + CompositeDatabaseModificationObserver observer = + new CompositeDatabaseModificationObserver(); + if (registrationWidget != null) { - removeAll(); - final IClientPlugin<EntityType, EntityTypePropertyType<EntityType>, EntityProperty<EntityType, EntityTypePropertyType<EntityType>>, IIdentifierHolder, ?> clientPlugin = - viewContext.getClientPluginFactoryProvider().getClientPluginFactory(entityKind, - entityType).createClientPlugin(entityKind); - registrationWidget = clientPlugin.createRegistrationForEntityType(entityType); - add(registrationWidget); - layout(); + observer.addObserver(registrationWidget); } + observer.addObserver(entityTypeSelection); + return observer; + } - private class PreviousSelection - { - T value; - - void update(T newValue) - { - this.value = newValue; - } + public DatabaseModificationKind[] getRelevantModifications() + { + return createCompositeDatabaseModificationObserver().getRelevantModifications(); + } - T getValue() - { - return value; - } - } + public void update(Set<DatabaseModificationKind> observedModifications) + { + createCompositeDatabaseModificationObserver().update(observedModifications); } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/SetUtils.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/SetUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..8623f3bf994aa6d5d3af71b88d43a03a21c07392 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/SetUtils.java @@ -0,0 +1,54 @@ +/* + * Copyright 2009 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.client.web.client.application.util; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * Utility methods for sets and collections. + * + * @author Tomasz Pylak + */ +public class SetUtils +{ + /** Adds specified items to the specified collection. */ + public static <T> void addAll(Collection<T> collection, T[] items) + { + for (T newElem : items) + { + collection.add(newElem); + } + } + + /** @return true if the specified set contains any item from the specified items */ + public static <T> boolean containsAny(Set<T> set, Set<T> items) + { + Set<T> setCopy = new HashSet<T>(set); + setCopy.retainAll(items); + return set.size() > 0; + } + + /** @return true if the specified set contains any item from the specified items */ + public static <T> boolean containsAny(Set<T> set, T[] items) + { + Set<T> itemsSet = new HashSet<T>(); + addAll(itemsSet, items); + return containsAny(set, itemsSet); + } +} \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java index 7f8fd05e5d674804d8a71ca959e7f4e667c1e231..4c4ffc9c426db344e36fa21a75796b9fbcdea144 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Set; import javax.servlet.http.HttpSession; @@ -109,6 +110,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; @@ -686,7 +688,8 @@ public final class CommonClientService extends AbstractClientService implements public List<VocabularyTermWithStats> getOriginalData() throws UserFailureException { List<ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats> terms = - commonServer.listVocabularyTerms(getSessionToken(), vocabulary); + commonServer.listVocabularyTermsWithStatistics(getSessionToken(), + vocabulary); return VocabularyTermTranslator.translate(terms); } }); @@ -909,7 +912,7 @@ public final class CommonClientService extends AbstractClientService implements assert vocabularyCode != null : "Unspecified vocabulary code."; assert termsToBeDeleted != null : "Unspecified term to be deleted."; assert termsToBeReplaced != null : "Unspecified term to be replaced."; - + try { final String sessionToken = getSessionToken(); @@ -921,6 +924,20 @@ public final class CommonClientService extends AbstractClientService implements } } + public List<VocabularyTerm> listVocabularyTerms(Vocabulary vocabulary) + { + try + { + final String sessionToken = getSessionToken(); + Set<VocabularyTermPE> terms = + commonServer.listVocabularyTerms(sessionToken, vocabulary); + return VocabularyTermTranslator.translateTerms(terms); + } catch (final UserFailureException e) + { + throw UserFailureExceptionTranslator.translate(e); + } + } + public void registerProject(Project project) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/VocabularyTermTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/VocabularyTermTranslator.java index f797f85667972f53923e356ba61fd759d57a3bee..dc4d714162594cad187c8b73a378ba8f6ed8e331 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/VocabularyTermTranslator.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/VocabularyTermTranslator.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.server.translator; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.apache.commons.lang.StringEscapeUtils; @@ -41,8 +42,18 @@ public class VocabularyTermTranslator return result; } + public static List<VocabularyTerm> translateTerms(Collection<VocabularyTermPE> terms) + { + List<VocabularyTerm> result = new ArrayList<VocabularyTerm>(); + for (VocabularyTermPE term : terms) + { + result.add(translate(term)); + } + return result; + } + public static List<VocabularyTermWithStats> translate( - List<ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats> terms) + Collection<ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats> terms) { List<VocabularyTermWithStats> result = new ArrayList<VocabularyTermWithStats>(); for (ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats term : terms) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java index f1d001d77892df353af17ecc7926ef3190b20436..c30aa0c92c52f1344571cc2927367dbff7b36c76 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Set; import org.springframework.dao.DataAccessException; @@ -87,6 +88,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SearchHit; import ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; @@ -733,7 +735,7 @@ public final class CommonServer extends AbstractServer<ICommonServer> implements } - public List<VocabularyTermWithStats> listVocabularyTerms(String sessionToken, + public List<VocabularyTermWithStats> listVocabularyTermsWithStatistics(String sessionToken, Vocabulary vocabulary) { final Session session = getSessionManager().getSession(sessionToken); @@ -742,6 +744,14 @@ public final class CommonServer extends AbstractServer<ICommonServer> implements return vocabularyBO.countTermsUsageStatistics(); } + public Set<VocabularyTermPE> listVocabularyTerms(String sessionToken, Vocabulary vocabulary) + { + final Session session = getSessionManager().getSession(sessionToken); + final IVocabularyBO vocabularyBO = businessObjectFactory.createVocabularyBO(session); + vocabularyBO.load(vocabulary.getCode()); + return vocabularyBO.enrichWithTerms(); + } + public List<DataSetTypePE> listDataSetTypes(String sessionToken) { return listEntityTypes(sessionToken, EntityKind.DATA_SET); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java index 41bfbca184ab58130a0f7262b3dd49ee2b11eff2..75c4ca442b3e88177c03f788e28bd5f24e475c66 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java @@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.generic.server; import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.Set; import ch.systemsx.cisd.authentication.ISessionManager; import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; @@ -59,6 +60,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SearchHit; import ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; @@ -366,8 +368,15 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe } - public List<VocabularyTermWithStats> listVocabularyTerms(String sessionToken, + public List<VocabularyTermWithStats> listVocabularyTermsWithStatistics(String sessionToken, Vocabulary vocabulary) + { + logAccess(sessionToken, "list_vocabulary_terms_with_statistics", "VOCABULARY(%s)", + vocabulary.getCode()); + return null; + } + + public Set<VocabularyTermPE> listVocabularyTerms(String sessionToken, Vocabulary vocabulary) { logAccess(sessionToken, "list_vocabulary_terms", "VOCABULARY(%s)", vocabulary.getCode()); return null; @@ -384,4 +393,5 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe logAccess(sessionToken, "getLastModificationState"); return null; } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IVocabularyBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IVocabularyBO.java index 58e95ec10433c4733b0572179fedd26422304ab7..19e35fda4de2943c666367d8fa4bd453822ab835 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IVocabularyBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IVocabularyBO.java @@ -17,12 +17,14 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo; import java.util.List; +import java.util.Set; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTermReplacement; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats; /** @@ -41,27 +43,30 @@ public interface IVocabularyBO extends IBusinessObject * * @throws UserFailureException if given <var>vocabulary</var> does already exist. */ - public void define(final Vocabulary vocabulary) throws UserFailureException; + void define(final Vocabulary vocabulary) throws UserFailureException; /** * Returns the loaded {@link VocabularyPE}. */ - public VocabularyPE getVocabulary(); + VocabularyPE getVocabulary(); /** * Loads specified vocabulary from the database. * * @throws UserFailureException if no vocabulary found for <code>vocabularyCode</code>. */ - public void load(String vocabularyCode) throws UserFailureException; + void load(String vocabularyCode) throws UserFailureException; /** @return terms with their usage statistics for the loaded vocabulary */ - public List<VocabularyTermWithStats> countTermsUsageStatistics(); - + List<VocabularyTermWithStats> countTermsUsageStatistics(); + + /** enriches currently loaded vocabulary with its terms and returns them */ + Set<VocabularyTermPE> enrichWithTerms(); + /** * Add the specified terms to a loaded vocabulary. */ - public void addNewTerms(List<String> newTerms); + void addNewTerms(List<String> newTerms); /** * Deletes the specified terms from a loaded vocabulary and replaces terms which are used. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/VocabularyBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/VocabularyBO.java index 7c4fc77e3fa2d9034842edd2bbd3f5e42c7e0e8f..16e381cb93f34b8744242849e92598c15ffa6b80 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/VocabularyBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/VocabularyBO.java @@ -206,8 +206,9 @@ public class VocabularyBO extends AbstractBusinessObject implements IVocabularyB } } - private void enrichWithTerms() + public Set<VocabularyTermPE> enrichWithTerms() { HibernateUtils.initialize(vocabularyPE.getTerms()); + return vocabularyPE.getTerms(); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java index b4aa3e9fc8d6f49879b080d5279da6280ddf6b83..39afa5a49651bfcba27a282f52685bbef1aab011 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.shared; import java.util.Date; import java.util.List; +import java.util.Set; import org.springframework.transaction.annotation.Transactional; @@ -67,6 +68,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.SearchHit; import ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; @@ -315,6 +317,7 @@ public interface ICommonServer extends IServer */ @Transactional @RolesAllowed(RoleSet.INSTANCE_ADMIN) + @DatabaseCreateOrDeleteModification(value = ObjectKind.VOCABULARY_TERM) public void deleteVocabularyTerms(String sessionToken, String vocabularyCode, List<VocabularyTerm> termsToBeDeleted, List<VocabularyTermReplacement> termsToBeReplaced); @@ -437,11 +440,18 @@ public interface ICommonServer extends IServer /** * Lists vocabulary terms of a given vocabulary. Includes terms usage statistics. */ - @Transactional - @RolesAllowed(RoleSet.USER) - public List<VocabularyTermWithStats> listVocabularyTerms(String sessionToken, + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<VocabularyTermWithStats> listVocabularyTermsWithStatistics(String sessionToken, Vocabulary vocabulary); + /** + * Lists vocabulary terms of a given vocabulary. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public Set<VocabularyTermPE> listVocabularyTerms(String sessionToken, Vocabulary vocabulary); + /** * List data set types. * diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DatabaseModificationKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DatabaseModificationKind.java index e823e8196dce7eeab7299dcc54d22ac1297d060c..d1a0972c53c4875013c26a53a87bb78a53f3f017 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DatabaseModificationKind.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DatabaseModificationKind.java @@ -16,6 +16,9 @@ package ch.systemsx.cisd.openbis.generic.shared.basic.dto; +import java.util.ArrayList; +import java.util.List; + import com.google.gwt.user.client.rpc.IsSerializable; /** @@ -25,11 +28,13 @@ import com.google.gwt.user.client.rpc.IsSerializable; */ public class DatabaseModificationKind implements IsSerializable { + public static final DatabaseModificationKind[] EMPTY_ARRAY = new DatabaseModificationKind[0]; + public enum ObjectKind implements IsSerializable { - SAMPLE, EXPERIMENT, MATERIAL, SAMPLE_TYPE, EXPERIMENT_TYPE, MATERIAL_TYPE, PROJECT, GROUP, - DATA_SET, PROPERTY_TYPE, PROPERTY_TYPE_ASSIGNMENT, VOCABULARY, VOCABULARY_TERM, ROLE, - PERSON + SAMPLE, EXPERIMENT, MATERIAL, DATA_SET, SAMPLE_TYPE, EXPERIMENT_TYPE, MATERIAL_TYPE, + DATASET_TYPE, PROJECT, GROUP, PROPERTY_TYPE, PROPERTY_TYPE_ASSIGNMENT, VOCABULARY, + VOCABULARY_TERM, ROLE, PERSON } public enum OperationKind implements IsSerializable @@ -49,6 +54,14 @@ public class DatabaseModificationKind implements IsSerializable { } + public static final DatabaseModificationKind[] any(ObjectKind objectType) + { + List<DatabaseModificationKind> result = new ArrayList<DatabaseModificationKind>(); + result.add(createOrDelete(objectType)); + result.add(edit(objectType)); + return result.toArray(EMPTY_ARRAY); + } + public static final DatabaseModificationKind createOrDelete(ObjectKind objectType) { return new DatabaseModificationKind(objectType, OperationKind.CREATE_OR_DELETE); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/AbstractGenericEntityEditForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/AbstractGenericEntityEditForm.java index 5665178b6529956a0e1f88fd15addbc2cdea3cf1..6f2bcf921cc984b433f261d87dca88ae5d14940f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/AbstractGenericEntityEditForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/AbstractGenericEntityEditForm.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application; import java.util.ArrayList; import java.util.List; +import java.util.Set; import com.extjs.gxt.ui.client.util.Margins; import com.extjs.gxt.ui.client.widget.form.Field; @@ -28,8 +29,12 @@ import com.google.gwt.user.client.ui.Widget; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.CompositeDatabaseModificationObserver; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.IEditableEntity; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; @@ -43,7 +48,7 @@ import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.exp * @author Izabela Adamczyk */ abstract public class AbstractGenericEntityEditForm<T extends EntityType, S extends EntityTypePropertyType<T>, P extends EntityProperty<T, S>, V extends IEditableEntity<T, S, P>> - extends AbstractRegistrationForm + extends AbstractRegistrationForm implements IDatabaseModificationObserver { private final PropertiesEditor<T, S, P> editor; @@ -58,7 +63,7 @@ abstract public class AbstractGenericEntityEditForm<T extends EntityType, S exte abstract protected List<Widget> getEntitySpecificCheckPageWidgets(); - abstract protected List<Field<?>> getEntitySpecificFormFields(); + abstract protected List<DatabaseModificationAwareField<?>> getEntitySpecificFormFields(); abstract protected void updateCheckPageWidgets(); @@ -87,35 +92,12 @@ abstract public class AbstractGenericEntityEditForm<T extends EntityType, S exte { checkComponents.add(w); } - // TODO 2009-03-18, Tomasz Pylak: Uncomment when LMS-794 is closed - //checkComponents.add(createEditorButton(viewContext)); for (Widget w : checkComponents) { add(w, new RowData(1, -1, new Margins(5))); } } - // TODO 2009-03-18, Tomasz Pylak: Uncomment when LMS-794 is closed -// private Button createEditorButton(final IViewContext<?> viewContext) -// { -// return new Button(viewContext.getMessage(Dict.BUTTON_EDIT), -// new SelectionListener<ComponentEvent>() -// { -// @Override -// public void componentSelected(ComponentEvent ce) -// { -// showEditor(); -// } -// }); -// } -// -// protected void showEditor() -// { -// setEditMode(true); -// infoBox.reset(); -// formPanel.reset(); -// } - protected static String createId(EntityKind entityKind, String identifier) { return GenericConstants.ID_PREFIX + createSimpleId(entityKind, identifier); @@ -126,15 +108,26 @@ abstract public class AbstractGenericEntityEditForm<T extends EntityType, S exte return "generic-" + entityKind.name().toLowerCase() + "-edit_form_" + identifier; } - private final void addFormFields() + private final List<DatabaseModificationAwareField<?>> getAllFields() { - for (final Field<?> propertyField : editor.getPropertyFields()) + List<DatabaseModificationAwareField<?>> fields = + new ArrayList<DatabaseModificationAwareField<?>>(); + for (DatabaseModificationAwareField<?> specificField : editor.getPropertyFields()) { - formPanel.add(propertyField); + fields.add(specificField); } - for (final Field<?> specificField : getEntitySpecificFormFields()) + for (DatabaseModificationAwareField<?> propertyField : getEntitySpecificFormFields()) { - formPanel.add(specificField); + fields.add(propertyField); + } + return fields; + } + + private final void addFormFields() + { + for (DatabaseModificationAwareField<?> field : getAllFields()) + { + formPanel.add(field.get()); } } @@ -167,16 +160,40 @@ abstract public class AbstractGenericEntityEditForm<T extends EntityType, S exte setEditMode(false); } - @SuppressWarnings("unchecked") protected void updateState() { - for (Field f : editor.getPropertyFields()) + for (DatabaseModificationAwareField<?> f : editor.getPropertyFields()) { - f.updateOriginalValue(f.getValue()); + updateOriginalValue(f.get()); } entity.setProperties(editor.extractProperties()); grid.setProperties(entity.getProperties()); updateCheckPageWidgets(); } + @SuppressWarnings("unchecked") + private void updateOriginalValue(Field field) + { + field.updateOriginalValue(field.getValue()); + } + + public void update(Set<DatabaseModificationKind> observedModifications) + { + createDatabaseModificationObserver().update(observedModifications); + } + + public DatabaseModificationKind[] getRelevantModifications() + { + return createDatabaseModificationObserver().getRelevantModifications(); + } + + // the db modification observer is composed from all the fields' observers + private IDatabaseModificationObserver createDatabaseModificationObserver() + { + CompositeDatabaseModificationObserver compositeObserver = + new CompositeDatabaseModificationObserver(); + compositeObserver.addObservers(getAllFields()); + return compositeObserver; + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/AbstractGenericEntityRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/AbstractGenericEntityRegistrationForm.java index 6a66ffc8b4d7534980a2f367dce5031cf6c7d415..b4fd8dd1419b3ad32816c28554133a7744446f40 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/AbstractGenericEntityRegistrationForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/AbstractGenericEntityRegistrationForm.java @@ -16,9 +16,10 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application; +import java.util.ArrayList; import java.util.List; +import java.util.Set; -import com.extjs.gxt.ui.client.widget.form.Field; import com.extjs.gxt.ui.client.widget.form.TextField; import com.google.gwt.user.client.Element; @@ -26,8 +27,12 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.CompositeDatabaseModificationObserver; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.CodeField; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; @@ -41,7 +46,7 @@ import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.exp * @author Izabela Adamczyk */ abstract public class AbstractGenericEntityRegistrationForm<T extends EntityType, S extends EntityTypePropertyType<T>, P extends EntityProperty<T, S>> - extends AbstractRegistrationForm + extends AbstractRegistrationForm implements IDatabaseModificationObserver { public static final String ID_SUFFIX_CODE = "code"; @@ -63,7 +68,7 @@ abstract public class AbstractGenericEntityRegistrationForm<T extends EntityType .getCommonViewContext()); } - abstract protected List<Field<?>> getEntitySpecificFields(); + abstract protected List<DatabaseModificationAwareField<?>> getEntitySpecificFields(); abstract protected void createEntitySpecificFields(); @@ -88,16 +93,27 @@ abstract public class AbstractGenericEntityRegistrationForm<T extends EntityType createEntitySpecificFields(); } - private final void addFormFields() + private final List<DatabaseModificationAwareField<?>> getAllFields() { - formPanel.add(codeField); - for (final Field<?> specificField : getEntitySpecificFields()) + List<DatabaseModificationAwareField<?>> fields = + new ArrayList<DatabaseModificationAwareField<?>>(); + fields.add(DatabaseModificationAwareField.wrapUnaware(codeField)); + for (DatabaseModificationAwareField<?> specificField : getEntitySpecificFields()) + { + fields.add(specificField); + } + for (DatabaseModificationAwareField<?> propertyField : propertiesEditor.getPropertyFields()) { - formPanel.add(specificField); + fields.add(propertyField); } - for (final Field<?> propertyField : propertiesEditor.getPropertyFields()) + return fields; + } + + private final void addFormFields() + { + for (DatabaseModificationAwareField<?> field : getAllFields()) { - formPanel.add(propertyField); + formPanel.add(field.get()); } } @@ -113,4 +129,23 @@ abstract public class AbstractGenericEntityRegistrationForm<T extends EntityType createFormFields(); addFormFields(); } + + public void update(Set<DatabaseModificationKind> observedModifications) + { + createDatabaseModificationObserver().update(observedModifications); + } + + public DatabaseModificationKind[] getRelevantModifications() + { + return createDatabaseModificationObserver().getRelevantModifications(); + } + + // the db modification observer is composed from all the fields' observers + private IDatabaseModificationObserver createDatabaseModificationObserver() + { + CompositeDatabaseModificationObserver compositeObserver = + new CompositeDatabaseModificationObserver(); + compositeObserver.addObservers(getAllFields()); + return compositeObserver; + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java index db98ff05265563a93e15706964a0f68f2f265a32..dd1415a77dca2d3b82debb76c217185270a4d266 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java @@ -18,13 +18,14 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application; import java.util.Set; -import com.extjs.gxt.ui.client.widget.Component; import com.google.gwt.user.client.ui.Widget; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractClientPluginFactory; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DefaultTabItem; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.ITabItem; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.ITabItemFactory; @@ -161,9 +162,12 @@ public final class ClientPluginFactory extends }; } - public final Widget createRegistrationForEntityType(final SampleType sampleType) + public final DatabaseModificationAwareWidget createRegistrationForEntityType( + final SampleType sampleType) { - return new GenericSampleRegistrationForm(getViewContext(), sampleType); + GenericSampleRegistrationForm form = + new GenericSampleRegistrationForm(getViewContext(), sampleType); + return new DatabaseModificationAwareWidget(form, form); } public final Widget createBatchRegistrationForEntityType(final SampleType sampleType) @@ -177,10 +181,10 @@ public final class ClientPluginFactory extends { public ITabItem create() { - Component component = - new GenericSampleEditForm(getViewContext(), entity, true); - return new DefaultTabItem( - getEditTitle(Dict.SAMPLE, entity.getIdentifier()), component, true); + DatabaseModificationAwareComponent component = + GenericSampleEditForm.create(getViewContext(), entity, true); + String title = getEditTitle(Dict.SAMPLE, entity.getIdentifier()); + return DefaultTabItem.create(title, component, getViewContext(), true); } public String getId() @@ -231,10 +235,10 @@ public final class ClientPluginFactory extends { public ITabItem create() { - Component component = - new GenericMaterialEditForm(getViewContext(), entity, true); - return new DefaultTabItem(getEditTitle(Dict.MATERIAL, entity - .getIdentifier()), component, true); + DatabaseModificationAwareComponent component = + GenericMaterialEditForm.create(getViewContext(), entity, true); + String title = getEditTitle(Dict.MATERIAL, entity.getIdentifier()); + return DefaultTabItem.create(title, component, getViewContext(), true); } public String getId() @@ -276,9 +280,12 @@ public final class ClientPluginFactory extends } @Override - public Widget createRegistrationForEntityType(ExperimentType entityType) + public DatabaseModificationAwareWidget createRegistrationForEntityType( + ExperimentType entityType) { - return new GenericExperimentRegistrationForm(getViewContext(), entityType); + GenericExperimentRegistrationForm form = + new GenericExperimentRegistrationForm(getViewContext(), entityType); + return new DatabaseModificationAwareWidget(form, form); } @Override @@ -288,10 +295,10 @@ public final class ClientPluginFactory extends { public ITabItem create() { - Component component = - new GenericExperimentEditForm(getViewContext(), entity, true); - return new DefaultTabItem(getEditTitle(Dict.EXPERIMENT, entity - .getIdentifier()), component, true); + DatabaseModificationAwareComponent component = + GenericExperimentEditForm.create(getViewContext(), entity, true); + String title = getEditTitle(Dict.EXPERIMENT, entity.getIdentifier()); + return DefaultTabItem.create(title, component, getViewContext(), true); } public String getId() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentEditForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentEditForm.java index c1aba1aec3147c5bdb0f088ab093353c1488d54d..a7e64e44567fa6666ec69c14cce1266a187ded2c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentEditForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentEditForm.java @@ -24,7 +24,6 @@ import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.util.Format; import com.extjs.gxt.ui.client.widget.Html; -import com.extjs.gxt.ui.client.widget.form.Field; import com.extjs.gxt.ui.client.widget.form.FileUploadField; import com.google.gwt.user.client.ui.Widget; @@ -32,6 +31,8 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCallbackListener; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.EditableExperiment; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.ProjectSelectionWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil; @@ -69,7 +70,16 @@ public final class GenericExperimentEditForm private String originalProjectIdentifier; - public GenericExperimentEditForm(IViewContext<IGenericClientServiceAsync> viewContext, + public static DatabaseModificationAwareComponent create( + IViewContext<IGenericClientServiceAsync> viewContext, EditableExperiment entity, + boolean editMode) + { + GenericExperimentEditForm form = + new GenericExperimentEditForm(viewContext, entity, editMode); + return new DatabaseModificationAwareComponent(form, form); + } + + private GenericExperimentEditForm(IViewContext<IGenericClientServiceAsync> viewContext, EditableExperiment entity, boolean editMode) { super(viewContext, entity, editMode); @@ -174,14 +184,16 @@ public final class GenericExperimentEditForm return new ExperimentPropertyEditor(entityTypesPropertyTypes, properties, id, context); } + @SuppressWarnings("unchecked") @Override - protected List<Field<?>> getEntitySpecificFormFields() + protected List<DatabaseModificationAwareField<?>> getEntitySpecificFormFields() { - List<Field<?>> fields = new ArrayList<Field<?>>(); - fields.add(projectChooser); + List<DatabaseModificationAwareField<?>> fields = + new ArrayList<DatabaseModificationAwareField<?>>(); + fields.add(projectChooser.asDatabaseModificationAware()); for (FileUploadField f : attachmentManager.getFields()) { - fields.add(f); + fields.add(DatabaseModificationAwareField.wrapUnaware(f)); } return fields; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentRegistrationForm.java index aafe5a264ea814c60bdbd6ccd8fbf82a35d194d5..0c82099888293027bcbd58833d1dd7abaefe4dcf 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentRegistrationForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentRegistrationForm.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.experiment; +import static ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField.wrapUnaware; + import java.util.ArrayList; import java.util.List; @@ -31,6 +33,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCallbackListener; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.ProjectSelectionWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.StringUtils; @@ -197,14 +200,15 @@ public final class GenericExperimentRegistrationForm } @Override - protected List<Field<?>> getEntitySpecificFields() + protected List<DatabaseModificationAwareField<?>> getEntitySpecificFields() { - final ArrayList<Field<?>> fields = new ArrayList<Field<?>>(); - fields.add(projectSelectionWidget); - fields.add(samplesArea); + final ArrayList<DatabaseModificationAwareField<?>> fields = + new ArrayList<DatabaseModificationAwareField<?>>(); + fields.add(projectSelectionWidget.asDatabaseModificationAware()); + fields.add(wrapUnaware(samplesArea)); for (FileUploadField attachmentField : attachmentManager.getFields()) { - fields.add(attachmentField); + fields.add(wrapUnaware((Field<?>) attachmentField)); } return fields; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/PropertiesEditor.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/PropertiesEditor.java index 1e0081e22fd6f10d43e961471a89e0f6a365d68d..d5c40ba43bed2e0bcd2b5fabcea7da20bd55e18c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/PropertiesEditor.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/PropertiesEditor.java @@ -21,10 +21,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import com.extjs.gxt.ui.client.widget.form.Field; - import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.PropertyFieldFactory; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; @@ -40,7 +39,7 @@ abstract public class PropertiesEditor<T extends EntityType, S extends EntityTyp private final List<S> entityTypesPropertyTypes; - private final List<Field<?>> propertyFields; + private final List<DatabaseModificationAwareField<?>> propertyFields; private final String id; @@ -61,9 +60,11 @@ abstract public class PropertiesEditor<T extends EntityType, S extends EntityTyp this.propertyFields = createPropertyFields(viewContext); } - private List<Field<?>> createPropertyFields(IViewContext<ICommonClientServiceAsync> viewContext) + private List<DatabaseModificationAwareField<?>> createPropertyFields( + IViewContext<ICommonClientServiceAsync> viewContext) { - List<Field<?>> result = new ArrayList<Field<?>>(); + List<DatabaseModificationAwareField<?>> result = + new ArrayList<DatabaseModificationAwareField<?>>(); for (final S stpt : entityTypesPropertyTypes) { result.add(createPropertyField(stpt, initialProperties.get(stpt.getPropertyType() @@ -91,18 +92,18 @@ abstract public class PropertiesEditor<T extends EntityType, S extends EntityTyp this(id, entityTypesPropertyTypes, new ArrayList<P>(), viewContext); } - private final Field<?> createPropertyField(final S etpt, String value, + private final DatabaseModificationAwareField<?> createPropertyField(final S etpt, String value, IViewContext<ICommonClientServiceAsync> viewContext) { - final Field<?> field; + final DatabaseModificationAwareField<?> field; final boolean isMandatory = etpt.isMandatory(); final String label = etpt.getPropertyType().getLabel(); final String propertyTypeCode = etpt.getPropertyType().getCode(); field = PropertyFieldFactory.createField(etpt.getPropertyType(), isMandatory, label, createFormFieldId(getId(), propertyTypeCode), value, viewContext); - field.setData(ETPT, etpt); - field.setTitle(propertyTypeCode); + field.get().setData(ETPT, etpt); + field.get().setTitle(propertyTypeCode); return field; } @@ -122,14 +123,14 @@ abstract public class PropertiesEditor<T extends EntityType, S extends EntityTyp public final List<P> extractProperties() { final List<P> properties = new ArrayList<P>(); - for (final Field<?> field : propertyFields) + for (final DatabaseModificationAwareField<?> field : propertyFields) { - if (field.getValue() != null - && PropertyFieldFactory.valueToString(field.getValue()) != null) + Object value = field.get().getValue(); + if (value != null && PropertyFieldFactory.valueToString(value) != null) { - final S stpt = field.getData(ETPT); + final S stpt = field.get().getData(ETPT); final P sampleProperty = createEntityProperty(); - sampleProperty.setValue(PropertyFieldFactory.valueToString(field.getValue())); + sampleProperty.setValue(PropertyFieldFactory.valueToString(value)); sampleProperty.setEntityTypePropertyType(stpt); properties.add(sampleProperty); } @@ -141,7 +142,7 @@ abstract public class PropertiesEditor<T extends EntityType, S extends EntityTyp * Returns a list of fields appropriate for entity type - property type assignments specific to * given {@link PropertiesEditor}. */ - public final List<Field<?>> getPropertyFields() + public final List<DatabaseModificationAwareField<?>> getPropertyFields() { return propertyFields; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialEditForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialEditForm.java index a7a8b045d893519d8e7276f6365b9caa12989575..b72b52e97ed66bec930e92e75126ee2ab2fee151 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialEditForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialEditForm.java @@ -19,13 +19,14 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.ma import java.util.ArrayList; import java.util.List; -import com.extjs.gxt.ui.client.widget.form.Field; import com.google.gwt.user.client.ui.Widget; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCallbackListener; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.EditableMaterial; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialProperty; @@ -47,7 +48,15 @@ public final class GenericMaterialEditForm private final IViewContext<IGenericClientServiceAsync> viewContext; - public GenericMaterialEditForm(IViewContext<IGenericClientServiceAsync> viewContext, + public static DatabaseModificationAwareComponent create( + IViewContext<IGenericClientServiceAsync> viewContext, EditableMaterial entity, + boolean editMode) + { + GenericMaterialEditForm form = new GenericMaterialEditForm(viewContext, entity, editMode); + return new DatabaseModificationAwareComponent(form, form); + } + + private GenericMaterialEditForm(IViewContext<IGenericClientServiceAsync> viewContext, EditableMaterial entity, boolean editMode) { super(viewContext, entity, editMode); @@ -96,9 +105,9 @@ public final class GenericMaterialEditForm } @Override - protected List<Field<?>> getEntitySpecificFormFields() + protected List<DatabaseModificationAwareField<?>> getEntitySpecificFormFields() { - return new ArrayList<Field<?>>(); + return new ArrayList<DatabaseModificationAwareField<?>>(); } @Override diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleEditForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleEditForm.java index 9b18429e7dd9d8e25e52a81315ccb7c24ed34f53..28887c6a8e08063b3f6574d07513c6dd3fcab41e 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleEditForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleEditForm.java @@ -16,12 +16,13 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample; +import static ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField.wrapUnaware; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import com.extjs.gxt.ui.client.widget.form.Field; import com.google.gwt.user.client.ui.Widget; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; @@ -29,6 +30,8 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCallbackListener; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareComponent; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.EditableSample; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ExperimentChooserField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ExperimentChooserField.ExperimentChooserFieldAdaptor; @@ -62,7 +65,15 @@ public final class GenericSampleEditForm private final IViewContext<IGenericClientServiceAsync> viewContext; - public GenericSampleEditForm(IViewContext<IGenericClientServiceAsync> viewContext, + public static DatabaseModificationAwareComponent create( + IViewContext<IGenericClientServiceAsync> viewContext, EditableSample entity, + boolean editMode) + { + GenericSampleEditForm form = new GenericSampleEditForm(viewContext, entity, editMode); + return new DatabaseModificationAwareComponent(form, form); + } + + private GenericSampleEditForm(IViewContext<IGenericClientServiceAsync> viewContext, EditableSample entity, boolean editMode) { super(viewContext, entity, editMode); @@ -125,12 +136,13 @@ public final class GenericSampleEditForm } @Override - protected List<Field<?>> getEntitySpecificFormFields() + protected List<DatabaseModificationAwareField<?>> getEntitySpecificFormFields() { - ArrayList<Field<?>> fields = new ArrayList<Field<?>>(); + ArrayList<DatabaseModificationAwareField<?>> fields = + new ArrayList<DatabaseModificationAwareField<?>>(); if (experimentFieldOrNull != null) { - fields.add(experimentFieldOrNull.getField()); + fields.add(wrapUnaware(experimentFieldOrNull.getField())); } return fields; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleRegistrationForm.java index 7fd4c349082de67343922e1afc18dfa75677860a..287343c8d74dcdb1e875f2185fe3f62b560f51f0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleRegistrationForm.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleRegistrationForm.java @@ -16,10 +16,11 @@ package ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample; +import static ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField.wrapUnaware; + import java.util.ArrayList; import java.util.List; -import com.extjs.gxt.ui.client.widget.form.Field; import com.extjs.gxt.ui.client.widget.form.TextField; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; @@ -27,6 +28,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCallbackListener; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.GroupSelectionWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.VarcharField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil; @@ -145,12 +147,13 @@ public final class GenericSampleRegistrationForm extends } @Override - protected List<Field<?>> getEntitySpecificFields() + protected List<DatabaseModificationAwareField<?>> getEntitySpecificFields() { - List<Field<?>> fields = new ArrayList<Field<?>>(); - fields.add(groupSelectionWidget); - fields.add(parent); - fields.add(container); + List<DatabaseModificationAwareField<?>> fields = + new ArrayList<DatabaseModificationAwareField<?>>(); + fields.add(groupSelectionWidget.asDatabaseModificationAware()); + fields.add(wrapUnaware(parent)); + fields.add(wrapUnaware(container)); return fields; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java index 38bb0ebb8cd9425f73b0c9e7a88e417e716e5afe..93052f82c20263f7996bfba6a5380a7a5d2cc6f9 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java @@ -25,6 +25,7 @@ import com.google.gwt.user.client.ui.Widget; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractClientPluginFactory; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareWidget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DefaultTabItem; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DummyComponent; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.ITabItem; @@ -138,9 +139,10 @@ public final class ClientPluginFactory extends }; } - public final Widget createRegistrationForEntityType(final SampleType sampleTypeCode) + public final DatabaseModificationAwareWidget createRegistrationForEntityType( + final SampleType sampleTypeCode) { - return new DummyComponent(); + return DatabaseModificationAwareWidget.wrapUnaware(new DummyComponent()); } public final Widget createBatchRegistrationForEntityType(final SampleType sampleType) diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected index ebaa7f070166032da392594ab48fbdcd9317d452..43ff1e8f3598ebeb0c24080bcf5ad8a0a5f32e5d 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.shared; import java.util.Date; import java.util.List; +import java.util.Set; import org.springframework.transaction.annotation.Transactional; @@ -67,6 +68,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.SearchHit; import ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; @@ -315,6 +317,7 @@ public interface ICommonServer extends IServer */ @Transactional @RolesAllowed(RoleSet.INSTANCE_ADMIN) + @DatabaseCreateOrDeleteModification(value = ObjectKind.VOCABULARY_TERM) public void deleteVocabularyTerms(String sessionToken, String vocabularyCode, List<VocabularyTerm> termsToBeDeleted, List<VocabularyTermReplacement> termsToBeReplaced); @@ -437,11 +440,18 @@ public interface ICommonServer extends IServer /** * Lists vocabulary terms of a given vocabulary. Includes terms usage statistics. */ - @Transactional - @RolesAllowed(RoleSet.USER) - public List<VocabularyTermWithStats> listVocabularyTerms(String sessionToken, + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public List<VocabularyTermWithStats> listVocabularyTermsWithStatistics(String sessionToken, Vocabulary vocabulary); + /** + * Lists vocabulary terms of a given vocabulary. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleSet.OBSERVER) + public Set<VocabularyTermPE> listVocabularyTerms(String sessionToken, Vocabulary vocabulary); + /** * List data set types. *