/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.openehealth.coala.domain;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/**
* Holds all consents for a given patient. This set locks itself once it is
* being accessed the first time.
*
* @author kmaerz
*/
public class FindPatientConsentResult implements Serializable {
private static final long serialVersionUID = 1L;
/**
* The internal list of query results
*/
private List<PatientConsent> consentList = new ArrayList<PatientConsent>();
/** The patient to whom this set belongs */
private Patient patient;
/** if true, the result cannot be modified anymore */
private boolean locked = false;
/** this is the parameter the consents will be sorted by */
private ConsentSortParameter sortBy;
/**
* The time that this consent set has been created
*/
private Date timeOfCreation;
/**
* Creates a new set of consents. Add Results via addConsent() and lock
* afterwards. Once locked or accessed, the list of consents is irrevocably
* immutable.
*
* @param sortBy
* The sort criterion used for result list order.
* @param patient
* The patient to whom this set of consents belongs.
*/
public FindPatientConsentResult(Patient patient, ConsentSortParameter sortBy) {
if (patient == null)
throw new IllegalArgumentException(
"Upon creation, one must specify the patientID of the patient to whom these results belong");
this.patient = patient;
if ((sortBy == null) || (sortBy.equals(ConsentSortParameter.UNSORTED)))
sortBy = ConsentSortParameter.getDefault();
this.sortBy = sortBy;
this.timeOfCreation = new Date();
}
/**
* Returns the {@link Patient} instance to whom this {@link FindPatientConsentResult} belongs
*
* @return the {@link Patient} instance to whom this {@link FindPatientConsentResult} belongs
*/
public Patient getPatient() {
return patient;
}
/**
* Adds a consent to the result. Adding consents can only take place while
* the result remains unlocked. Once it is read in anyway, the list will be
* locked and trying to add a consent results in an
* IllegalOperationExcaption.
*
* @param consent
* The consent to add.
*/
public void addPatientConsent(PatientConsent consent) {
if (locked)
throw new IllegalArgumentException(
"Cannot add a consent to a locked list. Has the list been accessd already?");
// insert sorted in place!
if (consentList.isEmpty()) {
consentList.add(consent);
return;
}
else
for (int i = 0; i < consentList.size(); i++) {
if (compareConsents(consent, consentList.get(i)) < 0) {
consentList.add(i, consent);
return; // exit, when added
}
}
consentList.add(consent); // if consent has never evaluated to "smaller", add to end of list
}
/**
* Adds a set of consents to the result. Adding consents can only happen
* while the result remains unlocked. Once it is read in anyway, the list
* will be locked and trying to add a consent results in an
* IllegalOperationExcaption.
*
* @param consents
* The set of consents to add.
*/
public void addAll(Collection<PatientConsent> consents) {
if (locked)
throw new IllegalArgumentException(
"Cannot add a consent to a locked list. Has the list been accessd already?");
for (PatientConsent c : consents) addPatientConsent(c);
}
/**
* Returns the list of consents as an unmodifiable List.
*
* @return the list of consents as an unmodifiable List.
*/
public List<PatientConsent> getPatientConsents() {
return Collections.unmodifiableList(consentList);
}
/**
* Locks this result set. After locking it cannot be unlocked again.
*/
public void lock() {
locked = true;
}
/**
* Returns the time that this set of results has been created (time of
* calling it's constructor)
*
* @return the time that this set of results has been created (time of
* calling it's constructor)
*/
public Date getTimeOfCreation() {
return this.timeOfCreation;
}
/**
* Compares two consents and returns a negative number, if c1 before c2, 0
* if c1 ~ c2 and a positive number if c1 after c2. Comparison is ordinal.
* Do not use output to calculate anything else than sort order.
*
* @param c1
* First consent to compare
* @param c2
* First consent to compare
* @return returns a negative number, if c1 < c2, 0 if c1 ~ c2 and a
* positive number if c1 > c2. (Comparison is ordinal)
*/
private int compareConsents(PatientConsent c1, PatientConsent c2) {
if (sortBy == ConsentSortParameter.UNSORTED)
return 0;
else if (sortBy == ConsentSortParameter.END_DATE_NEWEST_FIRST)
return c1.getValidUntil().compareTo(c2.getValidUntil());
else if (sortBy == ConsentSortParameter.END_DATE_OLDEST_FIRST)
return -1 * c1.getValidUntil().compareTo(c2.getValidUntil());
else if (sortBy == ConsentSortParameter.CREATION_DATE_NEWEST_FIRST)
return c1.getCreationDate().compareTo(c2.getCreationDate());
else if (sortBy == ConsentSortParameter.CREATION_DATE_OLDEST_FIRST)
return -1 * c1.getCreationDate().compareTo(c2.getCreationDate());
else if (sortBy == ConsentSortParameter.AUTHOR_ASCENDING)
return c1.getAuthor().compareTo(c2.getAuthor());
else if (sortBy == ConsentSortParameter.AUTHOR_DESCENDING)
return -1 * c1.getAuthor().compareTo(c2.getAuthor());
else if (sortBy == ConsentSortParameter.START_DATE_NEWEST_FIRST)
return c1.getValidFrom().compareTo(c2.getValidFrom());
else if (sortBy == ConsentSortParameter.START_DATE_OLDEST_FIRST)
return -1 * c1.getValidFrom().compareTo(c2.getValidFrom());
else if (sortBy == ConsentSortParameter.OBSOLETE_TRUE_FIRST)
return -1 * compareBool(c1.isObsolete(), c2.isObsolete());
else if (sortBy == ConsentSortParameter.OBSOLETE_FALSE_FIRST)
return compareBool(c1.isObsolete(), c2.isObsolete());
else if (sortBy == ConsentSortParameter.EFFECTIVE_TRUE_FIRST)
return -1 * compareBool(c1.isActive(), c2.isActive());
else if (sortBy == ConsentSortParameter.EFFECTIVE_FALSE_FIRST)
return compareBool(c1.isActive(), c2.isActive());
else if (sortBy == ConsentSortParameter.POLICY_TYPE_ASCENDING)
return c1.getPolicyType().getNumber()
- c2.getPolicyType().getNumber();
else if (sortBy == ConsentSortParameter.POLICY_TYPE_DESCENDING)
return -1
* (c1.getPolicyType().getNumber() - c2.getPolicyType()
.getNumber());
throw new RuntimeException(
"All possibilities checked. This line should never be reached, unless new sort Options have been introduced. Please update sorting algorithm.");
}
/**
* Compare two boolean parameters. Consider comparison b1 - b2 with True = 1
* and False = 0;
*
* @param b1
* first boolean
* @param b2
* second boolean
* @return b1 - b2, where True = 1, False = 0;
*/
private int compareBool(boolean b1, boolean b2) {
if (b1 == b2)
return 0; // Both equal
if (b1)
return 1; // b1 = true, b2 = false
return -1; // b1 = false, b2 = true;
}
// ===========================================================//
// INTERNAL LOGIC ENDS HERE, ITERATION CODE AHEAD //
// ===========================================================//
/**
* Returns an iterator to access all patients from the result
*/
public Iterator<PatientConsent> iterator() {
return new PatientConsentIterator();
}
/**
* Private inner iterator to safely iterate over all patients in the search
* result. It does not support removing patients.
*
* @author kmaerz
*/
private class PatientConsentIterator implements Iterator<PatientConsent> {
private int i = 0; // the next element to return
/**
* True, if the next() method can return another patient
*/
public boolean hasNext() {
return (i < consentList.size());
}
/**
* Returns the next patient
*/
public PatientConsent next() {
locked = true; // lock list forever when it is being read.
PatientConsent result = consentList.get(i);
i++;
return result;
}
/**
* Not supported for security reasons
*/
public void remove() {
throw new UnsupportedOperationException(
"Removing consents from a search result is not supported.");
}
}
}