All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.intelie.liverig.witsml.server.WITSMLServer Maven / Gradle / Ivy

The newest version!
package net.intelie.liverig.witsml.server;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import net.intelie.liverig.util.XMLOutputFactoryFactory;
import net.intelie.liverig.util.XMLStreamWriterAutoCloseable;
import net.intelie.liverig.witsml.StoreSoapPortInterface;
import net.intelie.liverig.witsml.WITSMLBaseMsg;
import net.intelie.liverig.witsml.WITSMLException;
import net.intelie.liverig.witsml.WITSMLResult;
import net.intelie.liverig.witsml.objects.ApiVers;
import net.intelie.liverig.witsml.objects.LogDateTimeIndex;
import net.intelie.liverig.witsml.objects.LogIndex;
import org.jetbrains.annotations.Nullable;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.StringWriter;
import java.util.*;

public class WITSMLServer implements StoreSoapPortInterface {
    private static final Splitter OPTIONS_SPLITTER = Splitter.on(';').omitEmptyStrings().trimResults();
    private static final Splitter SPLITTER = Splitter.on(',').trimResults();
    private static final Joiner JOINER = Joiner.on(',');

    private final Config config;

    public WITSMLServer(Config config) {
        this.config = config;
    }

    @Override
    public String addToStore(String type, String xml, String options, String capabilitiesIn) throws WITSMLException {
        throw new WITSMLException((short) -414);
    }

    @Override
    public void deleteFromStore(String type, String query, String options, String capabilitiesIn) throws WITSMLException {
        throw new WITSMLException((short) -414);
    }

    @Override
    public String getBaseMsg(short result) {
        return WITSMLBaseMsg.getBaseMsg(result);
    }

    @Override
    public String getCap(String options) throws WITSMLException {
        String dataVersion = option(options, "dataVersion");
        ApiVers apiVers = apiVers(Strings.isNullOrEmpty(dataVersion) ? "1.3.1.1" : dataVersion);
        if (apiVers == null) {
            throw new WITSMLException((short) -423);
        }
        return config.getCap(apiVers).toString();
    }

    @Override
    public WITSMLResult getFromStore(String type, String query, String options, String capabilitiesIn) throws WITSMLException {
        if (Strings.isNullOrEmpty(type)) {
            throw new WITSMLException((short) -407);
        }
        if (Strings.isNullOrEmpty(query)) {
            throw new WITSMLException((short) -408);
        }

        QueryParser parser = new QueryParser();
        parser.parse(query);
        if (!(type + 's').equals(parser.collection())) {
            throw new WITSMLException((short) -409);
        }

        ApiVers apiVers = apiVers(parser.version());
        if (apiVers == null) {
            throw new WITSMLException((short) -409);
        }

        String returnElements = option(options, "returnElements");

        StringWriter sw = new StringWriter();
        try (XMLStreamWriterAutoCloseable ac = XMLOutputFactoryFactory.createXMLStreamWriter(sw)) {
            XMLStreamWriter writer = ac.get();
            writer.setDefaultNamespace(apiVers.getSchemaNamespace());
            writer.writeStartElement(apiVers.getSchemaNamespace(), parser.collection());
            writer.writeDefaultNamespace(apiVers.getSchemaNamespace());
            writer.writeAttribute("version", apiVers.getSchemaVersion());

            for (QueryParser.Query entry : parser.queries()) {
                getFromStore(writer, apiVers, entry, returnElements);
            }

            writer.writeEndDocument();
        } catch (XMLStreamException e) {
            throw new WITSMLException(WITSMLException.UNKNOWN_PROGRAM_ERROR, e);
        }
        return new WITSMLResult(sw.toString());
    }

