Webiyo

This page was generated using Webiyo. See its source code and unit tests.

org/webiyo/examples/viewjava/Source.java

package org.webiyo.examples.viewjava;

import java.io.IOException;
import java.util.*;

import static org.webiyo.examples.viewjava.TokenType.NAME;
import static org.webiyo.examples.viewjava.TokenType.SYMBOL;
import static org.webiyo.examples.viewjava.TokenType.WHITESPACE;

public class Source {

    private final SourceFile file;
    private final String text;
    private final List<Token> tokens;
    private final Map<String, String> shortToFullClassName;

    public Source(SourceFile file, SourceIndex index) throws IOException {
        this(file, index, file.loadSource());
    }

    public Source(SourceFile file, SourceIndex index, String text) {
        this.file = file;
        this.text = text;
        this.tokens = parse(text);

        this.shortToFullClassName = new LinkedHashMap<String, String>();
        addClassNames(index.getFilesInPackage(file.getPackage()), shortToFullClassName);
        addImports(tokens, index, shortToFullClassName);
    }

    public SourceFile getFile() {
        return file;
    }

    public String getText() {
        return text;
    }

    public List<Token> getTokens() {
        return tokens;
    }

    public String getFullClassNameFor(String shortClassName) {
        return shortToFullClassName.get(shortClassName);
    }

    public String getClassName() {
        return file.getClassName();
    }
    
    // end of public methods

    private static List<Token> parse(String text) {
        List<Token> tokens = new ArrayList<Token>();
        Lexer lexer = new Lexer(text);
        while (lexer.hasNext()) {
            tokens.add(lexer.next());
        }
        return tokens;
    }

    private static void addClassNames(List<SourceFile> filesToAdd, Map<String, String> shortToFullClassName) {
        for (SourceFile file : filesToAdd) {
            shortToFullClassName.put(file.getClassNameWithoutPackage(), file.getClassName());
        }
    }

    private static void addImports(List<Token> tokens, SourceIndex index, Map<String, String> result) {
        Iterator<Token> it = tokens.iterator();
        while (it.hasNext()) {
            nextImport(it);

            if (match(WHITESPACE, it) == null) continue;

            String importName = readImportName(it);
            if (importName == null) continue;

            if (importName.endsWith(".*")) {
                String packageName = importName.substring(0, importName.length() - 2);
                addClassNames(index.getFilesInPackage(packageName), result);
            } else {
                result.put(getShortClassName(importName), importName);
            }
        }
    }

    private static String getShortClassName(String className) {
        int lastDot = className.lastIndexOf('.');
        String shortName = className.substring(lastDot + 1);
        return shortName;
    }

    private static String readImportName(Iterator<Token> it) {
        StringBuilder result = new StringBuilder();
        while (it.hasNext()) {
            Token token = it.next();

            if (token.getText().equals("*")) {
                result.append("*");

                return match(";", it) ? result.toString() : null;

            } else if (token.getType() != NAME) {
                return null;
            }

            result.append(token.getText());

            String symbol = match(SYMBOL, it);
            if (";".equals(symbol)) {
                return result.toString();
            } else if (!".".equals(symbol)) {
                return null;
            }
            result.append(".");
        }

        return null;
    }

    private static boolean match(String expectedText, Iterator<Token> it) {
        if (!it.hasNext()) return false;
        Token token = it.next();
        return token.getText().equals(expectedText);
    }

    private static String match(TokenType expectedType, Iterator<Token> it) {
        if (!it.hasNext()) return null;
        Token token = it.next();
        if (token.getType() == expectedType) {
            return token.getText();
        } else {
            return null;
        }
    }

    private static void nextImport(Iterator<Token> it) {
        while (it.hasNext()) {
            Token t = it.next();
            if (t.getText().equals("import")) {
                return;
            }
        }
    }

}

SourceForge