From a1359875db847d5c105b6077a0cb1cce91164343 Mon Sep 17 00:00:00 2001
From: buczekp <buczekp>
Date: Tue, 10 May 2011 12:23:45 +0000
Subject: [PATCH] [LMS-2104] basic support for virtual data sets in UI

SVN: 21197
---
 .../server/CommonBusinessObjectFactory.java   |   7 +
 .../openbis/generic/server/CommonServer.java  |  15 +-
 .../authorization/PredicateExecutor.java      |   3 +-
 .../generic/server/business/bo/DataBO.java    |  11 +-
 .../server/business/bo/ExternalDataBO.java    |   4 +-
 .../bo/ICommonBusinessObjectFactory.java      |   2 +
 .../server/business/bo/IExternalDataBO.java   |   2 +-
 .../openbis/generic/shared/dto/DataPE.java    |   7 +-
 .../shared/translator/DataSetTranslator.java  | 337 ++++++++++++++++++
 .../dataset/DataSetPropertiesPanel.java       |   7 +-
 10 files changed, 375 insertions(+), 20 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
index c4f929b587c..03c33da6c77 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
@@ -20,6 +20,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory
 import ch.systemsx.cisd.openbis.generic.server.business.bo.AbstractBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.AttachmentBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.AuthorizationGroupBO;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.DataBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.EntityTypeBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.EntityTypePropertyTypeBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ExperimentBO;
@@ -32,6 +33,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.GroupBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IAttachmentBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IAuthorizationGroupBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IEntityTypeBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IEntityTypePropertyTypeBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
@@ -131,6 +133,11 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
         return new SampleBO(getDaoFactory(), session);
     }
 