    private void getFromStore(XMLStreamWriter writer, ApiVers apiVers, QueryParser.Query query,
                              @Nullable String returnElements) throws WITSMLException, XMLStreamException {
        boolean id_only = apiVers == ApiVers.WITSML_141 && "id-only".equals(returnElements);
        boolean header_only = apiVers == ApiVers.WITSML_141 && "header-only".equals(returnElements);
        boolean data_only = apiVers == ApiVers.WITSML_141 && "data-only".equals(returnElements);
        boolean all = "all".equals(returnElements);
        boolean requested = !(id_only || header_only || data_only || all);
        boolean header = !id_only && !data_only;
        boolean data = data_only || all || (requested && query.getRequested().contains("logData"));

        if ("well".equals(query.getObject())) {
            for (Well well : getWells(query.getUid())) {
                writer.writeStartElement(apiVers.getSchemaNamespace(), "well");
                writer.writeAttribute("uid", Strings.nullToEmpty(well.getUid()));
                writeSimpleElement(writer, apiVers.getSchemaNamespace(), "name", Strings.nullToEmpty(well.getName()));
                writer.writeEndElement();
            }
        } else if ("wellbore".equals(query.getObject())) {
            for (Wellbore wellbore : getWellbores(query.getUidWell(), query.getUid())) {
                Well well = wellbore.getWell();
                writer.writeStartElement(apiVers.getSchemaNamespace(), "wellbore");
                writer.writeAttribute("uidWell", Strings.nullToEmpty(well.getUid()));
                writer.writeAttribute("uid", Strings.nullToEmpty(wellbore.getUid()));
                writeSimpleElement(writer, apiVers.getSchemaNamespace(), "nameWell", Strings.nullToEmpty(well.getName()));
                writeSimpleElement(writer, apiVers.getSchemaNamespace(), "name", Strings.nullToEmpty(wellbore.getName()));
                writer.writeEndElement();
            }
        } else if ("log".equals(query.getObject())) {
            for (Log log : getLogs(query.getUidWell(), query.getUidWellbore(), query.getUid())) {
                Wellbore wellbore = log.getWellbore();
                Well well = wellbore.getWell();
                writer.writeStartElement(apiVers.getSchemaNamespace(), "log");
                writer.writeAttribute("uidWell", Strings.nullToEmpty(well.getUid()));
                writer.writeAttribute("uidWellbore", Strings.nullToEmpty(wellbore.getUid()));
                writer.writeAttribute("uid", Strings.nullToEmpty(log.getUid()));
                writeSimpleElement(writer, apiVers.getSchemaNamespace(), "nameWell", Strings.nullToEmpty(well.getName()));
                writeSimpleElement(writer, apiVers.getSchemaNamespace(), "nameWellbore", Strings.nullToEmpty(wellbore.getName()));
                writeSimpleElement(writer, apiVers.getSchemaNamespace(), "name", Strings.nullToEmpty(log.getName()));

                List mnemonics = new ArrayList<>(log.getCurves().keySet());
                List units = null;
                if (apiVers == ApiVers.WITSML_141) {
                    units = new ArrayList<>(mnemonics.size());
                    Map curves = log.getCurves();
                    for (String mnemonic : mnemonics) {
                        units.add(curves.get(mnemonic).getUnit());
                    }
                }

                List> logData = null;
                if (data) {
                    logData = config.getLogData(log, getLogIndex(query), getLogDateTimeIndex(query));
                }

                if (header) {
                    if (!requested || query.getRequested().contains("indexType")) {
                        writeSimpleElement(writer, apiVers.getSchemaNamespace(), "indexType", Strings.nullToEmpty(log.getIndexType()));
                    }

                    // TODO depth index

                    if (!requested || query.getRequested().contains("startDateTimeIndex")) {
                        String startDateTimeIndex = null;   // TODO header-only index
                        if ("date time".equals(log.getIndexType()) && data && !logData.isEmpty()) {
                            startDateTimeIndex = logData.get(0).get(log.getIndexCurve());
                        }
                        writeSimpleElement(writer, apiVers.getSchemaNamespace(), "startDateTimeIndex", Strings.nullToEmpty(startDateTimeIndex));
                    }

                    if (!requested || query.getRequested().contains("endDateTimeIndex")) {
                        String endDateTimeIndex = null;     // TODO header-only index
                        if ("date time".equals(log.getIndexType()) && data && !logData.isEmpty()) {
                            endDateTimeIndex = logData.get(logData.size() - 1).get(log.getIndexCurve());
                        }
                        writeSimpleElement(writer, apiVers.getSchemaNamespace(), "endDateTimeIndex", Strings.nullToEmpty(endDateTimeIndex));
                    }

                    if (!requested || query.getRequested().contains("indexCurve")) {
                        int index = mnemonics.indexOf(log.getIndexCurve());
                        if (index >= 0 || apiVers != ApiVers.WITSML_131) {
                            writer.writeStartElement(apiVers.getSchemaNamespace(), "indexCurve");
                            if (apiVers == ApiVers.WITSML_131) {
                                writer.writeAttribute("columnIndex", String.valueOf(index + 1));
                            }
                            writer.writeCharacters(Strings.nullToEmpty(log.getIndexCurve()));
                            writer.writeEndElement();
                        }
                    }

                    if (!requested || query.getRequested().contains("logCurveInfo")) {
                        int index = 0;
                        for (String mnemonic : mnemonics) {
                            Curve curve = log.getCurves().get(mnemonic);
                            writer.writeStartElement(apiVers.getSchemaNamespace(), "logCurveInfo");
                            writer.writeAttribute("uid", Strings.nullToEmpty(curve.getUid()));
                            writeSimpleElement(writer, apiVers.getSchemaNamespace(), "mnemonic", mnemonic);
                            writeSimpleElement(writer, apiVers.getSchemaNamespace(), "unit", curve.getUnit());
                            if (apiVers == ApiVers.WITSML_131) {
                                writeSimpleElement(writer, apiVers.getSchemaNamespace(), "columnIndex", String.valueOf(++index));
                            }
                            writeSimpleElement(writer, apiVers.getSchemaNamespace(), "typeLogData", curve.getTypeLogData());
                            writer.writeEndElement();
                        }
                    }
                }

                if (data) {
                    writer.writeStartElement(apiVers.getSchemaNamespace(), "logData");
                    if (apiVers == ApiVers.WITSML_141) {
                        writeSimpleElement(writer, apiVers.getSchemaNamespace(), "mnemonicList", JOINER.join(mnemonics));
                        writeSimpleElement(writer, apiVers.getSchemaNamespace(), "unitList", JOINER.join(units));
                    }
                    for (Map row : logData) {
                        writer.writeStartElement(apiVers.getSchemaNamespace(), "data");
                        for (int i = 0; i < mnemonics.size(); i++) {
                            if (i > 0) {
                                writer.writeCharacters(",");
                            }
                            Object value = row.get(mnemonics.get(i));
                            writer.writeCharacters(value != null ? value.toString() : "");
                        }
                        writer.writeEndElement();
                    }
                    writer.writeEndElement();
                }
                writer.writeEndElement();
            }
        } else {
            throw new WITSMLException((short) -470);
        }
    }

