org.obeonetwork.m2doc.parser.BodyGeneratedParser.java Source code

Java tutorial

Introduction

Here is the source code for org.obeonetwork.m2doc.parser.BodyGeneratedParser.java

Source

/*******************************************************************************
 *  Copyright (c) 2016 Obeo. 
 *  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
 *   
 *   Contributors:
 *       Obeo - initial API and implementation
 *  
 *******************************************************************************/
package org.obeonetwork.m2doc.parser;

import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.poi.xwpf.usermodel.IBody;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.eclipse.acceleo.query.runtime.IQueryBuilderEngine;
import org.eclipse.acceleo.query.runtime.IQueryEnvironment;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.obeonetwork.m2doc.template.Block;
import org.obeonetwork.m2doc.template.TemplatePackage;
import org.obeonetwork.m2doc.template.UserContent;

import static org.obeonetwork.m2doc.util.M2DocUtils.message;

/**
 * Body parser for destination document (result of M2Doc generation document).
 * This
 * 
 * @author ohaegi
 */
public class BodyGeneratedParser extends BodyAbstractParser {

    /**
     * User Conetnt Ids list.
     * Used for uniqueness test.
     */
    private List<String> userContentIds = new ArrayList<String>();

    /**
     * Creates a new {@link BodyGeneratedParser} instance.
     * 
     * @param inputDocument
     *            the input template to parser
     * @param queryEnvironment
     *            the query environment to used during parsing.
     */
    public BodyGeneratedParser(IBody inputDocument, IQueryEnvironment queryEnvironment) {
        super(inputDocument, queryEnvironment);
    }

    /**
     * Creates a new {@link BodyGeneratedParser} instance.
     * 
     * @param inputDocument
     *            the input template to parser
     * @param queryParser
     *            the query parser to use during parsing
     * @param queryEnvironment
     *            The {@link IQueryEnvironment}
     */
    private BodyGeneratedParser(IBody inputDocument, IQueryBuilderEngine queryParser,
            IQueryEnvironment queryEnvironment) {
        super(inputDocument, queryParser, queryEnvironment);
    }

    /**
     * returns the next token type after index.
     * 
     * @return the next token type.
     */
    @Override
    protected TokenType getNextTokenType() {
        int index = 1;
        ParsingToken token = runIterator.lookAhead(index);
        TokenType result;
        if (token == null) {
            result = TokenType.EOF;
        } else if (token.getKind() == ParsingTokenKind.TABLE) {
            result = TokenType.WTABLE;
        } else {
            XWPFRun run = token.getRun();
            // is run a field begin run
            if (fieldUtils.isFieldBegin(run)) {
                String code = fieldUtils.lookAheadTag(runIterator);
                if (code.startsWith(TokenType.ENDUSERCONTENT.getValue())) {
                    result = TokenType.ENDUSERCONTENT;
                } else if (code.startsWith(TokenType.USERCONTENT.getValue())) {
                    result = TokenType.USERCONTENT;
                } else {
                    result = TokenType.STATIC;
                }
            } else {
                result = TokenType.STATIC;
            }
        }
        return result;
    }

    @Override
    protected Block parseBlock(TokenType... endTypes) throws DocumentParserException {
        final Block res = (Block) EcoreUtil.create(TemplatePackage.Literals.BLOCK);

        TokenType type = getNextTokenType();
        List<TokenType> endTypeList = Lists.newArrayList(endTypes);
        endBlock: while (!endTypeList.contains(type)) {
            switch (type) {
            case USERCONTENT:
                res.getStatements().add(parseUserContent());
                break;
            case ENDUSERCONTENT:
                // report the error and ignore the problem so that parsing
                // continues in other parts of the document.
                XWPFRun run = runIterator.lookAhead(1).getRun();
                if (run == null) {
                    throw new IllegalStateException(
                            "Token of type " + type + " detected. Run shouldn't be null at this place.");
                }
                res.getValidationMessages().add(new TemplateValidationMessage(ValidationMessageLevel.ERROR,
                        message(ParsingErrorMessage.UNEXPECTEDTAG, type.getValue()), run));
                readTag(res, res.getRuns());
                break;
            case EOF:
                final XWPFParagraph lastParagraph = document.getParagraphs()
                        .get(document.getParagraphs().size() - 1);
                final XWPFRun lastRun = lastParagraph.getRuns().get(lastParagraph.getRuns().size() - 1);
                res.getValidationMessages()
                        .add(new TemplateValidationMessage(ValidationMessageLevel.ERROR,
                                message(ParsingErrorMessage.UNEXPECTEDTAGMISSING, type, Arrays.toString(endTypes)),
                                lastRun));
                break endBlock;
            case STATIC:
                res.getStatements().add(parseStaticFragment());
                break;
            case WTABLE:
                res.getStatements().add(parseTable(runIterator.next().getTable()));
                break;
            default:
                throw new UnsupportedOperationException(
                        String.format("Developer error: TokenType %s is not supported", type));
            }
            type = getNextTokenType();
        }

        return res;
    }

    /**
     * Parses a user Document destination part.
     * user Document destination part are made of the following set of tags : {m:userdoccontent id} ...
     * ... {m:endusercontent}.
     * userContent is generated by M2Doc and the parser extract user document part.
     * 
     * @author ohaegi
     * @return the created object
     * @throws DocumentParserException
     *             if something wrong happens during parsing.
     */
    private UserContent parseUserContent() throws DocumentParserException {
        // first read the tag that opens the link
        final UserContent userContent = (UserContent) EcoreUtil.create(TemplatePackage.Literals.USER_CONTENT);
        String tagText = readTag(userContent, userContent.getRuns()).trim();
        // remove the prefix
        tagText = tagText.substring(TokenType.USERCONTENT.getValue().length()).trim();

        if (tagText == null || "".equals(tagText)) {
            final XWPFRun lastRun = userContent.getRuns().get(userContent.getRuns().size() - 1);
            TemplateValidationMessage templateValidationMessage = new TemplateValidationMessage(
                    ValidationMessageLevel.WARNING, ParsingErrorMessage.INVALID_USERCONTENT_VALUE.getMessage(),
                    lastRun);
            userContent.getValidationMessages().add(templateValidationMessage);
        } else {
            userContent.setId(tagText);
            if (userContentIds.contains(tagText)) {
                final XWPFRun lastRun = userContent.getRuns().get(userContent.getRuns().size() - 1);
                TemplateValidationMessage templateValidationMessage = new TemplateValidationMessage(
                        ValidationMessageLevel.WARNING,
                        message(ParsingErrorMessage.INVALID_USERDOC_ID_NOT_UNIQUE, tagText), lastRun);
                userContent.getValidationMessages().add(templateValidationMessage);
            } else {
                userContentIds.add(tagText);
            }
        }

        // read up the tags until the "m:enduserdoc" tag is encountered.
        final Block body = parseBlock(TokenType.ENDUSERCONTENT);
        userContent.setBody(body);
        if (getNextTokenType() != TokenType.EOF) {
            readTag(userContent, userContent.getClosingRuns());
        }

        return userContent;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.obeonetwork.m2doc.parser.BodyAbstractParser#getNewParser(org.apache.poi.xwpf.usermodel.IBody)
     */
    @Override
    protected BodyAbstractParser getNewParser(IBody inputDocument) {
        BodyAbstractParser parser = new BodyGeneratedParser(inputDocument, this.queryParser, this.queryEnvironment);
        return parser;
    }
}