/**
   * Generates initial content for a new R script file.
   *
   * @param su the R source unit to create the source for. The unit does not need to exist
   * @param lineDelimiter the line delimiter to be used
   * @return the new content or <code>null</code> if the template is undefined or empty
   * @throws CoreException thrown when the evaluation of the code template fails
   */
  public static EvaluatedTemplate getNewRFileContent(
      final RResourceUnit su, final String lineDelimiter) throws CoreException {
    final Template template =
        RUIPlugin.getDefault()
            .getRCodeGenerationTemplateStore()
            .findTemplate(RCodeTemplatesContextType.NEW_RSCRIPTFILE);
    if (template == null) {
      return null;
    }

    final RCodeTemplatesContext context =
        new RCodeTemplatesContext(
            RCodeTemplatesContextType.NEW_RSCRIPTFILE_CONTEXTTYPE, su, lineDelimiter);

    try {
      final TemplateBuffer buffer = context.evaluate(template);
      if (buffer == null) {
        return null;
      }
      return new TemplatesUtil.EvaluatedTemplate(buffer, lineDelimiter);
    } catch (final Exception e) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              RUI.PLUGIN_ID,
              NLS.bind(
                  TemplateMessages.TemplateEvaluation_error_description, template.getDescription()),
              e));
    }
  }
 public CodeClipDialog(
     Shell parentShell, Shell contextShell, TemplatePersistenceData templatePersistenceData) {
   super(parentShell);
   this.contextShell = contextShell;
   this.templatePersistenceData = templatePersistenceData;
   Template template = templatePersistenceData.getTemplate();
   abbrev = template.getName();
   description = template.getDescription();
   expansion = template.getPattern();
   contentType = template.getContextTypeId();
   setHelpAvailable(false);
 }
 /*
  * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension6#getStyledDisplayString()
  * @since 3.4
  */
 @Override
 public StyledString getStyledDisplayString() {
   if (fDisplayString == null) {
     String[] arguments = new String[] {fTemplate.getName(), fTemplate.getDescription()};
     String decorated =
         Messages.format(TemplateContentAssistMessages.TemplateProposal_displayString, arguments);
     StyledString string = new StyledString(fTemplate.getName(), StyledString.COUNTER_STYLER);
     fDisplayString =
         StyledCellLabelProvider.styleDecoratedString(
             decorated, StyledString.QUALIFIER_STYLER, string);
   }
   return fDisplayString;
 }
 private Template indentTemplatePattern(final Template template, final boolean indentFrom0) {
   String pattern = template.getPattern();
   final String whiteSpacePrefix = indentFrom0 ? "" : getWhiteSpacePrefix();
   try {
     pattern = IndentAction.indentLines(0, 0, pattern, true, whiteSpacePrefix);
   } catch (final RpcException e) {
     ErlLogger.error(e);
   }
   return new Template(
       template.getName(),
       template.getDescription(),
       template.getContextTypeId(),
       pattern,
       template.isAutoInsertable());
 }
  /**
   * Saves the templates as XML.
   *
   * @param templates the templates to save
   * @param result the stream result to write to
   * @throws IOException if writing the templates fails
   */
  private void save(TemplatePersistenceData[] templates, StreamResult result) throws IOException {
    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document document = builder.newDocument();

      Node root = document.createElement(TEMPLATE_ROOT);
      document.appendChild(root);

      for (int i = 0; i < templates.length; i++) {
        TemplatePersistenceData data = templates[i];
        Template template = data.getTemplate();

        Node node = document.createElement(TEMPLATE_ELEMENT);
        root.appendChild(node);

        NamedNodeMap attributes = node.getAttributes();

        String id = data.getId();
        if (id != null) {
          Attr idAttr = document.createAttribute(ID_ATTRIBUTE);
          idAttr.setValue(id);
          attributes.setNamedItem(idAttr);
        }

        if (template != null) {
          Attr name = document.createAttribute(NAME_ATTRIBUTE);
          name.setValue(template.getName());
          attributes.setNamedItem(name);
        }

        if (template != null) {
          Attr proposalDesc = document.createAttribute(PROPOSAL_POPUP_DESCRIPTION);
          if (template instanceof SQLTemplate) {
            proposalDesc.setValue(((SQLTemplate) template).getProposalPopupDescription());
          }
          attributes.setNamedItem(proposalDesc);
        }

        if (template != null) {
          Attr description = document.createAttribute(DESCRIPTION_ATTRIBUTE);
          description.setValue(template.getDescription());
          attributes.setNamedItem(description);
        }

        if (template != null) {
          Attr context = document.createAttribute(CONTEXT_ATTRIBUTE);
          context.setValue(template.getContextTypeId());
          attributes.setNamedItem(context);
        }

        Attr enabled = document.createAttribute(ENABLED_ATTRIBUTE);
        enabled.setValue(data.isEnabled() ? Boolean.toString(true) : Boolean.toString(false));
        attributes.setNamedItem(enabled);

        Attr deleted = document.createAttribute(DELETED_ATTRIBUTE);
        deleted.setValue(data.isDeleted() ? Boolean.toString(true) : Boolean.toString(false));
        attributes.setNamedItem(deleted);

        if (template != null) {
          Attr autoInsertable = document.createAttribute(AUTO_INSERTABLE_ATTRIBUTE);
          autoInsertable.setValue(
              template.isAutoInsertable() ? Boolean.toString(true) : Boolean.toString(false));
          attributes.setNamedItem(autoInsertable);
        }

        if (template != null) {
          Text pattern = document.createTextNode(template.getPattern());
          node.appendChild(pattern);
        }
      }

      Transformer transformer = TransformerFactory.newInstance().newTransformer();
      transformer.setOutputProperty(OutputKeys.METHOD, "xml"); // $NON-NLS-1$
      transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // $NON-NLS-1$
      DOMSource source = new DOMSource(document);

      transformer.transform(source, result);

    } catch (ParserConfigurationException e) {
      Assert.isTrue(false);
    } catch (TransformerException e) {
      if (e.getException() instanceof IOException) throw (IOException) e.getException();
      Assert.isTrue(false);
    }
  }
  /**
   * Generates content for the Roxygen comment for the given function definition
   *
   * @param rMethod function element
   * @param lineDelimiter the line delimiter to be used
   * @return
   * @throws CoreException thrown when the evaluation of the code template fails
   */
  public static EvaluatedTemplate getCommonFunctionRoxygenComment(
      final IRMethod rMethod, final String lineDelimiter) throws CoreException {
    final Template template =
        RUIPlugin.getDefault()
            .getRCodeGenerationTemplateStore()
            .findTemplate(RCodeTemplatesContextType.ROXYGEN_COMMONFUNCTION_TEMPLATE);
    if (template == null) {
      return null;
    }

    final ISourceUnit su = rMethod.getSourceUnit();
    final RCodeTemplatesContext context =
        new RCodeTemplatesContext(
            RCodeTemplatesContextType.ROXYGEN_COMMONFUNCTION_CONTEXTTYPE, su, lineDelimiter);
    context.setRElement(rMethod);

    try {
      final TemplateBuffer buffer = context.evaluate(template);
      if (buffer == null) {
        return null;
      }
      final EvaluatedTemplate data = new EvaluatedTemplate(buffer, lineDelimiter);

      final AbstractDocument content = data.startPostEdit();
      final StringBuilder tagBuffer = new StringBuilder(64);
      final TemplateVariable paramVariable =
          TemplatesUtil.findVariable(buffer, RCodeTemplatesContextType.ROXYGEN_PARAM_TAGS_VARIABLE);
      final Position[] paramPositions =
          new Position[(paramVariable != null) ? paramVariable.getOffsets().length : 0];
      for (int i = 0; i < paramPositions.length; i++) {
        paramPositions[i] = new Position(paramVariable.getOffsets()[i], paramVariable.getLength());
        content.addPosition(paramPositions[i]);
      }

      if (paramPositions.length > 0) {
        String[] tags = null;
        final ArgsDefinition args = rMethod.getArgsDefinition();
        if (args != null) {
          final int count = args.size();
          tags = new String[count];
          for (int i = 0; i < count; i++) {
            tagBuffer.append("@param "); // $NON-NLS-1$
            tagBuffer.append(args.get(i).name);
            tagBuffer.append(" "); // $NON-NLS-1$
            tags[i] = tagBuffer.toString();
            tagBuffer.setLength(0);
          }
        }
        for (final Position pos : paramPositions) {
          insertRoxygen(content, pos, tags);
        }
      }

      data.finishPostEdit();
      return data;
    } catch (final Exception e) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              RUI.PLUGIN_ID,
              NLS.bind(
                  TemplateMessages.TemplateEvaluation_error_description, template.getDescription()),
              e));
    }
  }
  /**
   * Generates content for the Roxygen comment for the given method definition
   *
   * @param rMethod function element
   * @param lineDelimiter the line delimiter to be used
   * @return
   * @throws CoreException thrown when the evaluation of the code template fails
   */
  public static EvaluatedTemplate getMethodRoxygenComment(
      final IRMethod rMethod, final String lineDelimiter) throws CoreException {
    final Template template =
        RUIPlugin.getDefault()
            .getRCodeGenerationTemplateStore()
            .findTemplate(RCodeTemplatesContextType.ROXYGEN_S4METHOD_TEMPLATE);
    if (template == null) {
      return null;
    }

    final ISourceUnit su = rMethod.getSourceUnit();
    final RCodeTemplatesContext context =
        new RCodeTemplatesContext(
            RCodeTemplatesContextType.ROXYGEN_METHOD_CONTEXTTYPE, su, lineDelimiter);
    context.setRElement(rMethod);

    try {
      final TemplateBuffer buffer = context.evaluate(template);
      if (buffer == null) {
        return null;
      }
      final EvaluatedTemplate data = new EvaluatedTemplate(buffer, lineDelimiter);

      final AbstractDocument content = data.startPostEdit();
      final StringBuilder sb = new StringBuilder(64);

      final Position[] sigPositions;
      String sigText = null;
      {
        final TemplateVariable variable =
            TemplatesUtil.findVariable(buffer, RCodeTemplatesContextType.ROXYGEN_SIG_LIST_VARIABLE);
        sigPositions = new Position[(variable != null) ? variable.getOffsets().length : 0];
        for (int i = 0; i < sigPositions.length; i++) {
          sigPositions[i] = new Position(variable.getOffsets()[i], variable.getLength());
          content.addPosition(sigPositions[i]);
        }

        if (sigPositions.length > 0) {
          final ArgsDefinition args = rMethod.getArgsDefinition();
          if (args != null) {
            final int count = args.size();
            for (int i = 0; i < count; i++) {
              final Arg arg = args.get(i);
              if (arg.className == null || arg.className.equals("ANY")) { // $NON-NLS-1$
                break;
              }
              sb.append(arg.className);
              sb.append(","); // $NON-NLS-1$
            }
            if (sb.length() > 0) {
              sigText = sb.substring(0, sb.length() - 1);
              sb.setLength(0);
            }
          }
        }
      }
      final Position[] paramPositions;
      String[] paramTags = null;
      {
        final TemplateVariable variable =
            TemplatesUtil.findVariable(
                buffer, RCodeTemplatesContextType.ROXYGEN_PARAM_TAGS_VARIABLE);
        paramPositions = new Position[(variable != null) ? variable.getOffsets().length : 0];
        for (int i = 0; i < paramPositions.length; i++) {
          paramPositions[i] = new Position(variable.getOffsets()[i], variable.getLength());
          content.addPosition(paramPositions[i]);
        }

        if (paramPositions.length > 0) {
          String list = null;
          final ArgsDefinition args = rMethod.getArgsDefinition();
          if (args != null) {
            final int count = args.size();
            paramTags = new String[count];
            for (int i = 0; i < count; i++) {
              sb.append("@param "); // $NON-NLS-1$
              sb.append(args.get(i).name);
              sb.append(" "); // $NON-NLS-1$
              paramTags[i] = sb.toString();
              sb.setLength(0);
            }
          }
        }
      }

      if (sigPositions != null) {
        for (final Position pos : sigPositions) {
          insertRoxygen(content, pos, sigText);
        }
      }
      if (paramPositions != null) {
        for (final Position pos : paramPositions) {
          insertRoxygen(content, pos, paramTags);
        }
      }

      data.finishPostEdit();
      return data;
    } catch (final Exception e) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              RUI.PLUGIN_ID,
              NLS.bind(
                  TemplateMessages.TemplateEvaluation_error_description, template.getDescription()),
              e));
    }
  }
  /**
   * Generates content for the Roxygen comment for the given class definition
   *
   * @param rClass class element
   * @param lineDelimiter the line delimiter to be used
   * @return
   * @throws CoreException thrown when the evaluation of the code template fails
   */
  public static EvaluatedTemplate getClassRoxygenComment(
      final IRClass rClass, final String lineDelimiter) throws CoreException {
    final Template template =
        RUIPlugin.getDefault()
            .getRCodeGenerationTemplateStore()
            .findTemplate(RCodeTemplatesContextType.ROXYGEN_S4CLASS_TEMPLATE);
    if (template == null) {
      return null;
    }

    final ISourceUnit su = rClass.getSourceUnit();
    final RCodeTemplatesContext context =
        new RCodeTemplatesContext(
            RCodeTemplatesContextType.ROXYGEN_CLASS_CONTEXTTYPE, su, lineDelimiter);
    context.setRElement(rClass);

    try {
      final TemplateBuffer buffer = context.evaluate(template);
      if (buffer == null) {
        return null;
      }
      final EvaluatedTemplate data = new EvaluatedTemplate(buffer, lineDelimiter);

      final AbstractDocument content = data.startPostEdit();
      final StringBuilder tagBuffer = new StringBuilder(64);
      final TemplateVariable slotVariable =
          TemplatesUtil.findVariable(buffer, RCodeTemplatesContextType.ROXYGEN_SLOT_TAGS_VARIABLE);
      final Position[] slotPositions =
          new Position[(slotVariable != null) ? slotVariable.getOffsets().length : 0];
      for (int i = 0; i < slotPositions.length; i++) {
        slotPositions[i] = new Position(slotVariable.getOffsets()[i], slotVariable.getLength());
        content.addPosition(slotPositions[i]);
      }

      if (slotPositions.length > 0) {
        String[] tags = null;
        final List<? extends IModelElement> slots =
            rClass.getModelChildren(IRElement.R_S4SLOT_FILTER);
        final int count = slots.size();
        tags = new String[count];
        for (int i = 0; i < count; i++) {
          final IRSlot slot = (IRSlot) slots.get(i);
          tagBuffer.append("@slot "); // $NON-NLS-1$
          tagBuffer.append(slot.getElementName().getDisplayName());
          tagBuffer.append(" "); // $NON-NLS-1$
          tags[i] = tagBuffer.toString();
          tagBuffer.setLength(0);
        }
        for (final Position pos : slotPositions) {
          insertRoxygen(content, pos, tags);
        }
      }

      data.finishPostEdit();
      return data;
    } catch (final Exception e) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              RUI.PLUGIN_ID,
              NLS.bind(
                  TemplateMessages.TemplateEvaluation_error_description, template.getDescription()),
              e));
    }
  }