    private Iterable getWells(String uid) {
        if (Strings.isNullOrEmpty(uid)) {
            return config.getWells();
        } else {
            return Optional.ofNullable(config.getWell(uid))
                    .map(Collections::singleton)
                    .orElse(Collections.emptySet());
        }
    }

    private Iterable getWellbores(String uidWell, String uid) {
        if (Strings.isNullOrEmpty(uidWell)) {
            List wellbores = new ArrayList<>();
            for (Well well : getWells(uidWell)) {
                Iterables.addAll(wellbores, config.getWellbores(well.getUid()));
            }
            return wellbores;
        } else if (Strings.isNullOrEmpty(uid)) {
            return config.getWellbores(uidWell);
        } else {
            return Optional.ofNullable(config.getWellbore(uidWell, uid))
                    .map(Collections::singleton)
                    .orElse(Collections.emptySet());
        }
    }

    private Iterable getLogs(String uidWell, String uidWellbore, String uid) {
        if (Strings.isNullOrEmpty(uidWell) || Strings.isNullOrEmpty(uidWellbore)) {
            List logs = new ArrayList<>();
            for (Wellbore wellbore : getWellbores(uidWell, uidWellbore)) {
                Iterables.addAll(logs, config.getLogs(wellbore.getWell().getUid(), wellbore.getUid()));
            }
            return logs;
        } else if (Strings.isNullOrEmpty(uid)) {
            return config.getLogs(uidWell, uidWellbore);
        } else {
            return Optional.ofNullable(config.getLog(uidWell, uidWellbore, uid))
                    .map(Collections::singleton)
                    .orElse(Collections.emptySet());
        }
    }

    private static LogIndex getLogIndex(QueryParser.Query query) {
        if (Strings.isNullOrEmpty(query.getStartIndex()) && Strings.isNullOrEmpty(query.getEndIndex())) {
            return null;
        }
        try {
            LogIndex index = new LogIndex();
            index.setStartIndex(Double.valueOf(query.getStartIndex()));
            index.setStartIndexUom(query.getStartIndexUom());
            index.setEndIndex(Double.valueOf(query.getEndIndex()));
            index.setEndIndexUom(query.getEndIndexUom());
            return index;
        } catch (NumberFormatException e) {
            return null;
        }
    }

