org.dozer.eclipse.plugin.sourcepage.contentassist.DozerContentAssistProcessor.java Source code

Java tutorial

Introduction

Here is the source code for org.dozer.eclipse.plugin.sourcepage.contentassist.DozerContentAssistProcessor.java

Source

/**
 * Copyright 2005-2013 Dozer Project
 *
 * Licensed 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.dozer.eclipse.plugin.sourcepage.contentassist;

import org.dozer.eclipse.plugin.sourcepage.util.DozerPluginUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.xml.core.internal.document.AttrImpl;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansMapEntry;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansTypedString;
import org.springframework.ide.eclipse.beans.core.model.IBean;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.BeansJavaCompletionProposal;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.DefaultContentAssistContext;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.DefaultContentAssistProposalRecorder;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.IContentAssistCalculator;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.IContentAssistContext;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.IContentAssistProposalRecorder;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.MethodContentAssistCalculator;
import org.springframework.ide.eclipse.beans.ui.editor.util.BeansEditorUtils;
import org.springframework.ide.eclipse.beans.ui.editor.util.BeansJavaCompletionUtils;
import org.springframework.ide.eclipse.beans.ui.model.BeansModelImages;
import org.springframework.ide.eclipse.core.java.FlagsMethodFilter;
import org.springframework.ide.eclipse.core.java.IMethodFilter;
import org.springframework.ide.eclipse.core.java.JdtUtils;
import org.springframework.ide.eclipse.core.model.IModelElement;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import java.util.ArrayList;
import java.util.List;

public class DozerContentAssistProcessor extends XMLContentAssistProcessor {

    @Override
    @SuppressWarnings("restriction")
    protected ContentAssistRequest computeAttributeValueProposals(int documentPosition, String matchString,
            ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {
        if ("field".equals(node.getNodeName()) || "a".equals(node.getNodeName())
                || "b".equals(node.getNodeName())) {
            NamedNodeMap attrs = nodeAtOffset.getAttributes();
            for (int i = 0; i < attrs.getLength(); i++) {
                AttrImpl existingAttr = (AttrImpl) attrs.item(i);
                ITextRegion valueRegion = existingAttr.getValueRegion();
                String attrName = existingAttr.getName();
                if (completionRegion.getStart() >= valueRegion.getStart()
                        && completionRegion.getEnd() <= valueRegion.getEnd()) {

                    //the first " in matchstring must be deleted for search
                    if ("custom-converter".equals(attrName)) {
                        return computeDozerClassContentProposals(documentPosition, matchString.substring(1),
                                completionRegion, existingAttr, node);
                    } else if ("custom-converter-id".equals(attrName)) {
                        return computeDozerBeanContentProposals(documentPosition, matchString.substring(1),
                                completionRegion, existingAttr, node);
                    } else if ("get-method".equals(attrName) || "set-method".equals(attrName)
                            || "map-get-method".equals(attrName) || "map-set-method".equals(attrName)) {
                        return computeDozerMethodContentProposals(documentPosition, matchString.substring(1),
                                completionRegion, existingAttr, node, attrName.substring(0, 3).equals("set"));
                    }
                }
            }
        }

        return super.computeAttributeValueProposals(documentPosition, matchString, completionRegion, nodeAtOffset,
                node);
    }

    @Override
    @SuppressWarnings("restriction")
    protected ContentAssistRequest computeEndTagOpenProposals(int documentPosition, String matchString,
            ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {
        Node firstChild = nodeAtOffset.getFirstChild();

        if ("class-a".equals(node.getNodeName()) || "class-b".equals(node.getNodeName())
                || "a-hint".equals(node.getNodeName()) || "b-hint".equals(node.getNodeName())
                || "a-deep-index-hint".equals(node.getNodeName())
                || "b-deep-index-hint".equals(node.getNodeName())) {
            if (firstChild == null)
                firstChild = nodeAtOffset.appendChild(node.getOwnerDocument().createTextNode(""));
            if (firstChild.getNodeType() == Node.TEXT_NODE) {
                return computeDozerClassContentProposals(documentPosition, firstChild.getNodeValue(),
                        completionRegion, (IDOMNode) firstChild, node);
            }
        } else if ("a".equals(node.getNodeName()) || "b".equals(node.getNodeName())) {
            if (firstChild == null)
                firstChild = nodeAtOffset.appendChild(node.getOwnerDocument().createTextNode(""));
            if (firstChild.getNodeType() == Node.TEXT_NODE && ("field".equals(node.getParentNode().getNodeName())
                    || "field-exclude".equals(node.getParentNode().getNodeName()))) {
                return computeDozerPropertyContentProposals(documentPosition, firstChild.getNodeValue(),
                        completionRegion, (IDOMNode) firstChild, node);
            }
        }

        return super.computeEndTagOpenProposals(documentPosition, matchString, completionRegion, nodeAtOffset,
                node);
    }

    protected void convertProposals(List proposals) {
        //somehow the springide class BeansJavaCompletionUtils adds " to the replacement. Maybe this
        //is because of spring never uses TEXT_NODE's for class-declarations but only attributes, which needs "
        //Thus, we must use our own Proposal class. SpringIDE's BeansJavaCompletionUtils is very inflexible
        //here and cannot be subclassed. So we must replace every Proposal.      
        List<ICompletionProposal> newList = new ArrayList<ICompletionProposal>();
        for (Object object : proposals) {
            BeansJavaCompletionProposal bjcp = (BeansJavaCompletionProposal) object;
            DozerJavaCompletionProposal djcp = new DozerJavaCompletionProposal(bjcp.getReplacementString(),
                    bjcp.getReplacementOffset(), bjcp.getReplacementLength(), bjcp.getCursorPosition(),
                    bjcp.getImage(), bjcp.getDisplayString(), bjcp.getContextInformation(), bjcp.getRelevance(),
                    true, bjcp.getProposedObject());
            newList.add(djcp);
        }
        proposals.clear();
        proposals.addAll(newList);
    }

    @SuppressWarnings("restriction")
    protected ContentAssistRequest computeDozerClassContentProposals(int documentPosition, String matchString,
            ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {
        int offset = nodeAtOffset.getStartOffset();
        int len = nodeAtOffset.getLength();
        if (nodeAtOffset.getNodeType() == Node.ATTRIBUTE_NODE) {
            offset += nodeAtOffset.getNodeName().length() + 2;
            len -= nodeAtOffset.getNodeName().length() + 3;
        }

        ContentAssistRequest contentAssistRequest = new ContentAssistRequest(nodeAtOffset, node,
                getStructuredDocumentRegion(documentPosition), completionRegion, offset, len, matchString);
        IContentAssistProposalRecorder recorder = new DefaultContentAssistProposalRecorder(contentAssistRequest);
        IContentAssistContext context = new DefaultContentAssistContext(contentAssistRequest, "xyz", //@TODO
                matchString);

        BeansJavaCompletionUtils.addClassValueProposals(context, recorder, BeansJavaCompletionUtils.FLAG_PACKAGE
                | BeansJavaCompletionUtils.FLAG_CLASS | BeansJavaCompletionUtils.FLAG_INTERFACE);
        convertProposals(contentAssistRequest.getProposals());

        return contentAssistRequest;
    }

    @SuppressWarnings("restriction")
    protected ContentAssistRequest computeDozerPropertyContentProposals(int documentPosition, String matchString,
            ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {
        int offset = nodeAtOffset.getStartOffset();
        int len = nodeAtOffset.getLength();

        ContentAssistRequest contentAssistRequest = new ContentAssistRequest(nodeAtOffset, node,
                getStructuredDocumentRegion(documentPosition), completionRegion, offset, len, matchString);

        IFile file = BeansEditorUtils.getFile(contentAssistRequest);
        IProject project = file.getProject();
        String className = DozerPluginUtils.getMappingClassName(nodeAtOffset.getParentNode());
        IType type = JdtUtils.getJavaType(project, className);

        //by default immer this hinzu
        DozerJavaCompletionProposal newProposal = new DozerJavaCompletionProposal("\" this", offset, len, 2,
                JavaPluginImages.get(JavaPluginImages.IMG_OBJS_CLASS), "this", (IContextInformation) null, 0, true,
                null);
        contentAssistRequest.addProposal(newProposal);

        DozerPluginUtils.addPropertyNameAttributeValueProposals(contentAssistRequest, matchString, "", type);
        convertProposals(contentAssistRequest.getProposals());

        return contentAssistRequest;
    }

    @SuppressWarnings("restriction")
    protected ContentAssistRequest computeDozerMethodContentProposals(int documentPosition, String matchString,
            ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node, boolean onlySetter) {
        int offset = nodeAtOffset.getStartOffset() + nodeAtOffset.getNodeName().length() + 1;
        int len = nodeAtOffset.getLength() - nodeAtOffset.getNodeName().length() - 2;

        ContentAssistRequest contentAssistRequest = new ContentAssistRequest(nodeAtOffset, node,
                getStructuredDocumentRegion(documentPosition), completionRegion, offset, len, matchString);
        String targetClassName = DozerPluginUtils.getMappingClassName(node);
        addGetterSetterMethodProposals(contentAssistRequest, matchString, targetClassName, onlySetter);

        return contentAssistRequest;
    }

    @SuppressWarnings("restriction")
    protected ContentAssistRequest computeDozerBeanContentProposals(int documentPosition, String matchString,
            ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {
        int offset = nodeAtOffset.getStartOffset() + nodeAtOffset.getNodeName().length() + 2;
        int len = nodeAtOffset.getLength() - nodeAtOffset.getNodeName().length() - 3;

        ContentAssistRequest contentAssistRequest = new ContentAssistRequest(nodeAtOffset, node,
                getStructuredDocumentRegion(documentPosition), completionRegion, offset, len, matchString);
        IFile file = BeansEditorUtils.getFile(this.fTextViewer.getDocument());
        IBean bean = DozerPluginUtils.getDozerBeanForMappingFile(file);
        IModelElement[] ccwiPropertyMapEntries = DozerPluginUtils.getPossibleCCIMappingForMappingFile(bean);

        if (ccwiPropertyMapEntries != null) {
            for (IModelElement beansMapEntry : ccwiPropertyMapEntries) {
                BeansMapEntry entry = (BeansMapEntry) beansMapEntry;
                BeansTypedString key = (BeansTypedString) entry.getKey();

                if (key.getString() != null && !key.getString().equals("")) {
                    DozerJavaCompletionProposal newProposal = new DozerJavaCompletionProposal(
                            "\"" + key.getString(), offset, len, 0, BeansModelImages.getImage(entry),
                            key.getString(), (IContextInformation) null, 0, true, bean);
                    contentAssistRequest.addProposal(newProposal);
                }
            }
        }

        return contentAssistRequest;
    }

    private void addGetterSetterMethodProposals(ContentAssistRequest contentAssistRequest, String prefix,
            final String className, boolean onlySetter) {
        if (BeansEditorUtils.getFile(contentAssistRequest) instanceof IFile) {
            final IFile file = BeansEditorUtils.getFile(contentAssistRequest);

            IMethodFilter filter = null;
            if (onlySetter) {
                filter = new FlagsMethodFilter(FlagsMethodFilter.NOT_INTERFACE | FlagsMethodFilter.NOT_CONSTRUCTOR
                        | FlagsMethodFilter.PUBLIC, 1);

            } else {
                filter = new FlagsMethodFilter(FlagsMethodFilter.NOT_VOID | FlagsMethodFilter.NOT_INTERFACE
                        | FlagsMethodFilter.NOT_CONSTRUCTOR | FlagsMethodFilter.PUBLIC);
            }

            IContentAssistCalculator calculator = new MethodContentAssistCalculator(filter) {

                @Override
                protected IType calculateType(IContentAssistContext context) {
                    return JdtUtils.getJavaType(file.getProject(), className);
                }
            };

            IContentAssistProposalRecorder recorder = new DefaultContentAssistProposalRecorder(
                    contentAssistRequest);
            IContentAssistContext context = new DefaultContentAssistContext(contentAssistRequest, "xyz", //FIXME
                    prefix);

            calculator.computeProposals(context, recorder); //request, prefix, null, null, null);
        }
    }

    @Override
    @SuppressWarnings("restriction")
    protected ContentAssistRequest computeContentProposals(int documentPosition, String matchString,
            ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {
        if ("class-a".equals(node.getNodeName()) || "class-b".equals(node.getNodeName())) {
            if (nodeAtOffset.getNodeType() == Node.TEXT_NODE) {
                return computeDozerClassContentProposals(documentPosition, nodeAtOffset.getNodeValue(),
                        completionRegion, nodeAtOffset, node);
            }
        } else if ("a".equals(node.getNodeName()) || "b".equals(node.getNodeName())) {
            if (nodeAtOffset.getNodeType() == Node.TEXT_NODE
                    && "field".equals(node.getParentNode().getNodeName())) {
                return computeDozerPropertyContentProposals(documentPosition, nodeAtOffset.getNodeValue(),
                        completionRegion, nodeAtOffset, node);
            }
        }

        return super.computeContentProposals(documentPosition, matchString, completionRegion, nodeAtOffset, node);
    }

    @Override
    public char[] getCompletionProposalAutoActivationCharacters() {
        return DozerPluginUtils.DOZER_CONTENT_ASSIST_CHARS;
    }

}