diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPropertiesPanel.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPropertiesPanel.java index f4422d3d2e8da5c1b3dc196359fca9dc3f90c5f6..5b78a235a7023d616e21a53e13081de234f93a14 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPropertiesPanel.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPropertiesPanel.java @@ -30,11 +30,14 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; @@ -43,6 +46,8 @@ import javax.swing.JTextField; import ch.systemsx.cisd.openbis.dss.client.api.gui.DataSetUploadClientModel.NewDataSetInfo; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTOBuilder; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ControlledVocabularyPropertyType; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ControlledVocabularyPropertyType.VocabularyTerm; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyTypeGroup; @@ -54,11 +59,32 @@ public class DataSetPropertiesPanel extends JPanel { private static final long serialVersionUID = 1L; + /** + * An adaptor to convert VocabularyTerms into something that can be put into combo boxes. + * + * @author Chandrasekhar Ramakrishnan + */ + private static final class VocabularyTermAdaptor + { + private final VocabularyTerm term; + + private VocabularyTermAdaptor(VocabularyTerm term) + { + this.term = term; + } + + @Override + public String toString() + { + return term.getLabel(); + } + } + private final DataSetType dataSetType; private final DataSetUploadClientModel clientModel; - private final HashMap<String, JTextField> formFields = new HashMap<String, JTextField>(); + private final HashMap<String, JComponent> formFields = new HashMap<String, JComponent>(); private NewDataSetInfo newDataSetInfo; @@ -123,7 +149,23 @@ public class DataSetPropertiesPanel extends JPanel label.setFont(label.getFont().deriveFont(Font.BOLD | Font.ITALIC)); } + final JComponent formField; + if (propertyType instanceof ControlledVocabularyPropertyType) + { + formField = createComboBox((ControlledVocabularyPropertyType) propertyType); + } else + { + formField = createTextField(propertyType); + } + formField.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT)); + addFormField(col, row, label, formField); + formFields.put(propertyType.getCode(), formField); + } + + private JTextField createTextField(final PropertyType propertyType) + { final JTextField textField = new JTextField(); + textField.setToolTipText(propertyType.getDescription()); textField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -144,9 +186,27 @@ public class DataSetPropertiesPanel extends JPanel // Do nothing } }); - textField.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT)); - addFormField(col, row, label, textField); - formFields.put(propertyType.getCode(), textField); + return textField; + } + + private JComboBox createComboBox(final ControlledVocabularyPropertyType propertyType) + { + final JComboBox comboBox = new JComboBox(); + comboBox.setToolTipText(propertyType.getDescription()); + for (VocabularyTerm term : propertyType.getTerms()) + { + comboBox.addItem(new VocabularyTermAdaptor(term)); + } + comboBox.addItemListener(new ItemListener() + { + public void itemStateChanged(ItemEvent e) + { + setPropertyValue(propertyType, + ((VocabularyTermAdaptor) e.getItem()).term.getCode()); + } + + }); + return comboBox; } private String getLabelStringForPropertyType(PropertyType propertyType) @@ -207,8 +267,24 @@ public class DataSetPropertiesPanel extends JPanel Map<String, String> props = metadata.getProperties(); for (String propertyTypeCode : formFields.keySet()) { - JTextField textField = formFields.get(propertyTypeCode); - textField.setText(props.get(propertyTypeCode)); + String propertyValue = props.get(propertyTypeCode); + JComponent formField = formFields.get(propertyTypeCode); + if (formField instanceof JTextField) + { + JTextField textField = (JTextField) formField; + textField.setText(propertyValue); + } else if (formField instanceof JComboBox) + { + JComboBox comboBox = (JComboBox) formField; + for (int i = 0; i < comboBox.getItemCount(); ++i) + { + VocabularyTermAdaptor adaptor = (VocabularyTermAdaptor) comboBox.getItemAt(i); + if (adaptor.term.getCode().equals(propertyValue)) + { + comboBox.setSelectedIndex(i); + } + } + } } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java index e4c799f70a501df03a65f5270208ac4d755ac0a1..4ee17e744d4afd40ff95397c0125b5886cb2b1ac 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java @@ -41,6 +41,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDatabaseInstanceDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataDAO; import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ControlledVocabularyPropertyType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment; @@ -387,11 +388,31 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType> privateDataSetTypes = commonServer.listDataSetTypes(sessionToken); + HashMap<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary, List<ControlledVocabularyPropertyType.VocabularyTerm>> vocabTerms = + getVocabularyTermsMap(sessionToken); + ArrayList<DataSetType> dataSetTypes = new ArrayList<DataSetType>(); for (ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType privateDataSetType : privateDataSetTypes) { - dataSetTypes.add(Translator.translate(privateDataSetType)); + dataSetTypes.add(Translator.translate(privateDataSetType, vocabTerms)); } return dataSetTypes; } + + private HashMap<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary, List<ControlledVocabularyPropertyType.VocabularyTerm>> getVocabularyTermsMap( + String sessionToken) + { + HashMap<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary, List<ControlledVocabularyPropertyType.VocabularyTerm>> vocabTerms = + new HashMap<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary, List<ControlledVocabularyPropertyType.VocabularyTerm>>(); + List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary> privateVocabularies = + commonServer.listVocabularies(sessionToken, false, false); + for (ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary privateVocabulary : privateVocabularies) + { + Set<ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm> privateTerms = + commonServer.listVocabularyTerms(sessionToken, privateVocabulary); + + vocabTerms.put(privateVocabulary, Translator.translate(privateTerms)); + } + return vocabTerms; + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/Translator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/Translator.java index af2af7e135aad9af90afc520eff8c4b72c1e2aee..5b64b638eb98f3720b7b82295035dcf4713990c0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/Translator.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/Translator.java @@ -16,9 +16,15 @@ package ch.systemsx.cisd.openbis.generic.server.api.v1; +import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Set; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ControlledVocabularyPropertyType; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ControlledVocabularyPropertyType.ControlledVocabularyPropertyTypeInitializer; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet.DataSetInitializer; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType; @@ -32,8 +38,10 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.PropertyTypeGroup.Prop import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample.SampleInitializer; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleLevel; @@ -97,7 +105,8 @@ public class Translator } static DataSetType translate( - ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType privateDataSetType) + ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType privateDataSetType, + HashMap<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary, List<ControlledVocabularyPropertyType.VocabularyTerm>> vocabTerms) { DataSetTypeInitializer initializer = new DataSetTypeInitializer(); initializer.setCode(privateDataSetType.getCode()); @@ -124,15 +133,38 @@ public class Translator groupInitializer = new PropertyTypeGroupInitializer(); sectionName = thisSectionName; } - PropertyTypeInitializer ptInitializer = new PropertyTypeInitializer(); + PropertyTypeInitializer ptInitializer; ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType propertyType = dstpt.getPropertyType(); + + boolean isControlledVocabulary = + propertyType.getDataType().getCode() == DataTypeCode.CONTROLLEDVOCABULARY; + if (isControlledVocabulary) + { + ControlledVocabularyPropertyTypeInitializer cvptInitializer = + new ControlledVocabularyPropertyTypeInitializer(); + + cvptInitializer.setTerms(vocabTerms.get(propertyType.getVocabulary())); + ptInitializer = cvptInitializer; + } else + { + ptInitializer = new PropertyTypeInitializer(); + } + ptInitializer.setDataType(propertyType.getDataType().getCode()); ptInitializer.setCode(propertyType.getCode()); ptInitializer.setLabel(propertyType.getLabel()); ptInitializer.setDescription(propertyType.getDescription()); ptInitializer.setMandatory(dstpt.isMandatory()); - groupInitializer.addPropertyType(new PropertyType(ptInitializer)); + + if (isControlledVocabulary) + { + groupInitializer.addPropertyType(new ControlledVocabularyPropertyType( + (ControlledVocabularyPropertyTypeInitializer) ptInitializer)); + } else + { + groupInitializer.addPropertyType(new PropertyType(ptInitializer)); + } } // Finally set the group initializer.addPropertyTypeGroup(new PropertyTypeGroup(groupInitializer)); @@ -140,8 +172,31 @@ public class Translator return new DataSetType(initializer); } - private Translator() + public static List<ControlledVocabularyPropertyType.VocabularyTerm> translate( + Set<ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm> privateTerms) { + ArrayList<ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm> sortedTerms = + new ArrayList<ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm>( + privateTerms); + Collections.sort(sortedTerms, + new Comparator<ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm>() + { + + public int compare(VocabularyTerm o1, VocabularyTerm o2) + { + return o1.getOrdinal().compareTo(o2.getOrdinal()); + } + + }); + ArrayList<ControlledVocabularyPropertyType.VocabularyTerm> terms = + new ArrayList<ControlledVocabularyPropertyType.VocabularyTerm>(); + for (ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm privateTerm : sortedTerms) + { + terms.add(new ControlledVocabularyPropertyType.VocabularyTerm(privateTerm.getCode(), + privateTerm.getCodeOrLabel())); + } + + return terms; } public static DataSet translate(ExternalData externalDatum) @@ -160,4 +215,8 @@ public class Translator return new DataSet(initializer); } + + private Translator() + { + } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/ControlledVocabularyPropertyType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/ControlledVocabularyPropertyType.java new file mode 100644 index 0000000000000000000000000000000000000000..760a96d839ee82fc2fa0f4900d8c521ce789289c --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/ControlledVocabularyPropertyType.java @@ -0,0 +1,132 @@ +/* + * Copyright 2011 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.shared.api.v1.dto; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * @author Chandrasekhar Ramakrishnan + */ +public class ControlledVocabularyPropertyType extends PropertyType +{ + private static final long serialVersionUID = 1L; + + public static class VocabularyTerm implements Serializable + { + private static final long serialVersionUID = 1L; + + private final String code; + + private final String label; + + public VocabularyTerm(String code, String label) + { + this.code = code; + this.label = label; + } + + public String getCode() + { + return code; + } + + public String getLabel() + { + return label; + } + + @Override + public boolean equals(Object obj) + { + if (obj == this) + { + return true; + } + if (obj instanceof VocabularyTerm == false) + { + return false; + } + + EqualsBuilder builder = new EqualsBuilder(); + VocabularyTerm other = (VocabularyTerm) obj; + builder.append(getCode(), other.getCode()); + return builder.isEquals(); + } + + @Override + public int hashCode() + { + HashCodeBuilder builder = new HashCodeBuilder(); + builder.append(getCode()); + return builder.toHashCode(); + } + + @Override + public String toString() + { + ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); + builder.append(getCode()); + builder.append(getLabel()); + return builder.toString(); + } + } + + public static class ControlledVocabularyPropertyTypeInitializer extends PropertyTypeInitializer + { + private final ArrayList<VocabularyTerm> terms = new ArrayList<VocabularyTerm>(); + + public void setTerms(List<VocabularyTerm> validValues) + { + this.terms.clear(); + this.terms.addAll(validValues); + } + } + + private final ArrayList<VocabularyTerm> terms; + + /** + * @param initializer + */ + public ControlledVocabularyPropertyType(ControlledVocabularyPropertyTypeInitializer initializer) + { + super(initializer); + terms = initializer.terms; + if (terms == null || terms.isEmpty()) + { + throw new IllegalArgumentException( + "A controlled vocabulary property type must have terms"); + } + } + + public List<VocabularyTerm> getTerms() + { + return terms; + } + + @Override + protected void appendFieldsToStringBuilder(ToStringBuilder builder) + { + builder.append(terms); + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/PropertyType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/PropertyType.java index dc0520d70a586605a75bb51eba0c2e68b2c39913..d87dfaf1a59cb7201a90767dbf60f5074e7222de 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/PropertyType.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/PropertyType.java @@ -30,7 +30,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; * * @author Chandrasekhar Ramakrishnan */ -public final class PropertyType implements Serializable +public class PropertyType implements Serializable { private static final long serialVersionUID = 1L; @@ -40,7 +40,7 @@ public final class PropertyType implements Serializable * * @author Chandrasekhar Ramakrishnan */ - public static final class PropertyTypeInitializer + public static class PropertyTypeInitializer { private DataTypeCode dataType; @@ -101,7 +101,6 @@ public final class PropertyType implements Serializable { this.mandatory = mandatory; } - } private final DataTypeCode dataType; @@ -214,6 +213,15 @@ public final class PropertyType implements Serializable builder.append(getLabel()); builder.append(getDescription()); builder.append(isMandatory() ? "mandatory" : "optional"); + this.appendFieldsToStringBuilder(builder); return builder.toString(); } + + /** + * For subclasses to override + */ + protected void appendFieldsToStringBuilder(ToStringBuilder builder) + { + + } }