diff --git a/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/Email.java b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/Email.java new file mode 100644 index 0000000000000000000000000000000000000000..2beefd20584d51b2e5be21fa08efa04586cf5970 --- /dev/null +++ b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/Email.java @@ -0,0 +1,76 @@ +/* + * 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.ethz.bsse.cisd.dsu.tracking; + +import ch.systemsx.cisd.common.mail.IMailClient; + +/** + * Simple encapsulation of + * {@link IMailClient#sendMessage(String, String, String, ch.systemsx.cisd.common.mail.From, String...)} + * method parameters. + * + * @author Piotr Buczek + */ +public class Email +{ + private final String subject; + + private final String content; + + private final String replyToOrNull; + + private final String fromOrNull; + + private final String[] recipients; + + public Email(String subject, String content, String replyToOrNull, String fromOrNull, + String... recipients) + { + super(); + this.subject = subject; + this.content = content; + this.replyToOrNull = replyToOrNull; + this.fromOrNull = fromOrNull; + this.recipients = recipients; + } + + public String getSubject() + { + return subject; + } + + public String getContent() + { + return content; + } + + public String getReplyToOrNull() + { + return replyToOrNull; + } + + public String getFromOrNull() + { + return fromOrNull; + } + + public String[] getRecipients() + { + return recipients; + } + +} diff --git a/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/EntityTrackingEmailData.java b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/EntityTrackingEmailData.java new file mode 100644 index 0000000000000000000000000000000000000000..d0d1dd9a371093ec29d6324df7cf14c02fd178e2 --- /dev/null +++ b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/EntityTrackingEmailData.java @@ -0,0 +1,139 @@ +/* + * 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.ethz.bsse.cisd.dsu.tracking; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; + +/** + * Structure containing all data about tracked entities that will be used in a single email to an + * recipient. Its purpose is to group data that will be used to generate content of an email + * containing merged information about all events that the recipient should be notified about. + * + * @author Piotr Buczek + */ +public class EntityTrackingEmailData +{ + public static class SequencingSampleData + { + private final boolean newlyTracked; + + private final Sample sequencingSample; + + private final List<Sample> flowLaneSamples = new ArrayList<Sample>(0); + + public SequencingSampleData(Sample sequencingSample, boolean newlyTracked) + { + super(); + this.sequencingSample = sequencingSample; + this.newlyTracked = newlyTracked; + } + + public void addFlowLaneSample(Sample flowLaneSample) + { + flowLaneSamples.add(flowLaneSample); + } + + public Sample getSequencingSample() + { + return sequencingSample; + } + + public List<Sample> getFlowLaneSamples() + { + return flowLaneSamples; + } + + public boolean isNewlyTracked() + { + return newlyTracked; + } + } + + // data grouped by sequencing sample: <sequencing sample id, data> + private final Map<Long, SequencingSampleData> sequencingSampleData = + new HashMap<Long, SequencingSampleData>(0); + + private final List<ExternalData> dataSets = new ArrayList<ExternalData>(0); + + private final String recipient; + + /** creates email data for given <var>recipient</var> */ + public EntityTrackingEmailData(String recipient) + { + this.recipient = recipient; + } + + public String getRecipient() + { + return recipient; + } + + public Map<Long, SequencingSampleData> getSequencingSampleData() + { + return sequencingSampleData; + } + + public List<ExternalData> getDataSets() + { + return dataSets; + } + + /** adds info about newly tracked sequencing */ + public void addSequencingSample(Sample sequencingSample) + { + createSequencingSampleData(sequencingSample, true); + } + + /** adds info about newly tracked flow lane sample */ + public void addFlowLaneSample(Sample flowLaneSample) + { + // if data about sequencing sample is not yet added add it too + final Sample sequencingSample = flowLaneSample.getGeneratedFrom(); + assert sequencingSample != null; + + SequencingSampleData infoOrNull = sequencingSampleData.get(sequencingSample.getId()); + if (infoOrNull == null) + { + // because sequencing samples are processed before flow lane samples + // the sequencing sample we have here must have existed before + infoOrNull = createSequencingSampleData(sequencingSample, false); + } + + infoOrNull.addFlowLaneSample(flowLaneSample); + } + + private SequencingSampleData createSequencingSampleData(Sample sequencingSample, + boolean newlyTracked) + { + final SequencingSampleData data = new SequencingSampleData(sequencingSample, newlyTracked); + sequencingSampleData.put(sequencingSample.getId(), data); + return data; + } + + /** adds info about newly tracked data set */ + public void addDataSet(ExternalData dataSet) + { + dataSets.add(dataSet); + } + +} diff --git a/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/EntityTrackingEmailDataManager.java b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/EntityTrackingEmailDataManager.java new file mode 100644 index 0000000000000000000000000000000000000000..ff73841dba6309380a3a420704500a2bda00a8a2 --- /dev/null +++ b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/EntityTrackingEmailDataManager.java @@ -0,0 +1,161 @@ +/* + * 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.ethz.bsse.cisd.dsu.tracking; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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.Sample; + +/** + * Manager that groups data about tracked entities into {@link EntityTrackingEmailData} objects. + * + * @author Piotr Buczek + */ +class EntityTrackingEmailDataManager +{ + private final static String CONTACT_PERSON_EMAIL = "CONTACT_PERSON_EMAIL"; + + private final static String PRINCIPAL_INVESTIGATOR_EMAIL = "PRINCIPAL_INVESTIGATOR_EMAIL"; + + public static Collection<EntityTrackingEmailData> groupByRecipient( + TrackedEntities trackedEntities) + { + // <recipients email, email data> + final Map<String, EntityTrackingEmailData> dataByRecipient = + new HashMap<String, EntityTrackingEmailData>(); + groupSequencingSamples(dataByRecipient, trackedEntities); + groupFlowLaneSamples(dataByRecipient, trackedEntities); + groupDataSetSamples(dataByRecipient, trackedEntities); + return dataByRecipient.values(); + } + + /** Puts tracked sequencing samples grouped by recipient into <var>result</var>. */ + private static void groupSequencingSamples(Map<String, EntityTrackingEmailData> result, + TrackedEntities trackedEntities) + { + for (Sample sequencingSample : trackedEntities.getSequencingSamples()) + { + for (String recipient : getFlowLaneSampleTrackingRecipients(sequencingSample)) + { + final EntityTrackingEmailData emailData = + getOrCreateRecipientEmailData(result, recipient); + emailData.addSequencingSample(sequencingSample); + } + } + } + + /** Puts tracked flow lane samples grouped by recipient into <var>result</var>. */ + private static void groupFlowLaneSamples(Map<String, EntityTrackingEmailData> result, + TrackedEntities trackedEntities) + { + for (Sample flowLaneSample : trackedEntities.getFlowLaneSamples()) + { + for (String recipient : getFlowLaneSampleTrackingRecipients(flowLaneSample)) + { + final EntityTrackingEmailData emailData = + getOrCreateRecipientEmailData(result, recipient); + emailData.addFlowLaneSample(flowLaneSample); + } + } + } + + /** Puts tracked data sets grouped by recipient into <var>result</var>. */ + private static void groupDataSetSamples(Map<String, EntityTrackingEmailData> result, + TrackedEntities trackedEntities) + { + for (ExternalData dataSet : trackedEntities.getDataSets()) + { + for (String recipient : getDataSetTrackingRecipients(dataSet)) + { + final EntityTrackingEmailData emailData = + getOrCreateRecipientEmailData(result, recipient); + emailData.addDataSet(dataSet); + } + } + } + + private static EntityTrackingEmailData getOrCreateRecipientEmailData( + Map<String, EntityTrackingEmailData> dataByRecipient, String recipient) + { + EntityTrackingEmailData emailDataOrNull = dataByRecipient.get(recipient); + if (emailDataOrNull == null) + { + emailDataOrNull = new EntityTrackingEmailData(recipient); + } + return emailDataOrNull; + } + + /** + * Returns an array of emails of recipient that should get a tracking information about given + * <var>sequencingSample</var>. + */ + private static String[] getSequencingSampleTrackingRecipients(Sample sequencingSample) + { + // Recipients are taken from properties of the sequencing sample. + assert sequencingSample != null; + + final Set<String> recipientPropertyTypeCodes = new HashSet<String>(); + recipientPropertyTypeCodes.add(CONTACT_PERSON_EMAIL); + recipientPropertyTypeCodes.add(PRINCIPAL_INVESTIGATOR_EMAIL); + + final List<String> recipients = new ArrayList<String>(); + for (IEntityProperty property : sequencingSample.getProperties()) + { + if (recipientPropertyTypeCodes.contains(property.getPropertyType().getCode())) + { + recipients.add(property.getValue()); + } + } + + // TODO 2009-11-23, Piotr Buczek: add affiliation email + + return recipients.toArray(new String[0]); + } + + /** + * Returns an array of emails of recipient that should get a tracking information about given + * <var>flowLaneSample</var>. + */ + private static String[] getFlowLaneSampleTrackingRecipients(Sample flowLaneSample) + { + // Recipients are taken from properties of sequencing sample + // that is a parent of the flow lane sample. + assert flowLaneSample != null; + return getSequencingSampleTrackingRecipients(flowLaneSample.getGeneratedFrom()); + } + + /** + * Returns an array of emails of recipient that should get a tracking information about given + * <var>dataSet</var>. + */ + private static String[] getDataSetTrackingRecipients(ExternalData dataSet) + { + // Recipients are taken from properties of sequencing sample + // that is a parent of a flow lane sample connected directly with the data set. + assert dataSet != null; + return getFlowLaneSampleTrackingRecipients(dataSet.getSample()); + } + +} \ No newline at end of file diff --git a/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/FlowLaneTrackingEmailGenerator.java b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/FlowLaneTrackingEmailGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..5b3f05001619d61cc234e1498dd1595895d4616c --- /dev/null +++ b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/FlowLaneTrackingEmailGenerator.java @@ -0,0 +1,49 @@ +/* + * 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.ethz.bsse.cisd.dsu.tracking; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author Piotr Buczek + */ +public class FlowLaneTrackingEmailGenerator implements IFlowLaneTrackingEmailGenerator +{ + + public List<Email> generateEmails(TrackedEntities trackedEntities) + { + final Collection<EntityTrackingEmailData> emailDataGroupedByRecipient = + EntityTrackingEmailDataManager.groupByRecipient(trackedEntities); + + final List<Email> results = new ArrayList<Email>(); + for (EntityTrackingEmailData emailData : emailDataGroupedByRecipient) + { + results.add(createEmail(emailData)); + } + + return results; + } + + private Email createEmail(EntityTrackingEmailData emailData) + { + // TODO 2009-11-23, Piotr Buczek: implement + return null; + } + +} diff --git a/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/IFlowLaneTrackingEmailGenerator.java b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/IFlowLaneTrackingEmailGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..b537b8706e10fe60b508a50817c12883e6bd19e7 --- /dev/null +++ b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/IFlowLaneTrackingEmailGenerator.java @@ -0,0 +1,33 @@ +/* + * 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.ethz.bsse.cisd.dsu.tracking; + +import java.util.List; + +/** + * @author Piotr Buczek + */ +interface IFlowLaneTrackingEmailGenerator +{ + /** + * Generates all {@link Email}s to be send containing information about + * <var>trackedEntities</var>. + * + * @param trackedEntities recently tracked entities + */ + List<Email> generateEmails(TrackedEntities trackedEntities); +} diff --git a/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/TrackedEntities.java b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/TrackedEntities.java new file mode 100644 index 0000000000000000000000000000000000000000..b5b9fcac7ac2fb7b8a99cdf7f61856fb57f3ce70 --- /dev/null +++ b/deep_sequencing_unit/source/java/ch/ethz/bsse/cisd/dsu/tracking/TrackedEntities.java @@ -0,0 +1,59 @@ +/* + * 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.ethz.bsse.cisd.dsu.tracking; + +import java.util.List; + +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; + +/** + * Simple encapsulation of list of entities that are tracked. + * + * @author Piotr Buczek + */ +public class TrackedEntities +{ + private final List<Sample> sequencingSamples; + + private final List<Sample> flowLaneSamples; + + private final List<ExternalData> dataSets; + + public TrackedEntities(List<Sample> sequencingSamples, List<Sample> flowLaneSamples, + List<ExternalData> dataSets) + { + this.sequencingSamples = sequencingSamples; + this.flowLaneSamples = flowLaneSamples; + this.dataSets = dataSets; + } + + public List<Sample> getSequencingSamples() + { + return sequencingSamples; + } + + public List<Sample> getFlowLaneSamples() + { + return flowLaneSamples; + } + + public List<ExternalData> getDataSets() + { + return dataSets; + } +}