@Override public void resolve(final TemplateBuffer buffer, final TemplateContext context) throws MalformedTreeException, BadLocationException { Assert.isNotNull(context); final TemplateVariable[] variables = buffer.getVariables(); final IDocument document = new Document(buffer.getString()); final List<TextEdit> positions = TemplatesUtil.variablesToPositions(variables); final List<TextEdit> edits = new ArrayList<>(5); // iterate over all variables and try to resolve them for (int i = 0; i != variables.length; i++) { final TemplateVariable variable = variables[i]; if (variable.isUnambiguous()) { continue; } // remember old values final int[] oldOffsets = variable.getOffsets(); final int oldLength = variable.getLength(); final String oldValue = variable.getDefaultValue(); final String type = variable.getType(); TemplateVariableResolver resolver = getResolver(type); if (resolver == null) { resolver = new TemplateVariableResolver(); resolver.setType(type); } resolver.resolve(variable, context); final String value = variable.getDefaultValue(); final String[] ln = document.getLegalLineDelimiters(); final boolean multiLine = (TextUtilities.indexOf(ln, value, 0)[0] != -1); if (!oldValue.equals(value)) { // update buffer to reflect new value for (int k = 0; k != oldOffsets.length; k++) { String thisValue = value; if (multiLine) { final String indent = TemplatesUtil.searchIndentation(document, oldOffsets[k]); if (indent.length() > 0) { final StringBuilder temp = new StringBuilder(thisValue); int offset = 0; while (true) { final int[] search = TextUtilities.indexOf(ln, temp.toString(), offset); if (search[0] == -1) { break; } offset = search[0] + ln[search[1]].length(); temp.insert(offset, indent); offset += indent.length(); } thisValue = temp.toString(); } } edits.add(new ReplaceEdit(oldOffsets[k], oldLength, thisValue)); } } } final MultiTextEdit edit = new MultiTextEdit(0, document.getLength()); edit.addChildren(positions.toArray(new TextEdit[positions.size()])); edit.addChildren(edits.toArray(new TextEdit[edits.size()])); edit.apply(document, TextEdit.UPDATE_REGIONS); TemplatesUtil.positionsToVariables(positions, variables); buffer.setContent(document.get(), variables); }
/* * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer, char, int, int) */ @Override public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { IDocument document = viewer.getDocument(); try { fContext.setReadOnly(false); int start; TemplateBuffer templateBuffer; try { beginCompoundChange(viewer); int oldReplaceOffset = getReplaceOffset(); try { // this may already modify the document (e.g. add imports) templateBuffer = fContext.evaluate(fTemplate); } catch (TemplateException e1) { fSelectedRegion = fRegion; return; } start = getReplaceOffset(); int shift = start - oldReplaceOffset; int end = Math.max(getReplaceEndOffset(), offset + shift); // insert template string if (end > document.getLength()) end = offset; String templateString = templateBuffer.getString(); document.replace(start, end - start, templateString); } finally { endCompoundChange(viewer); } // translate positions LinkedModeModel model = new LinkedModeModel(); TemplateVariable[] variables = templateBuffer.getVariables(); MultiVariableGuess guess = fContext instanceof CompilationUnitContext ? ((CompilationUnitContext) fContext).getMultiVariableGuess() : null; boolean hasPositions = false; for (int i = 0; i != variables.length; i++) { TemplateVariable variable = variables[i]; if (variable.isUnambiguous()) continue; LinkedPositionGroup group = new LinkedPositionGroup(); int[] offsets = variable.getOffsets(); int length = variable.getLength(); LinkedPosition first; if (guess != null && variable instanceof MultiVariable) { first = new VariablePosition( document, offsets[0] + start, length, guess, (MultiVariable) variable); guess.addSlave((VariablePosition) first); } else { String[] values = variable.getValues(); ICompletionProposal[] proposals = new ICompletionProposal[values.length]; for (int j = 0; j < values.length; j++) { ensurePositionCategoryInstalled(document, model); Position pos = new Position(offsets[0] + start, length); document.addPosition(getCategory(), pos); proposals[j] = new PositionBasedCompletionProposal(values[j], pos, length); } if (proposals.length > 1) first = new ProposalPosition(document, offsets[0] + start, length, proposals); else first = new LinkedPosition(document, offsets[0] + start, length); } for (int j = 0; j != offsets.length; j++) if (j == 0) group.addPosition(first); else group.addPosition(new LinkedPosition(document, offsets[j] + start, length)); model.addGroup(group); hasPositions = true; } if (hasPositions) { model.forceInstall(); JavaEditor editor = getJavaEditor(); if (editor != null) { model.addLinkingListener(new EditorHighlightingSynchronizer(editor)); } LinkedModeUI ui = new EditorLinkedModeUI(model, viewer); ui.setExitPosition(viewer, getCaretOffset(templateBuffer) + start, 0, Integer.MAX_VALUE); ui.enter(); fSelectedRegion = ui.getSelectedRegion(); } else { fSelectedRegion = new Region(getCaretOffset(templateBuffer) + start, 0); } } catch (BadLocationException e) { JavaPlugin.log(e); openErrorDialog(viewer.getTextWidget().getShell(), e); fSelectedRegion = fRegion; } catch (BadPositionCategoryException e) { JavaPlugin.log(e); openErrorDialog(viewer.getTextWidget().getShell(), e); fSelectedRegion = fRegion; } }