org.eclipse.osee.orcs.db.internal.sql.SqlFieldResolver.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.osee.orcs.db.internal.sql.SqlFieldResolver.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Boeing.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Boeing - initial API and implementation
 *******************************************************************************/
package org.eclipse.osee.orcs.db.internal.sql;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.osee.framework.jdk.core.type.CountingMap;
import org.eclipse.osee.orcs.core.ds.DynamicData;
import org.eclipse.osee.orcs.core.ds.DynamicObject;
import org.eclipse.osee.orcs.core.ds.ResultObjectDescription;
import org.eclipse.osee.orcs.core.ds.SelectSet;
import org.eclipse.osee.orcs.db.internal.sql.ObjectField.Family;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;

/**
 * @author Roberto E. Escobar
 */
public final class SqlFieldResolver {

    private final SqlAliasManager aliasManager;
    private final List<DynamicData> unresolved = new ArrayList<DynamicData>();
    private final CountingMap<String> counter = new CountingMap<String>();
    private final Iterable<SelectSet> selectSets;
    private boolean selectsProcessed;

    public SqlFieldResolver(SqlAliasManager aliasManager, Iterable<SelectSet> selectSets) {
        this.aliasManager = aliasManager;
        this.selectSets = selectSets;
    }

    public void reset() {
        counter.clear();
        unresolved.clear();
        selectsProcessed = false;
    }

    public boolean hasUnresolvedFields() {
        return unresolved != null && !unresolved.isEmpty();
    }

    public Iterable<DynamicData> getUnresolved() {
        return unresolved;
    }

    public Iterable<String> getSortFields() {
        Map<ObjectField, String> fieldToColumn = new LinkedHashMap<ObjectField, String>();
        for (SelectSet selectSet : selectSets) {
            DynamicData data = selectSet.getData();
            if (data != null) {
                loadRequiredFields(data, fieldToColumn);
            }
        }

        List<String> toReturn = new ArrayList<String>();
        Set<Family> processed = new HashSet<Family>();
        for (Entry<ObjectField, String> entry : fieldToColumn.entrySet()) {
            ObjectField key = entry.getKey();
            Family family = key.getFamily();
            if (processed.add(family)) {
                for (ObjectField field : ObjectField.getRequiredFieldsFor(family)) {
                    String column = fieldToColumn.get(field);
                    toReturn.add(column);
                }
            }
        }
        return toReturn;
    }

    private void loadRequiredFields(DynamicData data, Map<ObjectField, String> fieldToColumn) {
        if (data instanceof DynamicObject) {
            DynamicObject object = (DynamicObject) data;
            for (DynamicData child : object.getChildren()) {
                loadRequiredFields(child, fieldToColumn);
            }
        } else {
            ObjectField objectField = getObjectField(data);
            if (objectField != null && objectField.isRequired()) {
                String uniqueId = getColumnUniqueId(data);
                fieldToColumn.put(objectField, uniqueId);
            }
        }
    }

    public ResultObjectDescription getResult() {
        final List<DynamicData> datas = new ArrayList<DynamicData>();
        for (SelectSet selectSet : selectSets) {
            DynamicData data = selectSet.getData();
            if (data != null) {
                datas.add(data);
            }
        }
        return new ResultObjectDescription() {

            @Override
            public Iterable<? extends DynamicData> getDynamicData() {
                return datas;
            }
        };
    }

    private String getQualifiedName(String alias, String columnName) {
        return String.format("%s.%s", alias, columnName);
    }

    public void resolve() {
        if (!selectsProcessed) {
            selectsProcessed = true;
            processSelects();
        } else {
            processUnresolved();
        }
    }

    private void processSelects() {
        for (SelectSet selectSet : selectSets) {
            DynamicData data = selectSet.getData();
            if (data != null) {
                processData(data);
            }
        }
    }

    private void processData(DynamicData data) {
        if (data instanceof DynamicObject) {
            DynamicObject object = (DynamicObject) data;
            for (DynamicData child : object.getChildren()) {
                processData(child);
            }
            addRequiredFields(object);
        } else {
            processField(data, false);
        }
    }