    private static LogDateTimeIndex getLogDateTimeIndex(QueryParser.Query query) {
        if (Strings.isNullOrEmpty(query.getStartDateTimeIndex()) && Strings.isNullOrEmpty(query.getEndDateTimeIndex())) {
            return null;
        }
        LogDateTimeIndex index = new LogDateTimeIndex();
        index.setStartDateTimeIndex(query.getStartDateTimeIndex());
        index.setEndDateTimeIndex(query.getEndDateTimeIndex());
        return index;
    }

    @Override
    public String getVersion() {
        return "1.3.1.1,1.4.1.1";
    }

    @Override
    public void updateInStore(String type, String xml, String options, String capabilitiesIn) throws WITSMLException {
        if (Strings.isNullOrEmpty(type)) {
            throw new WITSMLException((short) -407);
        }
        if (Strings.isNullOrEmpty(xml)) {
            throw new WITSMLException((short) -408);
        }

        QueryParser parser = new QueryParser();
        parser.parse(xml);
        if (!(type + 's').equals(parser.collection())) {
            throw new WITSMLException((short) -409);
        }

        ApiVers apiVers = apiVers(parser.version());
        if (apiVers == null) {
            throw new WITSMLException((short) -409);
        }

        if (parser.queries().size() != 1) {
            throw new WITSMLException((short) -444);
        }
        QueryParser.Query query = parser.queries().get(0);

        if (!"log".equals(query.getObject())) {
            throw new WITSMLException((short) -414);
        }
        if (Strings.isNullOrEmpty(query.getUidWell()) || Strings.isNullOrEmpty(query.getUidWellbore()) || Strings.isNullOrEmpty(query.getUid())) {
            throw new WITSMLException((short) -415);
        }
        Log log = config.getLog(query.getUidWell(), query.getUidWellbore(), query.getUid());
        if (log == null) {
            throw new WITSMLException((short) -433);
        }

        Map columns;
        Map units;
        switch (apiVers) {
            case WITSML_131:
                if (query.getColumns() == null) {
                    throw new WITSMLException((short) -409);
                }
                columns = new HashMap<>(query.getColumns().size());
                for (Map.Entry entry : query.getColumns().entrySet()) {
                    try {
                        columns.put(Integer.valueOf(entry.getValue()), entry.getKey());
                    } catch (NumberFormatException e) {
                        throw new WITSMLException((short) -409, e);
                    }
                }

                units = query.getUnits();
                break;
            case WITSML_141:
                if (query.getMnemonicList() == null) {
                    throw new WITSMLException((short) -434);
                }
                columns = new HashMap<>();
                int i = 1;
                for (String mnemonic : SPLITTER.split(query.getMnemonicList())) {
                    columns.put(i++, mnemonic);
                }

                units = new LinkedHashMap<>(columns.size());
                i = 1;
                for (String unit : SPLITTER.split(query.getUnitList())) {
                    units.put(columns.get(i++), unit);
                }
                break;
            default:
                throw new WITSMLException(WITSMLException.UNKNOWN_PROGRAM_ERROR);
        }

        for (String row : query.getData()) {
            Map data = new LinkedHashMap<>(columns.size());
            int i = 1;
            for (String col : SPLITTER.split(row)) {
                data.put(columns.get(i++), col);
            }
            config.appendLogData(log, units, data);
        }
    }

    @Nullable
    private static String option(String options, String keyword) {
        for (String option : OPTIONS_SPLITTER.split(Strings.nullToEmpty(options))) {
            if (option.startsWith(keyword + '=')) {
                return option.substring(option.indexOf('=') + 1);
            }
        }
        return null;
    }

    @Nullable
    private static ApiVers apiVers(String version) {
        if ("1.3.1.1".equals(version)) {
            return ApiVers.WITSML_131;
        } else if ("1.4.1.1".equals(version)) {
            return ApiVers.WITSML_141;
        } else {
            return null;
        }
    }

    private static void writeSimpleElement(XMLStreamWriter writer, String namespace, String name, String value) throws XMLStreamException {
        if (value != null) {
            writer.writeStartElement(namespace, name);
            writer.writeCharacters(value);
            writer.writeEndElement();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy