org.xpect.expectation.impl.AbstractExpectation.java Source code

Java tutorial

Introduction

Here is the source code for org.xpect.expectation.impl.AbstractExpectation.java

Source

/*******************************************************************************
 * Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.xpect.expectation.impl;

import java.util.List;

import org.xpect.XpectArgument;
import org.xpect.expectation.IExpectationRegion;
import org.xpect.expectation.IMultiLineExpectationRegion;
import org.xpect.expectation.ISingleLineExpectationRegion;
import org.xpect.expectation.impl.TargetSyntaxSupport.TargetLiteralSupport;
import org.xpect.text.IReplacement;
import org.xpect.text.Replacement;
import org.xpect.text.Text;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;

/**
 * @author Moritz Eysholdt - Initial contribution and API
 */
public class AbstractExpectation {
    private final XpectArgument argument;
    private final IExpectationRegion region;
    private final TargetLiteralSupport targetLiteral;
    private final TargetSyntaxSupport targetSyntax;

    public AbstractExpectation(XpectArgument argument, TargetSyntaxSupport targetSyntax) {
        super();
        this.argument = argument;
        this.region = argument.getStatement().getRelatedRegion(IExpectationRegion.class);
        Preconditions.checkPositionIndex(region.getOffset(), region.getDocument().length());
        Preconditions.checkPositionIndex(region.getOffset() + region.getLength(), region.getDocument().length());
        this.targetSyntax = targetSyntax;
        this.targetLiteral = targetSyntax.getLiteralSupport(region.getOffset());
    }

    protected String findValidSeparator(String value, String suggestedSeparator) {
        if (suggestedSeparator != null && !value.contains(suggestedSeparator))
            return suggestedSeparator;
        final String chars = "-~=+*%#$&";
        for (int i = 3; i < 80; i++) {
            for (int c = 0; i < chars.length(); c++) {
                String separator = Strings.repeat(String.valueOf(chars.charAt(c)), i);
                if (!value.contains(separator))
                    return separator;
            }
        }
        throw new IllegalStateException();
    }

    public XpectArgument getArgument() {
        return argument;
    }

    public String getExpectation() {
        if (region.getLength() < 0)
            return "";
        Text substring = new Text(region.getDocument().toString().substring(region.getOffset(),
                region.getOffset() + region.getLength()));
        if (region instanceof IMultiLineExpectationRegion) {
            String indentation = ((IMultiLineExpectationRegion) region).getIndentation();
            List<String> lines = substring.splitIntoLines();
            String newLines[] = new String[lines.size()];
            for (int i = 0; i < lines.size(); i++)
                if (lines.get(i).startsWith(indentation))
                    newLines[i] = lines.get(i).substring(indentation.length());
                else
                    newLines[i] = lines.get(i);
            return Joiner.on(substring.getNL()).join(newLines);
        } else {
            return substring.getText().toString();
        }
    }

    public IExpectationRegion getRegion() {
        return region;
    }

    protected IReplacement getReplacement(Text value, boolean enforceMultiLine) {
        Text document = new Text(region.getDocument());
        if (region instanceof IMultiLineExpectationRegion) {
            IMultiLineExpectationRegion mlRegion = (IMultiLineExpectationRegion) region;
            String indentation = mlRegion.getIndentation();
            String separator = findValidSeparator(value.toString(), mlRegion.getSeparator());
            int sepOpening = mlRegion.getOpeningSeparatorOffset();
            int sepClosing = mlRegion.getClosingSeparatorOffset();
            String betweenSeparatorAndExpectation = document
                    .substring(sepOpening + mlRegion.getSeparator().length(), mlRegion.getOffset());
            String betweenExpectationAndSeparator = document.substring(mlRegion.getOffset() + mlRegion.getLength(),
                    sepClosing);
            String indented = indentation + value.indentWith(indentation);
            StringBuilder builder = new StringBuilder();
            builder.append(separator);
            builder.append(betweenSeparatorAndExpectation);
            builder.append(indented);
            builder.append(betweenExpectationAndSeparator);
            builder.append(separator);
            return new Replacement(document.getText(), sepOpening,
                    (sepClosing + mlRegion.getSeparator().length()) - sepOpening, builder.toString());
        } else if (region instanceof ISingleLineExpectationRegion) {
            ISingleLineExpectationRegion slRegion = (ISingleLineExpectationRegion) region;
            if (enforceMultiLine) {
                String separator = findValidSeparator(value.toString(), null);
                String indentation = document.findIndentation(slRegion.getOpeningSeparatorOffset());
                String insideIndentation = indentation;
                if (insideIndentation.length() > 0) {
                    char first = insideIndentation.charAt(0);
                    if (first == '\t')
                        insideIndentation += first;
                    else
                        insideIndentation += "" + first + first + first + first;
                }
                String indented = insideIndentation + value.indentWith(insideIndentation);
                StringBuilder builder = new StringBuilder();
                builder.append(separator);
                builder.append(document.getNL());
                builder.append(indented);
                builder.append(document.getNL());
                builder.append(indentation);
                builder.append(separator);
                int length = (slRegion.getOffset() - slRegion.getOpeningSeparatorOffset()) + slRegion.getLength();
                return new Replacement(document.getText(), slRegion.getOpeningSeparatorOffset(), length,
                        builder.toString());
            } else {
                return new Replacement(document.getText(), region.getOffset(), region.getLength(),
                        value.toString());
            }
        }
        throw new IllegalStateException();
    }

    public TargetSyntaxSupport getTargetSyntax() {
        return targetSyntax;
    }

    public TargetLiteralSupport getTargetSyntaxLiteral() {
        return targetLiteral;
    }

    protected String replaceInDocument(String newValue) {
        Text document = new Text(region.getDocument());
        Text value = new Text(newValue);
        boolean multiline = targetSyntax.supportsMultiLineLiteral() && value.isMultiline();
        IReplacement replacement = getReplacement(value, multiline);
        IReplacement targetReplacement = targetLiteral.adoptToTargetSyntax(replacement, multiline);
        return document.with(targetReplacement);
    }
}