com.sap.research.connectivity.gw.parsers.JavaSourceFileEditor.java Source code

Java tutorial

Introduction

Here is the source code for com.sap.research.connectivity.gw.parsers.JavaSourceFileEditor.java

Source

/*
 * Copyright 2012 SAP AG
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sap.research.connectivity.gw.parsers;

import japa.parser.JavaParser;
import japa.parser.ParseException;
import japa.parser.ast.CompilationUnit;
import japa.parser.ast.ImportDeclaration;
import japa.parser.ast.body.BodyDeclaration;
import japa.parser.ast.body.FieldDeclaration;
import japa.parser.ast.body.MethodDeclaration;
import japa.parser.ast.body.TypeDeclaration;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.springframework.roo.process.manager.MutableFile;

public class JavaSourceFileEditor implements JavaSourceFileEditorInterface {

    private static final char SEPARATOR = File.separatorChar;

    /*
     * The name of the class (we suppose that we are editing a .java file containing a class having the same name as the file name)
     */
    public String CLASS_NAME;
    /*
     * The header of the class (annotations and declaration, without {)
     */
    private String classDeclaration;

    private MutableFile sourceFile;

    private ArrayList<JavaSourceField> globalFieldList;
    private ArrayList<JavaSourceMethod> globalMethodList;
    private ArrayList<String> importList;

    /*
     * Needed by the JAVA Parser class, so we can get already existing content in the file
     */
    private CompilationUnit compilationUnit;

    public JavaSourceFileEditor(MutableFile sourceFile) {
        this.sourceFile = sourceFile;

        final String canonicalPath = sourceFile.getCanonicalPath();
        this.CLASS_NAME = canonicalPath.substring(canonicalPath.lastIndexOf(SEPARATOR) + 1,
                canonicalPath.lastIndexOf("."));

        importList = new ArrayList<String>();
        globalFieldList = new ArrayList<JavaSourceField>();
        globalMethodList = new ArrayList<JavaSourceMethod>();

        /*
         * Here we parse the java file and get the already existing imports, methods and fields
         */
        if (!sourceFile.toString().isEmpty())
            initJavaParser();
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#initJavaParser()
     */
    public void initJavaParser() {
        // creates an input stream for the file to be parsed
        InputStream inputStream = sourceFile.getInputStream();

        try {
            // parse the file
            compilationUnit = JavaParser.parse(inputStream);
        } catch (ParseException e) {
            System.out.println("Java Parser could not be initialized!");
            e.printStackTrace();
            return;
        } finally {
            IOUtils.closeQuietly(inputStream);
        }

        initImports();
        initVarsAndMethods();
    }

    private void initImports() {
        List<ImportDeclaration> imports = compilationUnit.getImports();
        for (ImportDeclaration imp : imports) {
            importList.add(imp.getName().toString());
        }
    }

    /*
     * We are translating the methods and fields from the java parser format to our format
     */
    private void initVarsAndMethods() {
        List<TypeDeclaration> types = compilationUnit.getTypes();
        for (TypeDeclaration type : types) {
            List<BodyDeclaration> members = type.getMembers();
            //We are dealing with class declaration
            StringBuffer s = new StringBuffer(type.toString());
            classDeclaration = type.toString().substring(0,
                    s.indexOf("{", type.toString().indexOf(type.getName())));
            //log.severe(type.toString().substring(0, type.toString().indexOf(type.getName()) + type.getName().length()));
            for (BodyDeclaration member : members) {
                //We are dealing with methods
                if (member instanceof MethodDeclaration) {
                    MethodDeclaration method = (MethodDeclaration) member;
                    JavaSourceMethod methodTranslated = new JavaSourceMethod(method);
                    globalMethodList.add(methodTranslated);
                } else
                //We are dealing with fields
                if (member instanceof FieldDeclaration) {
                    FieldDeclaration field = (FieldDeclaration) member;
                    JavaSourceField fieldTranslated = new JavaSourceField(field);
                    globalFieldList.add(fieldTranslated);
                }
            }
        }
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#addGlobalVariable(com.sap.research.connectivity.JavaSourceField)
     */
    public boolean addGlobalField(JavaSourceField field) {

        if (fieldExists(field.getFieldName()))
            return false;

        globalFieldList.add(field);
        return true;
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#addGlobalVariable(com.sap.research.connectivity.JavaSourceField)
     */
    public void addGlobalField(JavaSourceField field, boolean overwrite) {

        JavaSourceField currentVariable = fieldExists(field);
        if (currentVariable != null) {
            if (!overwrite)
                return;
            else {
                currentVariable = field;
                return;
            }
        }

        globalFieldList.add(field);
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#addImport(java.lang.String)
     */
    public void addImport(String importClassName) {
        if (!importExists(importClassName))
            importList.add(importClassName);
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#addImports(java.util.ArrayList)
     */
    public void addImports(ArrayList<String> importList) {
        for (String importClassName : importList) {
            addImport(importClassName);
        }
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#addMethod(com.sap.research.connectivity.JavaSourceMethod)
     */
    public void addMethod(JavaSourceMethod method) {
        addMethod(method, true);
    }

    public void addMethod(JavaSourceMethod method, boolean overwrite) {
        JavaSourceMethod currentMethod = null;
        StringBuffer fileContent;
        if ((currentMethod = getMethod(method)) != null) {
            if (!overwrite)
                return;
            else {
                fileContent = new StringBuffer(getFileContent());
                if (fileContent.equals(""))
                    return;

                replaceMethod(currentMethod, method, fileContent);
            }
        } else {
            fileContent = new StringBuffer(getFileContent());
            if (fileContent.equals(""))
                return;

            insertMethod(method, fileContent);
        }
    }

    private void insertMethod(JavaSourceMethod method, StringBuffer fileContent) {
        //We insert just before the end of the class
        try {
            fileContent.insert(fileContent.lastIndexOf("}"), method.METHOD_STRING);
            globalMethodList.add(method);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void replaceMethod(JavaSourceMethod currentMethod, JavaSourceMethod newMethod,
            StringBuffer fileContent) {
        try {
            currentMethod = newMethod;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#getSourceFile()
     */
    public MutableFile getSourceFile() {
        return sourceFile;
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#getGlobalFieldList()
     */
    public ArrayList<JavaSourceField> getGlobalFieldList() {
        return globalFieldList;
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#getGlobalMethodList()
     */
    public ArrayList<JavaSourceMethod> getGlobalMethodList() {
        return globalMethodList;
    }

    /* (non-Javadoc)
    * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#getImportList()
    */
    public ArrayList<String> getImportList() {
        return importList;
    }

    public JavaSourceMethod getMethod(JavaSourceMethod method) {

        for (JavaSourceMethod existingMethod : globalMethodList) {
            if (existingMethod.getReturnType().equals(method.getReturnType())
                    && existingMethod.getMethodName().equals(method.getMethodName())
                    && existingMethod.getParameters().containsAll(method.getParameters())
                    && method.getParameters().containsAll(existingMethod.getParameters()))
                return existingMethod;
        }

        return null;
    }

    private List<String> getFileLines() {
        InputStream inputStream = sourceFile.getInputStream();
        List<String> lines = null;
        try {
            lines = IOUtils.readLines(inputStream);
        } catch (IOException e) {
            System.out.println("Could not read the lines of the class file");
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
        }

        return lines;
    }

    /* (non-Javadoc)
     * @see com.sap.research.connectivity.JavaSourceFileEditorInterface#getFileContent()
     */
    public String getFileContent() {
        InputStream inputStream = sourceFile.getInputStream();
        String fileContent = "";
        try {
            fileContent = IOUtils.toString(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
        }

        return fileContent;
    }

    public boolean fieldExists(String fieldName) {
        for (JavaSourceField existingField : globalFieldList) {
            if (existingField.getFieldName().equals(fieldName))
                return true;
        }
        return false;
    }

    public JavaSourceField fieldExists(JavaSourceField field) {
        for (JavaSourceField existingField : globalFieldList) {
            if (existingField.equals(field))
                return existingField;
        }
        return null;
    }

    public boolean importExists(String importClassName) {
        return importList.contains(importClassName);
    }

    private void writeContentToFile(String tempContent) throws Exception {
        OutputStream outputStream = sourceFile.getOutputStream();
        try {
            IOUtils.write(tempContent, outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("Could not write into output class file");
        } finally {
            IOUtils.closeQuietly(outputStream);
        }
    }

    public String makeFile() throws Exception {
        StringBuffer newFileContent = new StringBuffer();
        newFileContent.append(getPackageLine());
        newFileContent.append("\n\n");

        ArrayList<String> importClasses = getImportList();
        for (String importClass : importClasses) {
            newFileContent.append("import " + importClass + ";\n");
        }
        newFileContent.append("\n");

        newFileContent.append(classDeclaration);
        newFileContent.append("{\n\n");

        for (JavaSourceField globalField : globalFieldList) {
            newFileContent.append(globalField.FIELD_STRING + "\n");
        }
        newFileContent.append("\n");

        for (JavaSourceMethod globalMethod : globalMethodList) {
            newFileContent.append(globalMethod.METHOD_STRING);
        }

        newFileContent.append("\n}");

        String newFileContentString = newFileContent.toString();
        writeContentToFile(newFileContentString);

        return newFileContentString;
    }

    public String getPackageLine() throws Error {
        List<String> fileLines = getFileLines();
        //compilationUnit.
        if (fileLines == null) {
            throw new Error("Cannot get package name!");
        }

        for (String line : fileLines) {
            if (line.startsWith("package "))
                return line;
        }

        throw new Error("Cannot get package name!");
    }

}