Package com.dci.intellij.dbn.object.lookup

Source Code of com.dci.intellij.dbn.object.lookup.DBObjectRef$Node

package com.dci.intellij.dbn.object.lookup;

import com.dci.intellij.dbn.common.Reference;
import com.dci.intellij.dbn.common.util.StringUtil;
import com.dci.intellij.dbn.connection.ConnectionCache;
import com.dci.intellij.dbn.connection.ConnectionHandler;
import com.dci.intellij.dbn.connection.ConnectionManager;
import com.dci.intellij.dbn.object.common.DBObject;
import com.dci.intellij.dbn.object.common.DBObjectType;
import com.intellij.openapi.project.Project;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

public class DBObjectRef<T extends DBObject> implements Comparable, Reference<T> {
    protected String connectionId;
    protected Node[] nodes;
    private WeakReference<T> reference;

    public DBObjectRef(T object) {
        reference = new WeakReference<T>(object);
        ConnectionHandler connectionHandler = object.getConnectionHandler();
        connectionId = connectionHandler == null ? null : connectionHandler.getId();

        List<DBObject> chain = new ArrayList<DBObject>();
        chain.add(object);

        DBObject parentObject = object.getParentObject();
        while (parentObject != null) {
            chain.add(0, parentObject);
            parentObject = parentObject.getParentObject();
        }
        int length = chain.size();
        nodes = new Node[length];
        for (int i = 0; i<length; i++) {
            DBObject chainObject = chain.get(i);
            nodes[i] = new Node(chainObject.getObjectType(), chainObject.getName());
        }
    }

    public DBObjectRef(ConnectionHandler connectionHandler) {
        this.connectionId = connectionHandler == null ? null : connectionHandler.getId();
    }

    public DBObjectRef(String connectionId) {
        this.connectionId = connectionId;
    }

    public DBObjectRef() {

    }

    public static DBObjectRef from(Element element) {
        if (StringUtil.isNotEmpty(element.getAttributeValue("object-ref"))) {
            DBObjectRef objectRef = new DBObjectRef();
            objectRef.readState(element);
            return objectRef;
        }
        return null;
    }

    public void readState(Element element) {
        if (element != null) {
            connectionId = element.getAttributeValue("connection-id");
            String databaseObject = element.getAttributeValue("object-ref");
            int typeEndIndex = databaseObject.lastIndexOf("]");
            StringTokenizer objectTypes = new StringTokenizer(databaseObject.substring(1, typeEndIndex), ".");
            StringTokenizer objectNames = new StringTokenizer(databaseObject.substring(typeEndIndex + 1), ".");
            while (objectTypes.hasMoreTokens()) {
                String objectTypeName = objectTypes.nextToken();
                String objectName = objectNames.nextToken();
                append(DBObjectType.getObjectType(objectTypeName), objectName);
            }
        }
    }

    public void writeState(Element element) {
        element.setAttribute("connection-id", connectionId);
        StringBuilder objectTypes = new StringBuilder();
        StringBuilder objectNames = new StringBuilder();

        for (Node node: nodes) {
            if (objectTypes.length() > 0) {
                objectTypes.append(".");
                objectNames.append(".");
            }
            objectTypes.append(node.getType().getName());
            objectNames.append(node.getName());
        }

        element.setAttribute("object-ref", "[" + objectTypes.toString() + "]" + objectNames);
    }

    public DBObjectRef append(DBObjectType objectType, String name) {
        Node node = new Node(objectType, name);
        if (nodes == null) {
            nodes = new Node[1];
            nodes[0] = node;
        } else {
            Node[] newNodes = new Node[nodes.length + 1];
            System.arraycopy(nodes, 0, newNodes, 0, nodes.length);
            newNodes[nodes.length] = node;
            nodes = newNodes;
        }
        return this;
    }

    public String getPath() {
        if (nodes.length == 1) {
            return nodes[0].getName();
        } else {
            StringBuilder buffer = new StringBuilder();
            for (Node node : nodes) {
                if (buffer.length() > 0) buffer.append(".");
                buffer.append(node.getName());
            }
            return buffer.toString();
        }
    }


    public String getConnectionId() {
        return connectionId;
    }

