Package org.openengsb.core.ekb.persistence.query.edb.internal

Source Code of org.openengsb.core.ekb.persistence.query.edb.internal.QueryInterfaceService

/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI 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.openengsb.core.ekb.persistence.query.edb.internal;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.openengsb.core.api.model.CommitMetaInfo;
import org.openengsb.core.api.model.CommitQueryRequest;
import org.openengsb.core.api.model.ModelDescription;
import org.openengsb.core.api.model.QueryRequest;
import org.openengsb.core.edb.api.EDBCommit;
import org.openengsb.core.edb.api.EDBConstants;
import org.openengsb.core.edb.api.EDBException;
import org.openengsb.core.edb.api.EDBObject;
import org.openengsb.core.edb.api.EngineeringDatabaseService;
import org.openengsb.core.ekb.api.EKBCommit;
import org.openengsb.core.ekb.api.EKBException;
import org.openengsb.core.ekb.api.ModelRegistry;
import org.openengsb.core.ekb.api.QueryInterface;
import org.openengsb.core.ekb.api.QueryParser;
import org.openengsb.core.ekb.common.EDBConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Implementation of the QueryInterface service. It's main responsibilities are the loading of elements from the EDB and
* converting them to the correct format.
*/
public class QueryInterfaceService implements QueryInterface {
    private static final Logger LOGGER = LoggerFactory.getLogger(QueryInterfaceService.class);
    private EngineeringDatabaseService edbService;
    private EDBConverter edbConverter;
    private ModelRegistry modelRegistry;
    private List<QueryParser> queryParsers;

    @Override
    public <T> T getModel(Class<T> model, String oid) {
        LOGGER.debug("Invoked getModel with the model {} and the oid {}", model.getName(), oid);
        EDBObject object = edbService.getObject(oid);
        return edbConverter.convertEDBObjectToModel(model, object);
    }

    @Override
    public <T> List<T> getModelHistory(Class<T> model, String oid) {
        LOGGER.debug("Invoked getModelHistory with the model {} and the oid {}", model.getName(), oid);
        return edbConverter.convertEDBObjectsToModelObjects(model, edbService.getHistory(oid));
    }

    @Override
    public <T> List<T> getModelHistoryForTimeRange(Class<T> model, String oid, Long from, Long to) {
        LOGGER.debug("Invoked getModelHistoryForTimeRange with the model {} and the oid {} for the "
                + "time period of {} to {}",
            new Object[]{ model.getName(), oid, new Date(from).toString(), new Date(to).toString() });
        return edbConverter.convertEDBObjectsToModelObjects(model, edbService.getHistoryForTimeRange(oid, from, to));
    }

    @Override
    public <T> List<T> query(Class<T> model, QueryRequest request) {
        LOGGER.debug("Query for model {} with the request {}", model.getName(), request);
        request.setModelClassName(model.getName());
        return edbConverter.convertEDBObjectsToModelObjects(model, edbService.query(request));
    }

    @Override
    public <T> List<T> queryByString(Class<T> model, String query) {
        return query(model, parseQueryString(query));
    }

    @Override
    public <T> List<T> queryByStringAndTimestamp(Class<T> model, String query, String timestamp) {
        Long time;
        if (timestamp == null || timestamp.isEmpty()) {
            LOGGER.debug("Got invalid timestamp string. Use the current timestamp instead");
            time = System.currentTimeMillis();
        } else {
            time = Long.parseLong(timestamp);
        }
        QueryRequest request = parseQueryString(query);
        request.setTimestamp(time);
        return query(model, request);
    }

    @Override
    public QueryRequest parseQueryString(String query) throws EKBException {
        if (query.isEmpty()) {
            return QueryRequest.create();
        }
        for (QueryParser parser : queryParsers) {
            if (parser.isParsingPossible(query)) {
                return parser.parseQueryString(query);
            }
        }
        throw new EKBException("There is no active parser which is able to parse the query string " + query);
    }

