Commit d15d7dd5 authored by rwm's avatar rwm

Maven site via markdown, fixed javadoc errors, documentation

parent 7db41860
......@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.sekmi.histream</groupId>
<artifactId>histream</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.2-alpha</version>
<inceptionYear>2013</inceptionYear>
<organization>
......@@ -75,46 +75,6 @@
</execution>
</executions>
</plugin>
<!--
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>schemagen</id>
<goals>
<goal>schemagen</goal>
</goals>
<phase>package</phase>
<configuration>
<includes>
<include>**/*.java</include>
</includes>
<outputDirectory>${project.build.directory}/generated-resources/schemagen</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
</configuration>
</execution>
</executions>
</plugin>
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
......@@ -148,6 +108,7 @@
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1201-jdbc41</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -105,8 +105,8 @@ public enum AbnormalFlag{
public String key(){return this.key;}
/**
* Get abnormal flag for the specified key.
* @param key
* Get abnormal flag for the specified key. For allowed values, see the enum values.
* @param key key string.
* @return null if key is null, matching flag otherwise
* @throws IllegalArgumentException for non-null keys which do not match any enum constant.
*/
......
package de.sekmi.histream;
import de.sekmi.histream.impl.AbstractValue;
/*
* #%L
* histream
......@@ -20,8 +22,24 @@ package de.sekmi.histream;
* #L%
*/
/**
* Pair of concept and value.
* Basic common interface for both {@link Observation} an {@link Modifier}.
*
* @author marap1
*
*/
public interface ConceptValuePair {
/**
* Get the concept id
* @return concept id
*/
public String getConceptId();
/**
* Get the value. This method shall not return {@code null}.
* If a non-existing value is needed, use {@link AbstractValue#NONE}
* @return value value
*/
public Value getValue();
}
......@@ -31,9 +31,7 @@ import java.util.Date;
/**
* Local date and time with specified accuracy. Maximum resolution is seconds.
* Supported accuracy values are {@link ChronoUnit#YEARS}, {@link ChronoUnit#MONTHS},
* {@link ChronoUnit#DAYS}, {@link ChronoUnit#HOURS}, {@link ChronoUnit#MINUTES} and
* {@link ChronoUnit#SECONDS}.
* For supported accuracy, see {@link #setAccuracy(ChronoUnit)}.
* @author Raphael
*
*/
......@@ -43,7 +41,7 @@ public class DateTimeAccuracy implements Temporal {
/**
* Create date time with accuracy to seconds.
* @param dateTime
* @param dateTime timestamp
*/
public DateTimeAccuracy(LocalDateTime dateTime){
this.dateTime = dateTime;
......@@ -104,8 +102,13 @@ public class DateTimeAccuracy implements Temporal {
/**
* Set the accuracy for the date time object.
* <p>
* Supported accuracy values are {@link ChronoUnit#YEARS}, {@link ChronoUnit#MONTHS},
* {@link ChronoUnit#DAYS}, {@link ChronoUnit#HOURS}, {@link ChronoUnit#MINUTES} and
* {@link ChronoUnit#SECONDS}
* <p>
* TODO: what happens if the accuracy is increased (but the underlaying time was truncated)
* @param accuracy
* @param accuracy accuracy
*/
public void setAccuracy(ChronoUnit accuracy){
this.accuracy = accuracy;
......@@ -114,7 +117,7 @@ public class DateTimeAccuracy implements Temporal {
/**
* Get the local time
* @return
* @return local time
*/
public LocalDateTime getLocal(){ return dateTime; }
......@@ -169,9 +172,9 @@ public class DateTimeAccuracy implements Temporal {
/**
* Parses a partial ISO 8601 date time string.
* [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
* @param str
* @param str ISO 8601 string
* @return date time with accuracy as derived from parse
* @throws IllegalArgumentException
* @throws IllegalArgumentException for unparsable string
*/
public static DateTimeAccuracy parsePartialIso8601(String str)throws IllegalArgumentException{
if( str.length() < 4 )throw new IllegalArgumentException("Need at least 4 characters for year: "+str);
......
......@@ -28,7 +28,7 @@ package de.sekmi.histream;
*
* @author Raphael
*
* @param <T>
* @param <T> type class
*/
public interface Extension<T>{
/**
......@@ -36,8 +36,8 @@ public interface Extension<T>{
* once for each observation, usually when the extension requested for
* the observation. The instance is then cached automatically.
*
* @param observation
* @return extension
* @param observation observation
* @return extension extension
*/
T createInstance(Observation observation);
......
......@@ -20,12 +20,23 @@ package de.sekmi.histream;
* #L%
*/
/**
* Accessor which can be used to access and set extension instances for observations.
*
* While extension can also accessed via {@link Observation#getExtension(Class)}, the main
* difference is that this class does not to lookup the extension type and thus provides
* faster access. Additionally, this interface can be used to set an extension explicitly
* via {@link #set(Observation, Object)}.
*
* @author marap1
*
* @param <T> extension type
*/
public interface ExtensionAccessor<T> {
/**
* Get the extension type instance. The instance is created automatically on first access.
* @param observation
* @return
* @param observation observation
* @return extension instance
*/
T access(Observation observation);
......
......@@ -20,7 +20,15 @@ package de.sekmi.histream;
* #L%
*/
/**
* Sub concept of an {@link Observation}.
*
* Multiple modifiers are allowed for a single observation,
* as long as each modifier uses a different concept id / modifier code.
*
* @author marap1
*
*/
public interface Modifier extends ConceptValuePair{
@Override
String getConceptId();
......@@ -28,6 +36,9 @@ public interface Modifier extends ConceptValuePair{
@Override
Value getValue();
/**
* Sets the value for this modifier
* @param value value
*/
void setValue(Value value);
}
......@@ -28,6 +28,8 @@ import de.sekmi.histream.ext.ExternalSourceType;
/**
* Observation of a single event or a single fact assigned to a single patient.
*
* TODO more details
*
* @author Raphael
*
*/
......@@ -56,8 +58,25 @@ public interface Observation extends ConceptValuePair, ExternalSourceType{
void setEncounterId(String encounterId);
void setLocationId(String locationId);
/**
* Whether this observation contains sub-concepts (=modifiers).
*
* @see #getModifier(String)
* @return true if modifiers are present, false otherwise
*/
boolean hasModifiers();
Modifier getModifier(String modifierId);
Enumeration<Modifier> getModifiers();
/**
* Add a sub concept to this observation.
*
* Use the returned {@link Modifier} to add additional information (e.g. value)
* to the modifier.
*
* @param modifierId concept id for the new modifier
* @return new modifier
* @throws IllegalArgumentException if the given modifierId is already used.
*/
Modifier addModifier(String modifierId)throws IllegalArgumentException;
}
......@@ -40,6 +40,9 @@ public class ObservationException extends Exception{
super(message, cause);
this.fact = fact;
}
/**
* Get the observation associated with this exception.
* @return associated observation or null if none.
*/
public Observation getObservation(){return fact;}
}
\ No newline at end of file
......@@ -32,7 +32,7 @@ package de.sekmi.histream;
public interface ObservationFactory {
/**
* Register an extension. Registered extensions cannot be removed.
* @param extension
* @param extension extension
*/
void registerExtension(Extension<?> extension);
......@@ -54,10 +54,10 @@ public interface ObservationFactory {
/**
* Create a new observation
* @param patientId
* @param conceptId
* @param startTime TODO
* @return
* @param patientId patient id
* @param conceptId concept code
* @param startTime start time for the fact TODO remove start time from constructor but throw exception later if startTime is needed.
* @return new observation
*/
Observation createObservation(String patientId, String conceptId, DateTimeAccuracy startTime);
}
......@@ -47,8 +47,8 @@ public interface ObservationHandler extends Consumer<Observation>{
/**
* Set meta information for this observation handler.
* @param key
* @param value
* @param key meta key
* @param value meta value
*/
void setMeta(String key, String value);
}
......@@ -24,7 +24,18 @@ package de.sekmi.histream;
import java.io.IOException;
import java.io.InputStream;
/**
* Observation provider parsing input streams to provide observations.
*
* @author marap1
*
*/
public interface ObservationParser extends ObservationProvider {
/**
* Parse an input stream to produce observations
* @param input input stream
* @throws IOException for io errors occurred during parsing
*/
public void parse(InputStream input) throws IOException;
}
......@@ -23,9 +23,26 @@ package de.sekmi.histream;
import java.util.function.Consumer;
/**
* Provider of observations.
*
* An observation provider usually needs an {@link ObservationFactory} to
* construct the observation it provides. The factory can be specified via
* {@link #setObservationFactory(ObservationFactory)}.
*/
public interface ObservationProvider{
/**
* Set the observation handler which will receive observations
* produced by this observation provider.
* @param consumer observation handler
*/
void setHandler(Consumer<Observation> consumer);
/**
* Set the observation factory which this provider will use
* to construct observations.
* @param factory observation factory
*/
void setObservationFactory(ObservationFactory factory);
Class<?>[] getSupportedExtensions();
......
......@@ -26,10 +26,11 @@ import java.math.BigDecimal;
import javax.xml.bind.annotation.XmlEnum;
/**
* @author marap1
*
* Interface for observation value.
*
* Also contains abnormal flag, value type and numeric operator.
*
* @author marap1
*/
public interface Value {
/**
......@@ -45,7 +46,7 @@ public interface Value {
AbnormalFlag getAbnormalFlag();
/**
* Value units. E.g. s or ml/h
* @return
* @return units string
*/
String getUnits();
/**
......@@ -60,6 +61,11 @@ public interface Value {
BigDecimal getReferenceHigh();
/**
* Value types
* @author marap1
*
*/
@XmlEnum
public enum Type{
/**
......@@ -80,7 +86,11 @@ public interface Value {
//NumericEnum
}
/**
* Value operators
* @author marap1
*
*/
@XmlEnum
public enum Operator{
Equal("EQ"),
......
......@@ -80,7 +80,7 @@ public class Configuration {
* <p>
* If an exception is thrown by the constructor if any plugin, the previously instantiated
* plugins are closed in reverse order. Any exceptions thrown by the close methods are suppressed
* by the constructor exception (via {@link Exception#addSuppressed(Throwable)).
* by the constructor exception (via {@link Exception#addSuppressed(Throwable)}).
* @return plugin instances
* @throws Exception exception thrown by any plugin during construction
*/
......
......@@ -39,7 +39,7 @@ public interface ExternalSourceType {
/**
* Set the point in time, when the contained information left it's source.
* @param instant
* @param sourceTimestamp source timestamp
*/
void setSourceTimestamp(Instant sourceTimestamp);
/**
......
......@@ -34,7 +34,7 @@ public interface IdExtensionType{
* Sets the id for the extension type instance.
* This method should be called only if the id was undefined before.
* The id should not be changed thereafter.
* @param id
* @param id id string
*/
void setId(String id);
......
......@@ -34,15 +34,15 @@ public interface PatientStore {
/**
* Get alias ids for the given patient (e.g. resulting from a merge)
* @param patient
* @return
* @param patient patient instance
* @return alias ids
*/
String[] getAliasIds(Patient patient);
/**
* Deletes the patient identified by given id. This method does not remove any other associated
* data e.g. like visits, observations.
* @param id
* @param id patient id
*/
void purge(String id);
}
......@@ -123,8 +123,8 @@ public class I2b2Inserter extends AbstractObservationHandler implements Observat
}
/**
* Deletes all observations with the given sourceId
* @param sourceId
* @throws SQLException
* @param sourceId source id
* @throws SQLException if the DELETE statement failed
*/
public synchronized void purgeSource(String sourceId)throws SQLException{
deleteSource.setString(1, sourceId);
......@@ -135,8 +135,8 @@ public class I2b2Inserter extends AbstractObservationHandler implements Observat
/**
* Deletes all observations for the given encounter_num
* @param encounter_num
* @throws SQLException
* @param encounter_num encounter number (e.g. observation_fact.encounter_num)
* @throws SQLException if the DELETE statement failed.
*/
public synchronized void purgeVisit(int encounter_num) throws SQLException{
deleteVisit.setInt(1, encounter_num);
......@@ -165,8 +165,8 @@ public class I2b2Inserter extends AbstractObservationHandler implements Observat
}
/**
* Opens a database connection and prepares statements
* @throws SQLException
* @throws ClassNotFoundException
* @throws SQLException if preparation/initialisation failed
* @throws ClassNotFoundException if database driver not found
*/
private void open(Map<String,String> props)throws SQLException, ClassNotFoundException{
db = PostgresExtension.getConnection(props);
......
......@@ -40,7 +40,7 @@ import de.sekmi.histream.Plugin;
*
* @author Raphael
*
* @param <T>
* @param <T> extension instance type
*/
abstract class PostgresExtension<T> implements Extension<T>, Plugin {
private static final int defaultFetchSize = 10000;
......
......@@ -106,16 +106,16 @@ public class PostgresPatientStore extends PostgresExtension<I2b2Patient> impleme
/**
* Construct new postgres patient store. In addition to properties
* needed by {@link PostgresExtension#PostgresExtension(Properties), the
* following properties are needed:
* needed by {@link PostgresExtension#PostgresExtension(Map)},
* the following properties are needed:
* <p>projectId,
* <p>Optional properties:
* <p>
* idSourceDefault ('HIVE'), idSourceSeparator (single char, ':')
* fetchSize (int, 10000)
* @param configuration
* @throws SQLException
* @throws ClassNotFoundException
* @param configuration configuration
* @throws SQLException if the preparation or initialisation fails
* @throws ClassNotFoundException if postgresql driver not found
*/
public PostgresPatientStore(Map<String,String> configuration) throws ClassNotFoundException, SQLException {
super(configuration);
......@@ -330,8 +330,8 @@ public class PostgresPatientStore extends PostgresExtension<I2b2Patient> impleme
/**
* Insert a new patient into the database. Only patient_num and sourcesystem_cd are filled.
* @param patient
* @throws SQLException
* @param patient patient object
* @throws SQLException if INSERT failed
*/
private void insertPatient(I2b2Patient patient) throws SQLException{
synchronized( insert ){
......@@ -343,9 +343,9 @@ public class PostgresPatientStore extends PostgresExtension<I2b2Patient> impleme
}
/**
* Get the i2b2 sex_cd for a patient
* @param patient
* @return
* Get the i2b2 sex_cd for a patient. Currently, only M and F are supported.
* @param patient patient object
* @return i2b2 sex_cd
*/
private static String getSexCd(Patient patient){
if( patient.getSex() == null )return null;
......@@ -360,8 +360,9 @@ public class PostgresPatientStore extends PostgresExtension<I2b2Patient> impleme
}
}
/**
* Get the i2b2 vital_status_cd for a patient
* @param patient
* Get the i2b2 vital_status_cd for a patient.
* Values Y,M,X,R,T,S can be returned.
* @param patient patient object
* @return vital status code, see CRC_Design doc
*/
private static String getVitalStatusCd(Patient patient){
......
......@@ -172,9 +172,9 @@ public class PostgresVisitStore extends PostgresExtension<I2b2Visit>{
/**
* Set aliases for a visit, puts aliases into cache.
*
* @param visit
* @param aliases
* @param primary
* @param visit visit instance
* @param aliases alias patient IDs (e.g. merged)
* @param primary index of primary alias (in aliases)
*/
private void setAliases(I2b2Visit visit, String[] aliases, int primary){
visit.aliasIds = aliases;
......@@ -287,7 +287,7 @@ public class PostgresVisitStore extends PostgresExtension<I2b2Visit>{
/**
* Add the visit to storage. Patient information is not written
* @param visit visit to add
* @throws SQLException
* @throws SQLException if the INSERT failed
*/
private void addToStorage(I2b2Visit visit) throws SQLException{
synchronized( insert ){
......@@ -317,8 +317,9 @@ public class PostgresVisitStore extends PostgresExtension<I2b2Visit>{
}
/**
* Get the i2b2 vital_status_cd for a patient
* @param visit
* Get the i2b2 vital_status_cd for a patient.
* TODO move method to generic i2b2 support class.
* @param visit visit object
* @return vital status code, see CRC_Design doc
*/
private static String getActiveStatusCd(Visit visit){
......
/**
* Connectors for i2b2 integration.
*
* Currently, only insertion in i2b2 is supported, e.g. for designing ETL processes.
* <p>
* Future versions will include support to query or export data from i2b2.
*
* @author marap1
*
*/
package de.sekmi.histream.i2b2;
/*
* #%L
* histream
* %%
* Copyright (C) 2013 - 2015 R.W.Majeed
* %%
* 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.
* #L%
*/
......@@ -47,8 +47,8 @@ public abstract class AbstractObservationHandler implements ObservationHandler{
/**
* Accept method which allows exceptions. Exceptions are passed to the error handler
* specified via {@link #setErrorHandler(Consumer)}.
* @param observation
* @throws ObservationException
* @param observation observation
* @throws ObservationException for errors during the accept operation
*/
protected abstract void acceptOrException(Observation observation)throws ObservationException;
......
......@@ -83,12 +83,12 @@ public class ObservationFactoryImpl implements ObservationFactory{
/**
* Set extension
* @param observation
* @param extensionType
* @param extension
* @param observation observation
* @param extensionType extension type
* @param extension extension
* @throws IllegalArgumentException if extension type is not part of the registered extensions
*/
protected <T> void setExtension(ObservationImpl observation, Class<T> extensionType, T extension)throws IllegalArgumentException {
<T> void setExtension(ObservationImpl observation, Class<T> extensionType, T extension)throws IllegalArgumentException {
ExtensionEntry e = extensions.get(extensionType);
if( e == null )throw new IllegalArgumentException("Unsupported extension type "+extensionType);
setExtension(observation, e, extension);
......
......@@ -59,8 +59,8 @@ public class ObservationImpl implements Observation{
/**
* Constructor should not be called directly. Instead, use
* {@link ObservationFactory#}
* @param factory
* {@link ObservationFactory#createObservation(String, String, DateTimeAccuracy)}.
* @param factory observation factory
*/
protected ObservationImpl(ObservationFactoryImpl factory){
this.factory = factory;
......@@ -119,7 +119,7 @@ public class ObservationImpl implements Observation{
* Assign a modifier to the concept. This will overwrite any existing modifier
* with the same modifierId.
*
* @param modifier
* @param modifier modifier
*/
public void setModifier(Modifier modifier){
// lazy create hashtable only, when a modifier is set
......
......@@ -47,8 +47,8 @@ public class AbstractObservationParser {
/**
* Set meta information for this parser
* @param key
* @param value
* @param key meta key
* @param value meta value
*/
protected void setMeta(String key, String value){
if( value == null ){
......
......@@ -47,7 +47,23 @@ import de.sekmi.histream.impl.NumericValue;
import de.sekmi.histream.impl.StringValue;
/**
* Reads observations from flat text files.
*
* <p>
* Compatible text files are read line by line via {@link BufferedReader#readLine()}.
* The line separator characters are system dependent.
* <p>
* The file MUST start with a header line which should list the headers specified in {@link #minHeaders}.
* Additional column headers are allowed to the right of the minimum headers.
* <p>
* Each of the following lines may start with a comment character, which by default is '#'.
* <p>
* If the comment starts with '#@', then the line is understood as special command
* to the reader. Allowed commands are {@code #@meta}, {@code #@concept} and {@code #@group}.
* <p>
* Any non-empty lines which are not comments are parsed as delimited values.
* TODO describe colums.
*
* @author Raphael
*
*/
......
......@@ -40,8 +40,7 @@ import de.sekmi.histream.impl.NumericValue;
import de.sekmi.histream.impl.StringValue;
/**
* Parser for EAV XML documents. This class is used by both the {@link SAXObservationProvider}
* and {@link XMLObservationProvider}.
* Parser for EAV XML documents. This class is used by {@link XMLObservationProvider}.
*
* @author marap1
*
......@@ -221,7 +220,7 @@ class XMLObservationParser extends AbstractObservationParser{
/**