private void proposeStatementText(ContentAssistRequest contentAssistRequest, Node statementNode) {
    int offset = contentAssistRequest.getReplacementBeginPosition();
    String text = contentAssistRequest.getText();
    int offsetInText = offset - contentAssistRequest.getStartOffset() - 1;
    ExpressionProposalParser parser = new ExpressionProposalParser(text, offsetInText);
    if (parser.isProposable()) {
      String matchString = parser.getMatchString();
      offset -= matchString.length();
      int length = parser.getReplacementLength();
      final IJavaProject project = getJavaProject(contentAssistRequest);
      String proposalTarget = parser.getProposalTarget();

      if (proposalTarget == null || proposalTarget.length() == 0)
        addProposals(
            contentAssistRequest,
            ProposalComputorHelper.proposeOptionName(offset, length, matchString));
      else if ("property".equals(proposalTarget))
        addProposals(
            contentAssistRequest,
            proposeParameter(project, offset, length, statementNode, true, matchString));
      else if ("jdbcType".equals(proposalTarget))
        addProposals(
            contentAssistRequest,
            ProposalComputorHelper.proposeJdbcType(offset, length, matchString));
      else if ("javaType".equals(proposalTarget))
        addProposals(
            contentAssistRequest,
            ProposalComputorHelper.proposeJavaType(project, offset, length, true, matchString));
      else if ("typeHandler".equals(proposalTarget))
        addProposals(
            contentAssistRequest,
            ProposalComputorHelper.proposeTypeHandler(project, offset, length, matchString));
    }
  }
  @Override
  protected void addTagInsertionProposals(
      ContentAssistRequest contentAssistRequest,
      int childPosition,
      CompletionProposalInvocationContext context) {
    int offset = contentAssistRequest.getReplacementBeginPosition();
    int length = contentAssistRequest.getReplacementLength();
    Node node = contentAssistRequest.getNode();
    // Current node can be 'parent' when the cursor is just before the end tag of the parent.
    Node parentNode = node.getNodeType() == Node.ELEMENT_NODE ? node : node.getParentNode();
    if (parentNode.getNodeType() != Node.ELEMENT_NODE) return;

    String tagName = parentNode.getNodeName();
    NamedNodeMap tagAttrs = parentNode.getAttributes();
    // Result mapping proposals.
    if ("resultMap".equals(tagName))
      generateResults(
          contentAssistRequest, offset, length, parentNode, tagAttrs.getNamedItem("type"));
    else if ("collection".equals(tagName))
      generateResults(
          contentAssistRequest, offset, length, parentNode, tagAttrs.getNamedItem("ofType"));
    else if ("association".equals(tagName))
      generateResults(
          contentAssistRequest, offset, length, parentNode, tagAttrs.getNamedItem("javaType"));

    Node statementNode = MybatipseXmlUtil.findEnclosingStatementNode(parentNode);
    if (statementNode == null) return;
    proposeStatementText(contentAssistRequest, statementNode);
  }
 private void addProposals(
     final ContentAssistRequest contentAssistRequest, List<ICompletionProposal> proposals) {
   Collections.sort(proposals, new CompletionProposalComparator());
   for (ICompletionProposal proposal : proposals) {
     contentAssistRequest.addProposal(proposal);
   }
 }
 private Node getCurrentNode(ContentAssistRequest contentAssistRequest) {
   Node currentNode = contentAssistRequest.getParent();
   if (currentNode instanceof Text) {
     currentNode = currentNode.getParentNode();
   }
   return currentNode;
 }
 private IJavaProject getJavaProject(ContentAssistRequest request) {
   if (request != null) {
     IStructuredDocumentRegion region = request.getDocumentRegion();
     if (region != null) {
       IDocument document = region.getParentDocument();
       return MybatipseXmlUtil.getJavaProject(document);
     }
   }
   return null;
 }
  public static IProject getProject(ContentAssistRequest request) {

    if (request != null) {
      IStructuredDocumentRegion region = request.getDocumentRegion();
      if (region != null) {
        IDocument document = region.getParentDocument();
        return getProject(document);
      }
    }
    return null;
  }
  private void generateResults(
      ContentAssistRequest contentAssistRequest,
      int offset,
      int length,
      Node parentNode,
      Node typeAttr) {
    if (typeAttr == null) return;

    String typeValue = typeAttr.getNodeValue();
    if (typeValue == null || typeValue.length() == 0) return;

    IJavaProject project = getJavaProject(contentAssistRequest);
    // Try resolving the alias.
    String qualifiedName = TypeAliasCache.getInstance().resolveAlias(project, typeValue, null);
    if (qualifiedName == null) {
      // Assumed to be FQN.
      qualifiedName = typeValue;
    }
    BeanPropertyInfo beanProps = BeanPropertyCache.getBeanPropertyInfo(project, qualifiedName);
    try {
      Set<String> existingProps = new HashSet<String>();
      NodeList existingPropNodes = XpathUtil.xpathNodes(parentNode, "*[@property]/@property");
      for (int i = 0; i < existingPropNodes.getLength(); i++) {
        existingProps.add(existingPropNodes.item(i).getNodeValue());
      }
      StringBuilder resultTags = new StringBuilder();
      for (Entry<String, String> prop : beanProps.getWritableFields().entrySet()) {
        String propName = prop.getKey();
        if (!existingProps.contains(propName)) {
          resultTags
              .append("<result property=\"")
              .append(propName)
              .append("\" column=\"")
              .append(propName)
              .append("\" />\n");
        }
      }
      contentAssistRequest.addProposal(
          new CompletionProposal(
              resultTags.toString(),
              offset,
              length,
              resultTags.length(),
              Activator.getIcon(),
              "<result /> for properties",
              null,
              null));
    } catch (XPathExpressionException e) {
      Activator.log(Status.ERROR, e.getMessage(), e);
    }
  }
 private void proposeMapperNamespace(
     ContentAssistRequest contentAssistRequest, IJavaProject project, int start, int length) {
   String namespace = MybatipseXmlUtil.getNamespaceFromActiveEditor(project);
   ICompletionProposal proposal =
       new CompletionProposal(
           namespace,
           start,
           length,
           namespace.length(),
           Activator.getIcon("/icons/mybatis-ns.png"),
           namespace,
           null,
           null);
   contentAssistRequest.addProposal(proposal);
 }
  protected void addAttributeNameProposals(ContentAssistRequest contentAssistRequest) {
    DataserviceTagElement currentDataserviceElement =
        getCurrentDataserviceElement(contentAssistRequest);
    if (currentDataserviceElement != null) {
      List<DataserviceAttributeElement> attributes = currentDataserviceElement.getAttributes();
      Node currentNode = getCurrentNode(contentAssistRequest);
      for (DataserviceAttributeElement element : attributes) {
        if (!isAttributePresent(currentNode, element.getName())) {
          contentAssistRequest.addProposal(getAttributeNameProposal(element));
        }
      }

    } else {
      super.addAttributeNameProposals(contentAssistRequest);
    }
  }
 @SuppressWarnings("restriction")
 protected void addTagInsertionProposals(
     ContentAssistRequest contentAssistRequest, int childPosition) {
   DataserviceTagElement currentDataserviceElement =
       getCurrentDataserviceElement(contentAssistRequest);
   if (currentDataserviceElement != null) {
     List<DataserviceTagElement> subElements = currentDataserviceElement.getSubElements();
     Node currentNode = getCurrentNode(contentAssistRequest);
     for (DataserviceTagElement element : subElements) {
       if (element.isUpperLimitUnbound()
           || getChildNodeCount(currentNode, element.getName()) < element.getMaxOccurances()) {
         contentAssistRequest.addProposal(getTagProposal(element));
       }
     }
   } else {
     super.addTagInsertionProposals(contentAssistRequest, childPosition);
   }
 }
  protected void addAttributeValueProposals(
      ContentAssistRequest contentAssistRequest, CompletionProposalInvocationContext context) {
    IDOMNode node = (IDOMNode) contentAssistRequest.getNode();
    String tagName = node.getNodeName();
    IStructuredDocumentRegion open = node.getFirstStructuredDocumentRegion();
    ITextRegionList openRegions = open.getRegions();
    int i = openRegions.indexOf(contentAssistRequest.getRegion());
    if (i < 0) return;
    ITextRegion nameRegion = null;
    while (i >= 0) {
      nameRegion = openRegions.get(i--);
      if (nameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) break;
    }

    // get the attribute in question (first attr name to the left of the cursor)
    String attributeName = null;
    if (nameRegion != null) attributeName = open.getText(nameRegion);

    ProposalType proposalType = resolveProposalType(tagName, attributeName);
    if (ProposalType.None.equals(proposalType)) {
      return;
    }

    String currentValue = null;
    if (contentAssistRequest.getRegion().getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)
      currentValue = contentAssistRequest.getText();
    else currentValue = "";

    String matchString = null;
    int matchStrLen = contentAssistRequest.getMatchString().length();
    int start = contentAssistRequest.getReplacementBeginPosition();
    int length = contentAssistRequest.getReplacementLength();
    if (currentValue.length() > StringUtils.strip(currentValue).length()
        && (currentValue.startsWith("\"") || currentValue.startsWith("'"))
        && matchStrLen > 0) {
      // Value is surrounded by (double) quotes.
      matchString = currentValue.substring(1, matchStrLen);
      start++;
      length = currentValue.length() - 2;
      currentValue = currentValue.substring(1, length + 1);
    } else {
      matchString = currentValue.substring(0, matchStrLen);
    }

    IJavaProject project = getJavaProject(contentAssistRequest);
    try {
      switch (proposalType) {
        case Package:
          proposePackage(contentAssistRequest, project, matchString, start, length);
          break;
        case TypeAlias:
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeJavaType(project, start, length, false, matchString));
          break;
        case ResultType:
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeJavaType(project, start, length, true, matchString));
          break;
        case ResultProperty:
          proposeProperty(contentAssistRequest, matchString, start, length, node);
          break;
        case TypeHandlerType:
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeTypeHandler(project, start, length, matchString));
          break;
        case CacheType:
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeCacheType(project, start, length, matchString));
          break;
        case SettingName:
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeSettingName(start, length, matchString));
          break;
        case ObjectFactory:
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeObjectFactory(project, start, length, matchString));
          break;
        case ObjectWrapperFactory:
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeObjectWrapperFactory(
                  project, start, length, matchString));
          break;
        case StatementId:
          proposeStatementId(contentAssistRequest, project, matchString, start, length, node);
          break;
        case MapperNamespace:
          proposeMapperNamespace(contentAssistRequest, project, start, length);
          break;
        case ResultMap:
          String ownId =
              "resultMap".equals(tagName) && "extends".equals(attributeName)
                  ? XpathUtil.xpathString(node, "@id")
                  : null;
          addProposals(
              contentAssistRequest,
              proposeResultMapReference(
                  project,
                  node.getOwnerDocument(),
                  start,
                  currentValue,
                  matchString.length(),
                  ownId));
          break;
        case Include:
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeReference(
                  project, node.getOwnerDocument(), matchString, start, length, "sql", null));
          break;
        case SelectId:
          // TODO: include mapper methods with @Select.
          addProposals(
              contentAssistRequest,
              ProposalComputorHelper.proposeReference(
                  project, node.getOwnerDocument(), matchString, start, length, "select", null));
          break;
        case KeyProperty:
          String nodeName = node.getNodeName();
          Node statementNode =
              "update".equals(nodeName) || "insert".equals(nodeName)
                  ? node
                  : MybatipseXmlUtil.findEnclosingStatementNode(node.getParentNode());
          addProposals(
              contentAssistRequest,
              proposeParameter(project, start, length, statementNode, false, matchString));
          break;
        case ParamProperty:
          addProposals(
              contentAssistRequest,
              proposeParameter(
                  project,
                  start,
                  length,
                  MybatipseXmlUtil.findEnclosingStatementNode(node),
                  true,
                  matchString));
          break;
        case ParamPropertyPartial:
          AttrTextParser parser = new AttrTextParser(currentValue, matchString.length());
          addProposals(
              contentAssistRequest,
              proposeParameter(
                  project,
                  start + parser.getMatchStringStart(),
                  parser.getReplacementLength(),
                  MybatipseXmlUtil.findEnclosingStatementNode(node.getParentNode()),
                  true,
                  parser.getMatchString()));
          break;
        default:
          break;
      }
    } catch (Exception e) {
      Activator.log(Status.ERROR, e.getMessage(), e);
    }
  }