    @Override
    public <T> List<T> queryForActiveModels(Class<T> model) {
        LOGGER.debug("Invoked queryForActiveModels with the model {}", model.getName());
        return query(model, QueryRequest.create());
    }

    @Override
    public UUID getCurrentRevisionNumber() {
        return edbService.getCurrentRevisionNumber();
    }

    @Override
    public UUID getLastRevisionNumberOfContext(String contextId) {
        return edbService.getLastRevisionNumberOfContext(contextId);
    }

    @Override
    public List<CommitMetaInfo> queryForCommits(CommitQueryRequest request) throws EKBException {
        return edbService.getRevisionsOfMatchingCommits(request);
    }

    @Override
    public EKBCommit loadCommit(String revision) throws EKBException {
        try {
            EDBCommit commit = edbService.getCommitByRevision(revision);
            return convertEDBCommitToEKBCommit(commit);
        } catch (EDBException e) {
            throw new EKBException("There is no commit with the revision " + revision);
        }
    }

    /**
     * Converts an EDBCommit object into an EKBCommit object.
     */
    private EKBCommit convertEDBCommitToEKBCommit(EDBCommit commit) throws EKBException {
        EKBCommit result = new EKBCommit();
        Map<ModelDescription, Class<?>> cache = new HashMap<>();
        result.setRevisionNumber(commit.getRevisionNumber());
        result.setComment(commit.getComment());
        result.setParentRevisionNumber(commit.getParentRevisionNumber());
        result.setDomainId(commit.getDomainId());
        result.setConnectorId(commit.getConnectorId());
        result.setInstanceId(commit.getInstanceId());
        for (EDBObject insert : commit.getInserts()) {
            result.addInsert(createModelOfEDBObject(insert, cache));
        }
        for (EDBObject update : commit.getUpdates()) {
            result.addUpdate(createModelOfEDBObject(update, cache));
        }
        for (String delete : commit.getDeletions()) {
            EDBObject object = edbService.getObject(delete, commit.getTimestamp());
            result.addDelete(createModelOfEDBObject(object, cache));
        }
        return result;
    }

    /**
     * Converts an EDBObject instance into a model. For this, the method need to retrieve the model class to be able to
     * instantiate the corresponding model objects. If the conversion fails, null is returned.
     */
    private Object createModelOfEDBObject(EDBObject object, Map<ModelDescription, Class<?>> cache) {
        try {
            ModelDescription description = getDescriptionFromObject(object);
            Class<?> modelClass;
            if (cache.containsKey(description)) {
                modelClass = cache.get(description);
            } else {
                modelClass = modelRegistry.loadModel(description);
                cache.put(description, modelClass);
            }
            return edbConverter.convertEDBObjectToModel(modelClass, object);
        } catch (IllegalArgumentException | ClassNotFoundException e) {
            LOGGER.warn("Unable to create model of the object {}", object.getOID(), e);
            return null;
        }
    }

    /**
     * Extracts the required values to lookup a model class from the given EDBObject. If this object does not contain
     * the required information, an IllegalArgumentException is thrown.
     */
    private ModelDescription getDescriptionFromObject(EDBObject obj) {
        String modelName = obj.getString(EDBConstants.MODEL_TYPE);
        String modelVersion = obj.getString(EDBConstants.MODEL_TYPE_VERSION);
        if (modelName == null || modelVersion == null) {
            throw new IllegalArgumentException("The object " + obj.getOID() + " contains no model information");
        }
        return new ModelDescription(modelName, modelVersion);
    }

    public void setEdbService(EngineeringDatabaseService edbService) {
        this.edbService = edbService;
    }

    public void setEdbConverter(EDBConverter edbConverter) {
        this.edbConverter = edbConverter;
    }

    public void setModelRegistry(ModelRegistry modelRegistry) {
        this.modelRegistry = modelRegistry;
    }

    public void setQueryParsers(List<QueryParser> queryParsers) {
        this.queryParsers = queryParsers;
    }
}
TOP

Related Classes of org.openengsb.core.ekb.persistence.query.edb.internal.QueryInterfaceService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.