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

org.apache.ignite.schema.model.PojoDescriptor Maven / Gradle / Ivy

Go to download

Java-based middleware for in-memory processing of big data in a distributed environment.

The newest version!
/*
 * 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.apache.ignite.schema.model;

import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.collections.*;
import org.apache.ignite.lang.*;
import org.apache.ignite.schema.parser.*;

import java.math.*;
import java.util.*;

import static java.sql.Types.*;

/**
 * Descriptor for java type.
 */
public class PojoDescriptor {
    /** Database table. */
    private final DbTable tbl;

    /** Selected property. */
    private final BooleanProperty useProp;

    /** Previous name for key class. */
    private final String keyClsNamePrev;

    /** Key class name to show on screen. */
    private final StringProperty keyClsNameProp;

    /** Previous name for value class. */
    private final String valClsNamePrev;

    /** Value class name to show on screen. */
    private final StringProperty valClsNameProp;

    /** Parent item (schema name). */
    private final PojoDescriptor parent;

    /** Children items (tables names). */
    private Collection children = Collections.emptyList();

    /** Indeterminate state of parent. */
    private final BooleanProperty indeterminateProp = new SimpleBooleanProperty(false);

    /** Full database name: schema + table. */
    private final String fullDbName;

    /** Java class fields. */
    private final ObservableList fields;

    /** Fields map for quick access. */
    private final Map fieldsMap;

    /**
     * Constructor of POJO descriptor.
     *
     * @param prn Parent descriptor.
     * @param tbl Database table Tab;e.
     */
    public PojoDescriptor(PojoDescriptor prn, DbTable tbl) {
        parent = prn;

        this.tbl = tbl;

        fullDbName = tbl.schema() + "." + tbl.table();

        valClsNamePrev = toJavaClassName(tbl.table());
        valClsNameProp = new SimpleStringProperty(valClsNamePrev);

        keyClsNamePrev = valClsNamePrev.isEmpty() ? "" : valClsNamePrev + "Key";
        keyClsNameProp = new SimpleStringProperty(keyClsNamePrev);

        Collection cols = tbl.columns();

        List flds = new ArrayList<>(cols.size());

        fieldsMap = new HashMap<>(cols.size());

        for (DbColumn col : cols) {
            String colName = col.name();

            PojoField fld = new PojoField(colName, col.type(),
                toJavaFieldName(colName), toJavaType(col.type(), col.nullable()).getName(),
                col.key(), col.nullable());

            fld.owner(this);

            flds.add(fld);

            fieldsMap.put(colName, fld);
        }

        fields = FXCollections.observableList(flds);

        boolean isTbl = parent != null;

        boolean hasKeys = !isTbl || !keyFields().isEmpty();

        useProp = new SimpleBooleanProperty(hasKeys);

        if (isTbl && !hasKeys && !parent.indeterminateProp.get())
            parent.indeterminateProp.set(true);

        useProp.addListener(new ChangeListener() {
            @Override public void changed(ObservableValue val, Boolean oldVal, Boolean newVal) {
                for (PojoDescriptor child : children)
                    child.useProp.set(newVal);

                if (parent != null && !parent.children.isEmpty()) {
                    Iterator it = parent.children.iterator();

                    boolean parentIndeterminate = false;
                    boolean first = it.next().useProp.get();

                    while (it.hasNext()) {
                        if (it.next().useProp.get() != first) {
                            parentIndeterminate = true;

                            break;
                        }
                    }

                    parent.indeterminateProp.set(parentIndeterminate);

                    if (!parentIndeterminate)
                        parent.useProp.set(first);
                }
            }
        });
    }

    /**
     * @return Parent descriptor.
     */
    public PojoDescriptor parent() {
        return parent;
    }

    /**
     * @return Full database name: schema + table.
     */
    public String fullDbName() {
        return fullDbName;
    }

    /**
     * @return {@code true} if POJO descriptor is a table descriptor and checked in GUI.
     */
    public boolean checked() {
        return parent != null && useProp.get();
    }

    /**
     * @return Boolean property support for {@code use} property.
     */
    public BooleanProperty useProperty() {
        return useProp;
    }

    /**
     * @return Boolean property support for parent {@code indeterminate} property.
     */
    public BooleanProperty indeterminate() {
        return indeterminateProp;
    }

    /**
     * @return Key class name.
     */
    public String keyClassName() {
        return keyClsNameProp.get();
    }

    /**
     * @param name New key class name.
     */
    public void keyClassName(String name) {
        keyClsNameProp.set(name);
    }

    /**
     * @return Value class name.
     */
    public String valueClassName() {
        return valClsNameProp.get();
    }

    /**
     * @param name New value class name.
     */
    public void valueClassName(String name) {
        valClsNameProp.set(name);
    }

    /**
     * @return {@code true} if at least one field checked as "used".
     */
    public boolean hasFields() {
        for (PojoField field : fields)
            if (field.use())
                return true;

        return false;
    }

    /**
     * @return {@code true} if at least one field checked as "used" and checked as "key".
     */
    public boolean hasKeyFields() {
        for (PojoField field : fields)
            if (field.use() && field.key())
                return true;

        return false;
    }

    /**
     * @param includeKeys {@code true} if key fields should be included into value class.
     * @return {@code true} if at least one field checked as "used" and not checked as "key".
     */
    public boolean hasValueFields(boolean includeKeys) {
        if (includeKeys)
            return hasKeyFields();

        for (PojoField field : fields)
            if (field.use() && !field.key())
                return true;

        return false;
    }

    /**
     * @return Collection of key fields.
     */
    public Collection keyFields() {
        Collection keys = new ArrayList<>();

        for (PojoField field : fields)
            if (field.use() && field.key() )
                keys.add(field);

        return keys;
    }