+    public IDataBO createDataBO(Session session)
+    {
+        return new DataBO(getDaoFactory(), session);
+    }
+
     public IExternalDataBO createExternalDataBO(Session session)
     {
         return new ExternalDataBO(getDaoFactory(), session);
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 8f546a76516..066e519f5ac 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
@@ -43,6 +43,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.DataAccessExceptionTr
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IAttachmentBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IAuthorizationGroupBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IEntityTypeBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IEntityTypePropertyTypeBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
@@ -138,11 +139,11 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PersonAdapter;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleAssignment;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleUpdateResult;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleUpdateResult;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Script;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ScriptType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
@@ -157,6 +158,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IPerson;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentHolderPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AuthorizationGroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
@@ -202,6 +204,7 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.AttachmentTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.AuthorizationGroupTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTypeTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.DataStoreServiceTranslator;
+import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.DataTypeTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.DtoConverters;
 import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator;
@@ -890,14 +893,14 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
     public ExternalData getDataSetInfo(final String sessionToken, final TechId datasetId)
     {
         final Session session = getSession(sessionToken);
-        final IExternalDataBO datasetBO = businessObjectFactory.createExternalDataBO(session);
+        final IDataBO datasetBO = businessObjectFactory.createDataBO(session);
         datasetBO.loadDataByTechId(datasetId);
         datasetBO.enrichWithParentsAndExperiment();
         datasetBO.enrichWithChildren();
-        datasetBO.enrichWithContainedDatas();
+        datasetBO.enrichWithContainedDataSets();
         datasetBO.enrichWithProperties();
-        final ExternalDataPE dataset = datasetBO.getExternalData();
-        return ExternalDataTranslator.translate(dataset, session.getBaseIndexURL(), false);
+        final DataPE dataset = datasetBO.getData();
+        return DataSetTranslator.translate(dataset, session.getBaseIndexURL(), false);
     }
 
     public List<ExternalData> listRelatedDataSets(String sessionToken,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java
index 17527f8f14a..d1b78c2de11 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java
@@ -43,7 +43,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetAccessPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GridCustomColumnPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GridCustomFilterPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PermId;
@@ -379,7 +378,7 @@ public final class PredicateExecutor
             switch (kind)
             {
                 case DATASET:
-                    ExternalDataPE dataset = daoFactory.getExternalDataDAO().getByTechId(techId);
+                    DataPE dataset = daoFactory.getDataDAO().getByTechId(techId);
                     return dataset.getExperiment().getProject().getSpace();
                 case EXPERIMENT:
                     ExperimentPE experiment = daoFactory.getExperimentDAO().getByTechId(techId);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
index f668fba0526..d05e106ab22 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
@@ -29,7 +29,6 @@ import ch.systemsx.cisd.common.collections.CollectionUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IVocabularyDAO;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus;
@@ -102,7 +101,7 @@ public class DataBO extends AbstractExternalDataBusinessObject implements IDataB
     private void loadByCode(String dataSetCode, boolean withPropertyTypes, boolean lockForUpdate)
     {
         data =
-                getExternalDataDAO().tryToFindFullDataSetByCode(dataSetCode, withPropertyTypes,
+                getDataDAO().tryToFindFullDataSetByCode(dataSetCode, withPropertyTypes,
                         lockForUpdate);
     }
 
@@ -114,7 +113,7 @@ public class DataBO extends AbstractExternalDataBusinessObject implements IDataB
     {
         String[] connections =
             { PROPERTY_TYPES, DATA_SET_TYPE };
-        data = getExternalDataDAO().tryGetByTechId(datasetId, connections);
+        data = getDataDAO().tryGetByTechId(datasetId, connections);
         if (data == null)
         {
             throw new UserFailureException(String.format("Data set with ID '%s' does not exist.",
@@ -303,7 +302,7 @@ public class DataBO extends AbstractExternalDataBusinessObject implements IDataB
     {
         assert parentDataSetCode != null : "Unspecified parent data set code.";
 
-        final IExternalDataDAO dataDAO = getExternalDataDAO();
+        final IDataDAO dataDAO = getDataDAO();
         DataPE parent = dataDAO.tryToFindDataSetByCode(parentDataSetCode);
         if (parent == null)
         {
@@ -516,7 +515,7 @@ public class DataBO extends AbstractExternalDataBusinessObject implements IDataB
 
     private Set<TechId> findParentIds(Set<TechId> dataSetIds)
     {
-        return getExternalDataDAO().findParentIds(dataSetIds);
+        return getDataDAO().findParentIds(dataSetIds);
     }
 
     private Collection<DataPE> filterDataSets(Collection<DataPE> dataSets,
@@ -551,7 +550,7 @@ public class DataBO extends AbstractExternalDataBusinessObject implements IDataB
 
     private List<DataPE> findDataSetsByCodes(Set<String> codes)
     {
-        final IExternalDataDAO dao = getExternalDataDAO();
+        final IDataDAO dao = getDataDAO();
         final List<DataPE> dataSets = new ArrayList<DataPE>();
         final List<String> missingDataSetCodes = new ArrayList<String>();
         for (String code : codes)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBO.java
index 72e2757702e..768297549e5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExternalDataBO.java
@@ -145,9 +145,9 @@ public class ExternalDataBO extends AbstractExternalDataBusinessObject implement
         }
     }
 
-    public void enrichWithContainedDatas()
+    public void enrichWithContainedDataSets()
     {
-        if (externalData != null && externalData.getDataSetType().isContainerType())
+        if (externalData != null && externalData.isContainer())
         {
             HibernateUtils.initialize(externalData.getContainedDataSets());
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java
index 21d3feec274..4d7c308835c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java
@@ -44,6 +44,8 @@ public interface ICommonBusinessObjectFactory
 
     public IExternalDataBO createExternalDataBO(Session session);
 
+    public IDataBO createDataBO(Session session);
+
     public IExternalDataTable createExternalDataTable(final Session session);
 
     public IExperimentTable createExperimentTable(final Session session);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataBO.java
index dc1a502c398..5eabf47e589 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IExternalDataBO.java
@@ -110,7 +110,7 @@ public interface IExternalDataBO extends IEntityBusinessObject
     /**
      * Enrich external data with virtual children.
      */
-    public void enrichWithContainedDatas();
+    public void enrichWithContainedDataSets();
 
     /**
      * Enrich external data with properties.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java
index bcb67099e8a..3e66ebae598 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java
@@ -419,7 +419,12 @@ public class DataPE extends AbstractIdAndCodeHolder<DataPE> implements
         this.children.remove(child);
     }
 
-    @SuppressWarnings("unused")
+    @Transient
+    public DataPE getContainer()
+    {
+        return getContainerInternal();
+    }
+
     @ManyToOne(fetch = FetchType.EAGER, targetEntity = DataPE.class)
     @JoinColumn(name = ColumnNames.DATA_CONTAINER_COLUMN)
     private DataPE getContainerInternal()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java
new file mode 100644
index 00000000000..a8c5ea9c2a3
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java
@@ -0,0 +1,337 @@
+/*
+ * 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.shared.translator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+import ch.systemsx.cisd.common.types.BooleanOrUnknown;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolder;
+import ch.systemsx.cisd.openbis.generic.shared.basic.PermlinkUtilities;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType;
+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.Invalidation;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.InvalidationPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator.LoadableFields;
+import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class DataSetTranslator
+{
+    private DataSetTranslator()
+    {
+    }
+
+    public static DatasetDescription translateToDescription(ExternalData data)
+    {
+        DatasetDescription description = new DatasetDescription();
+        description.setDatasetCode(data.getCode());
+
+        DataSet dataSet = data.tryGetAsDataSet();
+        if (dataSet != null)
+        {
+            // TODO KE: 2011-05-06 make sure this other classes handle NULL correctly
+            description.setDataSetLocation(dataSet.getLocation());
+            description.setSpeedHint(dataSet.getSpeedHint());
+        }
+        description.setDataSetSize(data.getSize());
+        DataSetType dataSetType = data.getDataSetType();
+        if (dataSetType != null)
+        {
+            description.setDatasetTypeCode(dataSetType.getCode());
+        }
+        Experiment experiment = data.getExperiment();
+        if (experiment != null)
+        {
+            description.setExperimentCode(experiment.getCode());
+            description.setExperimentIdentifier(experiment.getIdentifier());
+            Project project = experiment.getProject();
+            if (project != null)
+            {
+                description.setProjectCode(project.getCode());
+                Space space = project.getSpace();
+                if (space != null)
+                {
+                    description.setSpaceCode(space.getCode());
+                    DatabaseInstance instance = space.getInstance();
+                    if (instance != null)
+                    {
+                        description.setDatabaseInstanceCode(instance.getCode());
+                    }
+                }
+            }
+            ExperimentType experimentType = experiment.getExperimentType();
+            if (experimentType != null)
+            {
+                description.setExperimentTypeCode(experimentType.getCode());
+            }
+        }
+        Sample sample = data.getSample();
+        if (sample != null)
+        {
+            description.setSampleCode(sample.getCode());
+            description.setSampleIdentifier(sample.getIdentifier());
+            SampleType sampleType = sample.getSampleType();
+            if (sampleType != null)
+            {
+                description.setSampleTypeCode(sampleType.getCode());
+            }
+        }
+        return description;
+    }
+
+    public static List<ExternalData> translate(List<DataPE> list, String defaultDataStoreBaseURL,
+            String baseIndexURL)
+    {
+        ArrayList<ExternalData> result = new ArrayList<ExternalData>(list.size());
+        for (DataPE dataPE : list)
+        {
+            ExternalData data =
+                    translate(dataPE, baseIndexURL, true,
+                            ExperimentTranslator.LoadableFields.PROPERTIES);
+            result.add(data);
+        }
+        return result;
+    }
+
+    public static ExternalData translate(DataPE dataPE, String baseIndexURL,
+            final LoadableFields... withExperimentFields)
+    {
+        return translate(dataPE, baseIndexURL, true, withExperimentFields);
+    }
+
+    public static ExternalData translate(DataPE dataPE, String baseIndexURL, boolean withDetails,
+            final LoadableFields... withExperimentFields)
+    {
+        ExternalData externalData = null;
+        if (dataPE.isContainer())
+        {
+            externalData = translateContainerDataSetProperties(dataPE, withDetails);
+        } else
+        {
+            externalData = translateDataSetProperties(dataPE);
+        }
+
+        SamplePE sampleOrNull = dataPE.tryGetSample();
+        ExperimentPE experiment = dataPE.getExperiment();
+        externalData.setId(HibernateUtils.getId(dataPE));
+        externalData.setCode(dataPE.getCode());
+        externalData.setDataProducerCode(dataPE.getDataProducerCode());
+        externalData.setDataSetType(DataSetTypeTranslator.translate(dataPE.getDataSetType(),
+                new HashMap<PropertyTypePE, PropertyType>()));
+        externalData.setDerived(dataPE.isDerived());
+        externalData.setInvalidation(tryToGetInvalidation(sampleOrNull, experiment));
+        externalData.setContainer(tryToTranslateContainer(dataPE.getContainer(), baseIndexURL));
+        final Collection<ExternalData> parents = new HashSet<ExternalData>();
+        externalData.setParents(parents);
+        for (DataPE parentPE : dataPE.getParents())
+        {
+            parents.add(translateBasicProperties(parentPE));
+        }
+        setChildren(dataPE, externalData);
+        externalData.setProductionDate(dataPE.getProductionDate());
+        externalData.setModificationDate(dataPE.getModificationDate());
+        externalData.setRegistrator(PersonTranslator.translate(dataPE.getRegistrator()));
+        externalData.setRegistrationDate(dataPE.getRegistrationDate());
+        externalData.setSample(sampleOrNull == null ? null : fillSample(new Sample(), sampleOrNull,
+                withDetails));
+        externalData.setDataStore(DataStoreTranslator.translate(dataPE.getDataStore()));
+        externalData.setPermlink(PermlinkUtilities.createPermlinkURL(baseIndexURL,
+                EntityKind.DATA_SET, externalData.getIdentifier()));
+        setProperties(dataPE, externalData);
+        externalData.setExperiment(ExperimentTranslator.translate(experiment, baseIndexURL,
+                withExperimentFields));
+
+        return externalData;
+    }
+
+    private static ContainerDataSet tryToTranslateContainer(DataPE containerOrNull,
+            String baseIndexURL)
+    {
+        return containerOrNull != null ? (ContainerDataSet) translate(containerOrNull,
+                baseIndexURL, false) : null;
+    }
+
+    private static ExternalData translateContainerDataSetProperties(DataPE dataPE,
+            boolean withComponents)
+    {
+        ContainerDataSet containerDataSet = new ContainerDataSet();
+        if (withComponents)
+        {
+            setContainedDataSets(dataPE, containerDataSet);
+        }
+        return containerDataSet;
+    }
+
+    private static ExternalData translateDataSetProperties(DataPE dataPE)
+    {
+        assert dataPE instanceof ExternalDataPE;
+
+        ExternalDataPE externalDataPE = (ExternalDataPE) dataPE;
+        DataSet dataSet = new DataSet();
+        dataSet.setSize(externalDataPE.getSize());
+        dataSet.setComplete(BooleanOrUnknown.tryToResolve(externalDataPE.getComplete()));
+        dataSet.setStatus(externalDataPE.getStatus());
+        dataSet.setSpeedHint(externalDataPE.getSpeedHint());
+        dataSet.setFileFormatType(TypeTranslator.translate(externalDataPE.getFileFormatType()));
+        dataSet.setLocation(externalDataPE.getLocation());
+        dataSet.setLocatorType(TypeTranslator.translate(externalDataPE.getLocatorType()));
+        return dataSet;
+    }
+
+    private static void setProperties(DataPE dataPE, ExternalData externalData)
+    {
+        if (HibernateUtils.isInitialized(dataPE.getProperties()))
+        {
+            externalData.setDataSetProperties(EntityPropertyTranslator.translate(
+                    dataPE.getProperties(), new HashMap<PropertyTypePE, PropertyType>()));
+        } else
+        {
+            externalData.setDataSetProperties(new ArrayList<IEntityProperty>());
+        }
+    }
+
+    private static Invalidation tryToGetInvalidation(SamplePE sampleOrNull, ExperimentPE experiment)
+    {
+        InvalidationPE invalidationOrNull;
+        if (sampleOrNull != null)
+        {
+            invalidationOrNull = tryToGetInvalidationPE(sampleOrNull);
+        } else
+        {
+            invalidationOrNull = tryToGetInvalidationPE(experiment);
+        }
+        return translateInvalidation(invalidationOrNull);
+    }
+
+    private static InvalidationPE tryToGetInvalidationPE(SamplePE sampleOrNull)
+    {
+        if (sampleOrNull != null)
+        {
+            return sampleOrNull.getInvalidation();
+        } else
+        {
+            return null;
+        }
+    }
+
+    private static InvalidationPE tryToGetInvalidationPE(ExperimentPE experiment)
+    {
+        if (experiment != null)
+        {
+            return experiment.getInvalidation();
+        } else
+        {
+            return null;
+        }
+    }
+
+    private static Invalidation translateInvalidation(InvalidationPE invalidationPE)
+    {
+        if (invalidationPE == null)
+        {
+            return null;
+        }
+        Invalidation result = new Invalidation();
+        result.setReason(invalidationPE.getReason());
+        result.setRegistrationDate(invalidationPE.getRegistrationDate());
+        result.setRegistrator(PersonTranslator.translate(invalidationPE.getRegistrator()));
+        return result;
+    }
+
+    private static Sample fillSample(Sample sample, SamplePE samplePE, boolean loadSampleProperties)
+    {
+        sample.setId(HibernateUtils.getId(samplePE));
+        sample.setPermId(samplePE.getPermId());
+        SampleTranslator.setCodes(sample, samplePE);
+        sample.setInvalidation(translateInvalidation(samplePE.getInvalidation()));
+        sample.setSampleType(TypeTranslator.translate(samplePE.getSampleType()));
+        sample.setIdentifier(samplePE.getSampleIdentifier().toString());
+        sample.setRegistrationDate(samplePE.getRegistrationDate());
+        sample.setRegistrator(PersonTranslator.translate(samplePE.getRegistrator()));
+        sample.setSpace(GroupTranslator.translate(samplePE.getSpace()));
+        if (loadSampleProperties)
+        {
+            sample.setProperties(EntityPropertyTranslator.translate(samplePE.getProperties(),
+                    new HashMap<PropertyTypePE, PropertyType>()));
+        }
+        return sample;
+    }
+
+    private static void setChildren(DataPE dataPE, ExternalData externalData)
+    {
+        List<ExternalData> children = new ArrayList<ExternalData>();
+        if (HibernateUtils.isInitialized(dataPE.getChildren()))
+        {
+            for (DataPE childPE : dataPE.getChildren())
+            {
+                children.add(translateBasicProperties(childPE));
+            }
+        }
+        externalData.setChildren(children);
+    }
+
+    private static void setContainedDataSets(DataPE dataPE, ContainerDataSet containerDataSet)
+    {
+        List<ExternalData> containedDataSets = new ArrayList<ExternalData>();
+        if (HibernateUtils.isInitialized(dataPE.getContainedDataSets()))
+        {
+            for (DataPE childPE : dataPE.getContainedDataSets())
+            {
+                containedDataSets.add(translateBasicProperties(childPE));
+            }
+        }
+        containerDataSet.setContainedDataSets(containedDataSets);
+    }
+
+    /**
+     * Creates an <var>externalData</var> from <var>dataPE</vra> an fills it with all data needed by
+     * {@link IEntityInformationHolder}.
+     */
+    private static ExternalData translateBasicProperties(DataPE dataPE)
+    {
+        ExternalData result = new ExternalData();
+        result.setId(HibernateUtils.getId(dataPE));
+        result.setCode(dataPE.getCode());
+        result.setDataSetType(DataSetTypeTranslator.translate(dataPE.getDataSetType(),
+                new HashMap<PropertyTypePE, PropertyType>()));
+        return result;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetPropertiesPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetPropertiesPanel.java
index f2f0a107c3b..9efd8c25cca 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetPropertiesPanel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/dataset/DataSetPropertiesPanel.java
@@ -123,8 +123,11 @@ public class DataSetPropertiesPanel extends ContentPanel
         properties.put(messageProvider.getMessage(Dict.REGISTRATOR), dataset.getRegistrator());
         properties.put(messageProvider.getMessage(Dict.REGISTRATION_DATE),
                 dataset.getRegistrationDate());
-        properties.put(messageProvider.getMessage(Dict.CONTAINER_DATA_SET),
-                dataset.tryGetContainer());
+        DataSet containerOrNull = dataset.tryGetAsDataSet();
+        if (containerOrNull != null)
+        {
+            properties.put(messageProvider.getMessage(Dict.CONTAINER_DATA_SET), containerOrNull);
+        }
         properties.put(messageProvider.getMessage(Dict.PROJECT), dataset.getExperiment()
                 .getProject());
         properties.put(messageProvider.getMessage(Dict.EXPERIMENT), dataset.getExperiment());
-- 
GitLab