Java tutorial
/* * 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.plugin.generic.client.web.server; import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Component; import org.springframework.transaction.TransactionSystemException; import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.io.DelegatedReader; import ch.systemsx.cisd.common.parser.IParserObjectFactory; import ch.systemsx.cisd.common.parser.IParserObjectFactoryFactory; import ch.systemsx.cisd.common.parser.IPropertyMapper; import ch.systemsx.cisd.common.parser.ParserException; import ch.systemsx.cisd.common.servlet.IRequestContextProvider; import ch.systemsx.cisd.common.spring.IUncheckedMultipartFile; import ch.systemsx.cisd.common.utilities.BeanUtils; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.BatchRegistrationResult; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DataSetUpdates; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleUpdates; import ch.systemsx.cisd.openbis.generic.client.web.server.AbstractClientService; import ch.systemsx.cisd.openbis.generic.client.web.server.AttachmentRegistrationHelper; import ch.systemsx.cisd.openbis.generic.client.web.server.BisTabFileLoader; import ch.systemsx.cisd.openbis.generic.client.web.server.UploadedFilesBean; import ch.systemsx.cisd.openbis.generic.client.web.server.translator.UserFailureExceptionTranslator; import ch.systemsx.cisd.openbis.generic.shared.IServer; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetUpdateResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentUpdateResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentUpdates; 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.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; 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.dto.DataSetUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierFactory; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory; import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientService; import ch.systemsx.cisd.openbis.plugin.generic.client.web.server.parser.NewMaterialParserObjectFactory; import ch.systemsx.cisd.openbis.plugin.generic.client.web.server.parser.SampleUploadSectionsParser; import ch.systemsx.cisd.openbis.plugin.generic.client.web.server.parser.SampleUploadSectionsParser.BatchSamplesRegistration; import ch.systemsx.cisd.openbis.plugin.generic.client.web.server.parser.SampleUploadSectionsParser.SampleCodeGenerator; import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer; import ch.systemsx.cisd.openbis.plugin.generic.shared.ResourceNames; /** * The {@link IGenericClientService} implementation. * * @author Franz-Josef Elmer */ @Component(value = ResourceNames.GENERIC_PLUGIN_SERVICE) public final class GenericClientService extends AbstractClientService implements IGenericClientService { @Resource(name = ResourceNames.GENERIC_PLUGIN_SERVER) private IGenericServer genericServer; public GenericClientService() { } @Private GenericClientService(final IGenericServer genericServer, final IRequestContextProvider requestContextProvider) { super(requestContextProvider); this.genericServer = genericServer; } // // AbstractClientService // @Override protected final IServer getServer() { return genericServer; } // // IGenericClientService // public final SampleParentWithDerived getSampleGenerationInfo(final TechId sampleId) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { final String sessionToken = getSessionToken(); final SampleParentWithDerived sampleParentWithDerived = genericServer.getSampleInfo(sessionToken, sampleId); return sampleParentWithDerived; } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } } public final Sample getSampleInfo(final TechId sampleId) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { return getSampleGenerationInfo(sampleId).getParent(); } public final void registerSample(final String sessionKey, final NewSample newSample) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { final String sessionToken = getSessionToken(); new AttachmentRegistrationHelper() { @Override public void register(Collection<NewAttachment> attachments) { genericServer.registerSample(sessionToken, newSample, attachments); } }.process(sessionKey, getHttpSession(), newSample.getAttachments()); } public final List<BatchRegistrationResult> registerSamples(final SampleType sampleType, final String sessionKey, String defaultGroupIdentifier) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { BatchSamplesRegistration info = parseSamples(sampleType, sessionKey, defaultGroupIdentifier, defaultGroupIdentifier != null, true); try { final String sessionToken = getSessionToken(); genericServer.registerSamples(sessionToken, info.getSamples()); return info.getResultList(); } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } } public final Experiment getExperimentInfo(final String experimentIdentifier) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { final String sessionToken = getSessionToken(); final ExperimentIdentifier identifier = new ExperimentIdentifierFactory(experimentIdentifier) .createIdentifier(); final Experiment experiment = genericServer.getExperimentInfo(sessionToken, identifier); return experiment; } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } } public final Experiment getExperimentInfo(final TechId experimentId) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { final String sessionToken = getSessionToken(); final Experiment experiment = genericServer.getExperimentInfo(sessionToken, experimentId); return experiment; } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } } public final Material getMaterialInfo(final TechId materialId) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { final String sessionToken = getSessionToken(); final Material material = genericServer.getMaterialInfo(sessionToken, materialId); return material; } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } } public final ExternalData getDataSetInfo(final TechId datasetId) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { final String sessionToken = getSessionToken(); final ExternalData dataset = genericServer.getDataSetInfo(sessionToken, datasetId); return dataset; } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } } public void registerExperiment(final String attachmentsSessionKey, final String samplesSessionKey, final NewExperiment experiment) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { final String sessionToken = getSessionToken(); if (experiment.isRegisterSamples()) { final ExperimentIdentifier identifier = new ExperimentIdentifierFactory(experiment.getIdentifier()) .createIdentifier(); BatchSamplesRegistration result = parseSamples(experiment.getSampleType(), samplesSessionKey, new GroupIdentifier(identifier.getDatabaseInstanceCode(), identifier.getGroupCode()).toString(), experiment.isGenerateCodes(), false); experiment.setNewSamples(result.getSamples()); experiment.setSamples(result.getCodes()); } new AttachmentRegistrationHelper() { @Override public void register(Collection<NewAttachment> attachments) { genericServer.registerExperiment(sessionToken, experiment, attachments); } }.process(attachmentsSessionKey, getHttpSession(), experiment.getAttachments()); } private BatchSamplesRegistration parseSamples(final SampleType sampleType, final String sessionKey, String defaultGroupIdentifier, final boolean isAutoGenerateCodes, final boolean allowExperiments) { HttpSession httpSession = getHttpSession(); UploadedFilesBean uploadedFiles = null; try { SampleCodeGenerator sampleCodeGeneratorOrNull = tryGetSampleCodeGenerator(isAutoGenerateCodes); uploadedFiles = getUploadedFiles(sessionKey, httpSession); return SampleUploadSectionsParser.prepareSamples(sampleType, uploadedFiles, defaultGroupIdentifier, sampleCodeGeneratorOrNull, allowExperiments); } catch (final UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } finally { cleanUploadedFiles(sessionKey, httpSession, uploadedFiles); } } private SampleCodeGenerator tryGetSampleCodeGenerator(boolean isAutoGenerateCodes) { if (isAutoGenerateCodes) { return new SampleCodeGenerator() { public List<String> generateCodes(int size) { return genericServer.generateCodes(getSessionToken(), "S", size); } }; } else { return null; } } private UploadedFilesBean getUploadedFiles(String sessionKey, HttpSession session) { assert session.getAttribute(sessionKey) != null && session.getAttribute(sessionKey) instanceof UploadedFilesBean : String .format("No UploadedFilesBean object as session attribute '%s' found.", sessionKey); return (UploadedFilesBean) session.getAttribute(sessionKey); } public final List<BatchRegistrationResult> registerMaterials(final MaterialType materialType, final String sessionKey) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { HttpSession session = getHttpSession(); UploadedFilesBean uploadedFiles = null; try { uploadedFiles = getUploadedFiles(sessionKey, session); final BisTabFileLoader<NewMaterial> tabFileLoader = new BisTabFileLoader<NewMaterial>( new IParserObjectFactoryFactory<NewMaterial>() { public final IParserObjectFactory<NewMaterial> createFactory( final IPropertyMapper propertyMapper) throws ParserException { return new NewMaterialParserObjectFactory(propertyMapper); } }, false); final List<NewMaterial> newMaterials = new ArrayList<NewMaterial>(); final List<BatchRegistrationResult> results = new ArrayList<BatchRegistrationResult>( uploadedFiles.size()); for (final IUncheckedMultipartFile multipartFile : uploadedFiles.iterable()) { final StringReader stringReader = new StringReader(new String(multipartFile.getBytes())); final List<NewMaterial> loadedMaterials = tabFileLoader .load(new DelegatedReader(stringReader, multipartFile.getOriginalFilename())); newMaterials.addAll(loadedMaterials); results.add(new BatchRegistrationResult(multipartFile.getOriginalFilename(), String.format("%d material(s) found and registered.", loadedMaterials.size()))); } genericServer.registerMaterials(getSessionToken(), materialType.getCode(), newMaterials); return results; } catch (final UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } finally { cleanUploadedFiles(sessionKey, session, uploadedFiles); } } private void cleanUploadedFiles(final String sessionKey, HttpSession session, UploadedFilesBean uploadedFiles) { if (uploadedFiles != null) { uploadedFiles.deleteTransferredFiles(); } if (session != null) { session.removeAttribute(sessionKey); } } public Date updateSample(final SampleUpdates updates) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { final String sessionToken = getSessionToken(); final Date modificationDate = new Date(); new AttachmentRegistrationHelper() { @Override public void register(Collection<NewAttachment> attachments) { ExperimentIdentifier convExperimentIdentifierOrNull = null; SampleIdentifier sampleOwner = null; if (updates.getExperimentIdentifierOrNull() != null) { convExperimentIdentifierOrNull = new ExperimentIdentifierFactory( updates.getExperimentIdentifierOrNull().getIdentifier()).createIdentifier(); } if (StringUtils.isBlank(updates.getSampleIdentifier()) == false) { sampleOwner = new SampleIdentifierFactory(updates.getSampleIdentifier()).createIdentifier(); } Date date = genericServer.updateSample(sessionToken, new SampleUpdatesDTO(updates.getSampleId(), updates.getProperties(), convExperimentIdentifierOrNull, attachments, updates.getVersion(), sampleOwner, updates.getParentIdentifierOrNull(), updates.getContainerIdentifierOrNull())); modificationDate.setTime(date.getTime()); } }.process(updates.getSessionKey(), getHttpSession(), updates.getAttachments()); return modificationDate; } public Date updateMaterial(TechId materialId, List<IEntityProperty> properties, Date version) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { final String sessionToken = getSessionToken(); return genericServer.updateMaterial(sessionToken, materialId, properties, version); } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } } public ExperimentUpdateResult updateExperiment(final ExperimentUpdates updates) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { final String sessionToken = getSessionToken(); final ExperimentUpdateResult result = new ExperimentUpdateResult(); if (updates.isRegisterSamples()) { final ProjectIdentifier newProject = new ProjectIdentifierFactory(updates.getProjectIdentifier()) .createIdentifier(); BatchSamplesRegistration info = parseSamples(updates.getSampleType(), updates.getSamplesSessionKey(), new GroupIdentifier(newProject.getDatabaseInstanceCode(), newProject.getGroupCode()).toString(), updates.isGenerateCodes(), false); updates.setNewSamples(info.getSamples()); updates.setSampleCodes(info.getCodes()); } new AttachmentRegistrationHelper() { @Override public void register(Collection<NewAttachment> attachments) { ExperimentUpdatesDTO updatesDTO = createExperimentUpdatesDTO(updates, attachments); BeanUtils.fillBean(ExperimentUpdateResult.class, result, genericServer.updateExperiment(sessionToken, updatesDTO)); } }.process(updates.getAttachmentSessionKey(), getHttpSession(), updates.getAttachments()); return result; } private static ExperimentUpdatesDTO createExperimentUpdatesDTO(ExperimentUpdates updates, Collection<NewAttachment> attachments) { ExperimentUpdatesDTO updatesDTO = new ExperimentUpdatesDTO(); updatesDTO.setExperimentId(updates.getExperimentId()); final ProjectIdentifier project = new ProjectIdentifierFactory(updates.getProjectIdentifier()) .createIdentifier(); updatesDTO.setProjectIdentifier(project); updatesDTO.setAttachments(attachments); updatesDTO.setProperties(updates.getProperties()); updatesDTO.setSampleCodes(updates.getSampleCodes()); updatesDTO.setVersion(updates.getVersion()); updatesDTO.setRegisterSamples(updates.isRegisterSamples()); updatesDTO.setNewSamples(updates.getNewSamples()); updatesDTO.setSampleType(updates.getSampleType()); return updatesDTO; } public DataSetUpdateResult updateDataSet(final DataSetUpdates updates) throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException { try { final String sessionToken = getSessionToken(); return genericServer.updateDataSet(sessionToken, createDataSetUpdatesDTO(updates)); } catch (TransactionSystemException e) { // Deferred triger may throw an exception just before commit. // Message in the exception is readable for the user. throw UserFailureExceptionTranslator .translate(new UserFailureException(e.getMostSpecificCause().getMessage())); } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) { throw UserFailureExceptionTranslator.translate(e); } } private static DataSetUpdatesDTO createDataSetUpdatesDTO(DataSetUpdates updates) { DataSetUpdatesDTO updatesDTO = new DataSetUpdatesDTO(); updatesDTO.setDatasetId(updates.getDatasetId()); updatesDTO.setProperties(updates.getProperties()); updatesDTO.setVersion(updates.getVersion()); updatesDTO.setModifiedParentDatasetCodesOrNull(updates.getModifiedParentDatasetCodesOrNull()); String sampleIdentifierOrNull = updates.getSampleIdentifierOrNull(); updatesDTO.setSampleIdentifierOrNull( sampleIdentifierOrNull == null ? null : SampleIdentifierFactory.parse(sampleIdentifierOrNull)); updatesDTO.setFileFormatTypeCode(updates.getFileFormatTypeCode()); return updatesDTO; } }