    /**
     * @param includeKeys {@code true} if key fields should be included into value class.
     * @return Collection of value fields.
     */
    public Collection valueFields(boolean includeKeys) {
        Collection vals = new ArrayList<>();

        for (PojoField field : fields)
            if (field.use() && (includeKeys || !field.key()))
                vals.add(field);

        return vals;
    }

    /**
     * @return Ascending fields.
     */
    public Collection ascendingFields() {
        Collection res = new ArrayList<>();

        Set asc = tbl.ascendingColumns();

        for (PojoField field : fields)
            if (field.use() && asc.contains(field.dbName()))
                res.add(field);

        return res;
    }

    /**
     * @return Descending fields.
     */
    public Collection descendingFields() {
        Collection res = new ArrayList<>();

        Set desc = tbl.descendingColumns();

        for (PojoField field : fields)
            if (field.use() && desc.contains(field.dbName()))
                res.add(field);

        return res;
    }

    /**
     * Gets indexes groups.
     */
    public Map>> groups() {
        Map> idxs = tbl.indexes();

        Map>> groups = new LinkedHashMap<>(idxs.size());

        for (Map.Entry> idx : idxs.entrySet()) {
            String idxName = idx.getKey();

            Map idxCols = idx.getValue();

            Map> grp = new LinkedHashMap<>();

            groups.put(idxName, grp);

            for (Map.Entry idxCol : idxCols.entrySet()) {
                PojoField fld = fieldsMap.get(idxCol.getKey());

                grp.put(fld.javaName(), new IgniteBiTuple<>(fld.javaTypeName(), idxCol.getValue()));
            }
        }

        return groups;
    }

    /**
     * @return Key class name property.
     */
    public StringProperty keyClassNameProperty() {
        return keyClsNameProp;
    }

    /**
     * @return Value class name property.
     */
    public StringProperty valueClassNameProperty() {
        return valClsNameProp;
    }

    /**
     * @return Schema name.
     */
    public String schema() {
        return tbl.schema();
    }

    /**
     * @return Table name.
     */
    public String table() {
        return tbl.table();
    }

    /**
     * Sets children items.
     *
     * @param children Items to set.
     */
    public void children(Collection children) {
        this.children = children;
    }

    /**
     * @return {@code true} if descriptor was changed by user via GUI.
     */
    public boolean changed() {
        if (!keyClsNameProp.get().equals(keyClsNamePrev) || !valClsNameProp.get().equals(valClsNamePrev))
            return true;

        for (PojoField field : fields)
            if (field.changed())
                return true;

        return false;
    }

    /**
     * Revert changes to key class name made by user.
     */
    public void revertKeyClassName() {
        keyClsNameProp.set(keyClsNamePrev);
    }

    /**
     * Revert changes to value class name made by user.
     */
    public void revertValueClassName() {
        valClsNameProp.set(valClsNamePrev);
    }

    /**
     * Revert changes to java names made by user.
     */
    public void revertJavaNames() {
        for (PojoField field : fields)
            field.resetJavaName();
    }

    /**
     * @return Java class fields.
     */
    public ObservableList fields() {
        return fields;
    }

    /**
     * @param name Source name.
     * @return String converted to java class name notation.
     */
    private static String toJavaClassName(String name) {
        int len = name.length();

        StringBuilder buf = new StringBuilder(len);

        boolean capitalizeNext = true;

        for (int i = 0; i < len; i++) {
            char ch = name.charAt(i);

            if (Character.isWhitespace(ch) || '_' == ch)
                capitalizeNext = true;
            else if (capitalizeNext) {
                buf.append(Character.toUpperCase(ch));

                capitalizeNext = false;
            }
            else
                buf.append(Character.toLowerCase(ch));
        }

        return buf.toString();
    }

    /**
     * @param name Source name.
     * @return String converted to java field name notation.
     */
    private static String toJavaFieldName(String name) {
        String javaName = toJavaClassName(name);

        return Character.toLowerCase(javaName.charAt(0)) + javaName.substring(1);
    }

    /**
     * Convert JDBC data type to java type.
     *
     * @param type JDBC SQL data type.
     * @param nullable {@code true} if {@code NULL} is allowed for this field in database.
     * @return Java data type.
     */
    private static Class toJavaType(int type, boolean nullable) {
        switch (type) {
            case BIT:
            case BOOLEAN:
                return nullable ? Boolean.class : boolean.class;

            case TINYINT:
                return nullable ? Byte.class : byte.class;

            case SMALLINT:
                return nullable ? Short.class : short.class;

            case INTEGER:
                return nullable ? Integer.class : int.class;

            case BIGINT:
                return nullable ? Long.class : long.class;

            case REAL:
                return nullable ? Float.class : float.class;

            case FLOAT:
            case DOUBLE:
                return nullable ? Double.class : double.class;

            case NUMERIC:
            case DECIMAL:
                return BigDecimal.class;

            case CHAR:
            case VARCHAR:
            case LONGVARCHAR:
            case NCHAR:
            case NVARCHAR:
            case LONGNVARCHAR:
                return String.class;

            case DATE:
                return java.sql.Date.class;

            case TIME:
                return java.sql.Time.class;

            case TIMESTAMP:
                return java.sql.Timestamp.class;

            // BINARY, VARBINARY, LONGVARBINARY, ARRAY, BLOB, CLOB, NCLOB, NULL, DATALINK
            // OTHER, JAVA_OBJECT, DISTINCT, STRUCT, REF, ROWID, SQLXML
            default:
                return Object.class;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy