Java tutorial
/** * 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; } }