Package com.dci.intellij.dbn.language.common.element

Source Code of com.dci.intellij.dbn.language.common.element.ElementTypeBundle

package com.dci.intellij.dbn.language.common.element;

import com.dci.intellij.dbn.language.common.DBLanguageDialect;
import com.dci.intellij.dbn.language.common.TokenTypeBundle;
import com.dci.intellij.dbn.language.common.element.impl.BasicElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.BlockElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.ExecVariableElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.IdentifierElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.IterationElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.NamedElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.NestedRangeElementType;
import com.dci.intellij.dbn.language.common.element.impl.OneOfElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.QualifiedIdentifierElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.SequenceElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.TokenElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.impl.WrapperElementTypeImpl;
import com.dci.intellij.dbn.language.common.element.util.ElementTypeAttribute;
import com.dci.intellij.dbn.language.common.element.util.ElementTypeDefinition;
import com.dci.intellij.dbn.language.common.element.util.ElementTypeDefinitionException;
import com.dci.intellij.dbn.object.common.DBObjectType;
import com.intellij.openapi.diagnostic.Logger;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.io.StringWriter;
import java.util.Map;
import java.util.Set;

public class ElementTypeBundle {
    private final Logger log = Logger.getInstance(getClass().getName());
    private TokenTypeBundle tokenTypeBundle;
    private NestedRangeElementType nestedRangeElementType;
    private BasicElementType unknownElementType;
    private NamedElementType rootElementType;

    private Set<ElementType> complexElementTypes = new THashSet<ElementType>();
    private Set<LeafElementType> leafElementTypes = new THashSet<LeafElementType>();
    private Set<WrapperElementType> wrapperElementTypes = new THashSet<WrapperElementType>();
    private Set<OneOfElementType> oneOfElementTypes = new THashSet<OneOfElementType>();
    private final Map<String, NamedElementType> namedElementTypes = new THashMap<String, NamedElementType>();
    private final Set<ElementType> virtualObjectElementTypes = new THashSet<ElementType>();
    private final DBLanguageDialect languageDialect;
    private boolean rewriteIndexes;

    private int idCursor;