    public boolean is(@NotNull T object) {
        if (object.getConnectionHandler().getId().equals(connectionId)) {
            int index = nodes.length -1;
            DBObject checkObject = object;
            while (checkObject != null) {
                Node checkNode = nodes[index];
                if (!checkNode.matches(checkObject)) return false;
                checkObject = checkObject.getParentObject();
                index--;
            }
            return true;
        }
        return false;
    }

    @Nullable
    public static <T extends DBObject> DBObjectRef<T> from(T object) {
        return object == null ? null : object.getRef();
    }

    @Nullable
    public static <T extends DBObject> T get(DBObjectRef<T> objectRef) {
        return objectRef == null ? null : objectRef.get();
    }

    @Nullable
    public T get() {
        return load(null);
    }

    @Nullable
    public T get(Project project) {
        return load(project);
    }

    protected final T load(Project project) {
        T object = reference == null ? null : reference.get();
        if (reference == null || object == null || object.isDisposed()) {
            object = null;
            if (reference != null) {
                reference.clear();
                reference = null;
            }
            ConnectionHandler connectionHandler =
                    project == null ?
                            ConnectionCache.findConnectionHandler(connectionId) :
                            ConnectionManager.getInstance(project).getConnectionHandler(connectionId);
            if (connectionHandler != null && !connectionHandler.isDisposed() && connectionHandler.isActive()) {
                object = lookup(connectionHandler);
                if (object != null) {
                    reference = new WeakReference<T>(object);
                }
            }

        }
        return object;
    }

    @Nullable
    protected T lookup(@NotNull ConnectionHandler connectionHandler) {
        DBObject object = null;
        for (Node node : nodes) {
            DBObjectType objectType = node.getType();
            String objectName = node.getName();
            if (object == null) {
                object = connectionHandler.getObjectBundle().getObject(objectType, objectName);
            } else {
                object = object.getChildObject(objectType, objectName, true);
            }
            if (object == null) break;
        }
        return (T) object;
    }

    public ConnectionHandler lookupConnectionHandler() {
        return ConnectionCache.findConnectionHandler(connectionId);
    }

    @Override
    public int compareTo(@NotNull Object o) {
        if (o instanceof DBObjectRef) {
            DBObjectRef that = (DBObjectRef) o;
            int result = this.connectionId.compareTo(that.getConnectionId());
            if (result != 0) return result;

            if (this.nodes.length != that.nodes.length) {
                return this.nodes.length - that.nodes.length;
            }

            for (int i=0; i<this.nodes.length; i++) {
                Node thisNode = this.nodes[i];
                Node thatNode = that.nodes[i];
                result = thisNode.getType().compareTo(thatNode.getType());
                if (result != 0) return result;
                result = thisNode.getName().compareTo(thatNode.getName());
                if (result != 0) return result;
            }
        }
        return 0;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        DBObjectRef that = (DBObjectRef) o;

        if (!connectionId.equals(that.connectionId)) return false;
        if (!Arrays.equals(nodes, that.nodes)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = connectionId.hashCode();
        result = 31 * result + Arrays.hashCode(nodes);
        return result;
    }

    public String getName() {
        return nodes[nodes.length-1].getName();
    }

    public String getFileName() {
        return getName();
    }

    public DBObjectType getObjectType() {
        return nodes[nodes.length-1].getType();
    }

    public boolean isOfType(DBObjectType objectType) {
        return getObjectType().matches(objectType);
    }

    public static class Node {
        private DBObjectType type;
        private String name;

        public Node(DBObjectType type, String name) {
            this.type = type;
            this.name = name;
        }

        public DBObjectType getType() {
            return type;
        }

        public String getName() {
            return name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Node node = (Node) o;

            if (!name.equals(node.name)) return false;
            if (type != node.type) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = type.hashCode();
            result = 31 * result + name.hashCode();
            return result;
        }

        @Override
        public String toString() {
            return "[" + type.getName() + "] " + getName();
        }

        public boolean matches(DBObject object) {
            return type == object.getObjectType() && name.equals(object.getName());
        }
    }

}
TOP

Related Classes of com.dci.intellij.dbn.object.lookup.DBObjectRef$Node

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.