    private void addRequiredFields(DynamicObject object) {
        Family family = null;
        int level = object.getLevel();
        Set<ObjectField> fields = new HashSet<ObjectField>();
        for (DynamicData child : object.getChildren()) {
            String fieldId = child.getGuid();
            if (fieldId != null) {
                ObjectField objectField = ObjectField.fromString(fieldId);
                if (objectField != null) {
                    family = objectField.getFamily();
                    fields.add(objectField);
                    level = child.getLevel();
                }
            }
        }
        if (family != null && !fields.isEmpty()) {
            Set<ObjectField> required = ObjectField.getRequiredFieldsFor(family);
            SetView<ObjectField> missing = Sets.difference(required, fields);

            int index = 0;
            for (ObjectField field : missing) {
                String fieldId = field.name();
                DynamicData data = new DynamicData(fieldId, null);
                data.setLevel(level);
                data.setFieldName(fieldId);
                processField(data, true);
                object.addChild(index++, data);
            }
        }
    }

    private void processField(DynamicData data, boolean hidden) {
        String fieldId = data.getGuid();
        if (fieldId != null) {
            ObjectField field = getObjectField(data);
            if (field == null) {
                field = ObjectField.fromString(fieldId);
                setObjectField(data, field);
            }

            int level = data.getLevel();
            data.setPrimaryKey(field.isPrimaryKey());
            data.setHidden(hidden);

            TableEnum table = field.getTable();
            ObjectType type = field.getType();
            String alias = aliasManager.getFirstAlias(level, table, type);

            if (alias != null) {
                resolve(data, field, alias);
            } else {
                unresolved.add(data);
            }
        }
    }

    private void resolve(DynamicData data, ObjectField field, String alias) {
        Map<String, String> columnData = Maps.newLinkedHashMap();

        String[] columnNames = field.getColumnNames();
        for (String columnName : columnNames) {
            String columnUuid;
            if (field.isComposite()) {
                columnUuid = String.format("%s_%s", columnName, nextColumnIndex(columnName));
            } else {
                columnUuid = String.format("%s_%s", field.name(), nextColumnIndex(columnName));
            }
            String qualifiedColumn = getQualifiedName(alias, columnName);
            columnData.put(columnUuid, qualifiedColumn);
        }
        setColumnInfo(data, columnData);
    }

    private int nextColumnIndex(String columnName) {
        counter.put(columnName);
        return counter.get(columnName);
    }

    private void processUnresolved() {
        Iterator<DynamicData> iterator = getUnresolved().iterator();
        while (iterator.hasNext()) {
            DynamicData data = iterator.next();
            ObjectField field = getObjectField(data);
            int level = data.getLevel();

            String alias = aliasManager.getFirstAlias(level, field.getTable(), field.getType());
            if (alias != null) {
                resolve(data, field, alias);
                iterator.remove();
            }
        }
    }

    private static final String OBJECT_FIELD = "sql.object.field";
    private static final String COLUMN_INFO = "sql.column.info";

    public static void setObjectField(DynamicData data, ObjectField field) {
        data.put(OBJECT_FIELD, field);
    }

    public static ObjectField getObjectField(DynamicData data) {
        return data.getObject(OBJECT_FIELD);
    }

    public static void setColumnInfo(DynamicData data, Map<String, String> columnData) {
        data.put(COLUMN_INFO, columnData);
    }

    public static Map<String, String> getColumnInfo(DynamicData data) {
        Map<String, String> columnData = data.getObject(COLUMN_INFO);
        return columnData != null ? columnData : Collections.<String, String>emptyMap();
    }

    public static Collection<String> getColumnUniqueIds(DynamicData data) {
        return getColumnInfo(data).keySet();
    }

    public static String getColumnUniqueId(DynamicData data) {
        return Iterables.getFirst(getColumnUniqueIds(data), null);
    }

}