    public ElementTypeBundle(DBLanguageDialect languageDialect, TokenTypeBundle tokenTypeBundle, Document elementTypesDef) {
        this.languageDialect = languageDialect;
        this.tokenTypeBundle = tokenTypeBundle;
        try {
            Element root = elementTypesDef.getRootElement();
            for (Object o : root.getChildren()) {
                Element child = (Element) o;
                createNamedElementType(child);
            }

            NamedElementType unknown = namedElementTypes.get("custom_undefined");
            for(NamedElementType namedElementType : namedElementTypes.values()){
                if (!namedElementType.isDefinitionLoaded()) {
                    namedElementType.update(unknown);
                    //log.info("ERROR: element '" + namedElementType.getId() + "' not defined.");
                    System.out.println("DEBUG - [" + getLanguageDialect().getID() + "] undefined element type: " + namedElementType.getId());
/*
                    if (DatabaseNavigator.getInstance().isDebugModeEnabled()) {
                        System.out.println("WARNING - [" + getLanguageDialect().getID() + "] undefined element type: " + namedElementType.getId());
                    }
*/
                }
            }

            for (LeafElementType leafElementType: leafElementTypes) {
                leafElementType.registerLeaf();
            }

            for (WrapperElementType wrapperElementType : wrapperElementTypes) {
                wrapperElementType.getBeginTokenElement().registerLeaf();
                wrapperElementType.getEndTokenElement().registerLeaf();
            }

            for (ElementType virtualObjectElementType : virtualObjectElementTypes) {
                virtualObjectElementType.registerVirtualObject(virtualObjectElementType.getVirtualObjectType());
            }

            if (rewriteIndexes) {
                StringWriter stringWriter = new StringWriter();
                new XMLOutputter().output(elementTypesDef, stringWriter);

                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                String data = stringWriter.getBuffer().toString();
                System.out.println(data);
                clipboard.setContents(new StringSelection(data), null);

            } else {
            }

            //warnAmbiguousBranches();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Set<ElementType> getComplexElementTypes() {
        return complexElementTypes;
    }

    public TokenTypeBundle getTokenTypeBundle() {
        return tokenTypeBundle;
    }

    private void warnAmbiguousBranches() {
        for (OneOfElementType oneOfElementType : oneOfElementTypes) {
            oneOfElementType.warnAmbiguousBranches();
        }
    }


    public void markIndexesDirty() {
        this.rewriteIndexes = true;
    }

    public boolean isRewriteIndexes() {
        return rewriteIndexes;
    }

    private void createNamedElementType(Element def) throws ElementTypeDefinitionException {
        String id = determineMandatoryAttribute(def, "id", "Invalid definition of named element type.");
        log.debug("Updating complex element definition '" + id + "'");
        NamedElementType elementType = getNamedElementType(id, null);
        elementType.loadDefinition(def);
        if (elementType.is(ElementTypeAttribute.ROOT)) {
            if (rootElementType == null) {
                rootElementType = elementType;
            } else {
                throw new ElementTypeDefinitionException("Duplicate root definition");
            }
        }
    }


    public static String determineMandatoryAttribute(Element def, String attribute, String message) throws ElementTypeDefinitionException {
        String value = def.getAttributeValue(attribute);
        if (value == null) {
            throw new ElementTypeDefinitionException(message + "Missing '" + attribute + "' attribute.");
        }
        return value;
    }

    public ElementType resolveElementDefinition(Element def, String type, ElementType parent) throws ElementTypeDefinitionException {
        ElementType result;
        if (ElementTypeDefinition.SEQUENCE.is(type)){
            result = new SequenceElementTypeImpl(this, parent, createId(), def);
            log.debug("Created sequence element definition");
        } else if (ElementTypeDefinition.BLOCK.is(type)) {
            result = new BlockElementTypeImpl(this, parent, createId(), def);
            log.debug("Created iteration element definition");
        } else if (ElementTypeDefinition.ITERATION.is(type)) {
            result = new IterationElementTypeImpl(this, parent, createId(), def);
            log.debug("Created iteration element definition");
        } else if (ElementTypeDefinition.ONE_OF.is(type)) {
            result =  new OneOfElementTypeImpl(this, parent, createId(), def);
            oneOfElementTypes.add((OneOfElementType) result);
            log.debug("Created one-of element definition");
        } else if (ElementTypeDefinition.QUALIFIED_IDENTIFIER.is(type)) {
            result =  new QualifiedIdentifierElementTypeImpl(this, parent, createId(), def);
            log.debug("Created qualified identifier element definition");
        } else if (ElementTypeDefinition.WRAPPER.is(type)) {
            result = new WrapperElementTypeImpl(this, parent, createId(), def);
            wrapperElementTypes.add((WrapperElementType) result);
            log.debug("Created wrapper element definition");
        } else if (ElementTypeDefinition.ELEMENT.is(type)) {
            String id = determineMandatoryAttribute(def, "ref-id", "Invalid reference to element.");
            result = getNamedElementType(id, parent);
        } else if (ElementTypeDefinition.TOKEN.is(type)) {
            result = new TokenElementTypeImpl(this, parent, createId(), def);
        } else if (
                ElementTypeDefinition.OBJECT_DEF.is(type) ||
                ElementTypeDefinition.OBJECT_REF.is(type) ||
                ElementTypeDefinition.ALIAS_DEF.is(type) ||
                ElementTypeDefinition.ALIAS_REF.is(type) ||
                ElementTypeDefinition.VARIABLE_DEF.is(type) ||
                ElementTypeDefinition.VARIABLE_REF.is(type)) {
            result = new IdentifierElementTypeImpl(this, parent, createId(), def);
        } else if (ElementTypeDefinition.EXEC_VARIABLE.is(type)) {
            result = new ExecVariableElementTypeImpl(this, parent, createId(), def);           
        else {
            throw new ElementTypeDefinitionException("Could not resolve element definition '" + type + "'");
        }
        if (result instanceof LeafElementType)
            leafElementTypes.add((LeafElementType) result); else
            complexElementTypes.add(result);

        if (result.isVirtualObject()) {
            virtualObjectElementTypes.add(result);
        }

        return result;
    }


    public static DBObjectType resolveObjectType(String name) throws ElementTypeDefinitionException {
        DBObjectType objectType = DBObjectType.getObjectType(name);
        if (objectType == null)
            throw new ElementTypeDefinitionException("Invalid object type '" + name + "'");
        return objectType;
    }


    /*protected synchronized TokenElementType getTokenElementType(String id) {
        TokenElementType elementType = tokenElementTypes.get(id);
        if (elementType == null) {
            elementType = new TokenElementType(this, id);
            tokenElementTypes.put(id, elementType);
            log.info("Created token element objectType '" + id + "'");
        }
        return elementType;
    }*/

    protected synchronized NamedElementType getNamedElementType(String id, ElementType parent) {
        NamedElementType elementType = namedElementTypes.get(id);
        if (elementType == null) {
            elementType = new NamedElementTypeImpl(this, id);
            namedElementTypes.put(id, elementType);
            log.debug("Created named element type '" + id + "'");
        }
        if (parent != null) elementType.addParent(parent);
        return elementType;
    }

    public DBLanguageDialect getLanguageDialect() {
        return languageDialect;
    }

    public NamedElementType getRootElementType() {
        return rootElementType;
    }

    public NamedElementType getNamedElementType(String id) {
        return namedElementTypes.get(id);
    }

    public BasicElementType getUnknownElementType() {
        if (unknownElementType == null) {
            unknownElementType = new BasicElementTypeImpl(this);
        }
        return unknownElementType;
    }

    public NestedRangeElementType getNestedRangeElementType() {
        if (nestedRangeElementType == null) {
            nestedRangeElementType = new NestedRangeElementType(this);
        }
        return nestedRangeElementType;
    }

    public String createId() {
        String id = Integer.toString(idCursor++);
        StringBuilder buffer = new StringBuilder();
        while (buffer.length() + id.length() < 9) {
            buffer.append('0');
        }
        buffer.append(id);
        return buffer.toString();
    }
}
TOP

Related Classes of com.dci.intellij.dbn.language.common.element.ElementTypeBundle

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.