/* * Copyright 2010 Pablo Arrighi, Alex Concha, Miguel Lezama for version 1. * Copyright 2013 Pablo Arrighi, Miguel Lezama, Kevin Mazet for version 2. * * This file is part of GOOL. * * GOOL is free software: you can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation, version 3. * * GOOL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License version 3 for more details. * * You should have received a copy of the GNU General Public License along with GOOL, * in the file COPYING.txt. If not, see <http://www.gnu.org/licenses/>. */ package gool.recognizer.common; import gool.Settings; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; public class RecognizerMatcher { //private static Platform InputLang; private static String InputLang; private static String DirOutPut; private static HashMap<String, ArrayList<String>> ClassMatchTable; private static HashMap<String, ArrayList<String>> MethodMatchTable; static public void init(/*Platform inputLang*/ String inputLang) { // Initialization of data structures InputLang = inputLang; ClassMatchTable = new HashMap<String, ArrayList<String>>(); MethodMatchTable = new HashMap<String, ArrayList<String>>(); DirOutPut = Settings.get(InputLang+"_in_dir_tmp"); File tmpFolder = new File(DirOutPut); tmpFolder.mkdir(); // Enabling the recognition of default libraries of the input language ArrayList<String> defaultGoolClasses = getGoolClassesFromImport("default"); for (String defaultGoolClass : defaultGoolClasses) enableRecognition(defaultGoolClass); } public static ArrayList<String> matchImportAdd(String inputLangImport) { ArrayList<String> imports = getImportChange(inputLangImport); ArrayList<String> toReturn = new ArrayList<String>(); if(imports.isEmpty()) return imports ; System.out.print("[RecognizerMatcher] Enabling the recognition of the import : " + inputLangImport ); File tmpFolder = new File(DirOutPut); if(!tmpFolder.exists()){ tmpFolder.mkdir(); } for (String importName : imports){ System.out.println(" and change to "+ importName); File tmpFile = new File(DirOutPut+"/"+importName); System.out.println( copyFile(new File(importName),tmpFile )); toReturn.add(DirOutPut+"/"+importName); } return toReturn; } public static boolean matchImport(String inputLangImport) { ArrayList<String> goolClasses = getGoolClassesFromImport(inputLangImport); for (String goolClass : goolClasses) enableRecognition(goolClass); return !goolClasses.isEmpty(); } public static String matchClass(String inputLangClass) { for (String goolClass : ClassMatchTable.keySet()) if (ClassMatchTable.get(goolClass).contains(inputLangClass)) return goolClass; return null; } public static String matchMethod(String inputLangMethodSignature) { for (String goolMethod : MethodMatchTable.keySet()) if (MethodMatchTable.get(goolMethod).contains( inputLangMethodSignature)) return goolMethod; return null; } private static void enableRecognition(String goolClass) { if(ClassMatchTable.keySet().contains(goolClass)) return; System.out .println("[RecognizerMatcher] Enabling the recognition of the GOOL class: " + goolClass + "."); try { // matching the GOOL class with the input language classes ArrayList<String> inputClasses = new ArrayList<String>(); InputStream ips = new FileInputStream( getPathOfInputClassMatchFile(goolClass)); InputStreamReader ipsr = new InputStreamReader(ips); BufferedReader br = new BufferedReader(ipsr); String line; while ((line = br.readLine()) != null) { line = removeSpaces(line); if (isInputMatchLine(line)) { String currentGoolClass = getLeftPartOfInputMatchLine(line); ArrayList<String> currentInputClasses = parseCommaSeparatedValues(getRightPartOfInputMatchLine(line)); if (currentGoolClass.equals(goolClass)) inputClasses.addAll(currentInputClasses); } } br.close(); ClassMatchTable.put(goolClass, inputClasses); // matching the GOOL methods of the GOOL class with the input // language methods ArrayList<String> goolMethods = getGoolMethodsFromGoolClass(goolClass); for (String goolMethod : goolMethods) { ArrayList<String> inputMethodSignatures = new ArrayList<String>(); ips = new FileInputStream( getPathOfInputMethodMatchFile(goolMethod)); ipsr = new InputStreamReader(ips); br = new BufferedReader(ipsr); while ((line = br.readLine()) != null) { line = removeSpaces(line); if (isInputMatchLine(line)) { String currentGoolMethod = getLeftPartOfInputMatchLine(line); String currentInputMethodSignature = getRightPartOfInputMatchLine(line); if (currentGoolMethod.equals(goolMethod)) inputMethodSignatures .add(currentInputMethodSignature); } } br.close(); MethodMatchTable.put(goolMethod, inputMethodSignatures); } } catch (Exception e) { System.out.println(e.toString()); } } static private ArrayList<String> getImportChange( String inputLangImport) { ArrayList<String> imports = new ArrayList<String>(); try { InputStream ips = new FileInputStream( getPathOfInputImportMatchFile()); InputStreamReader ipsr = new InputStreamReader(ips); BufferedReader br = new BufferedReader(ipsr); String line; while ((line = br.readLine()) != null) { line = removeSpaces(line); if (isInputMatchLine(line)) { String currentImport = getLeftPartOfInputMatchLine(line); ArrayList<String> currentInputImports = parseCommaSeparatedValues(getRightPartOfInputMatchLine(line)); if(isImportAddName(currentImport)){ String importName = getImportAddName(currentImport); if(importName.compareTo(inputLangImport) == 0){ // Recognized import changed : imports.addAll(currentInputImports); } } } } br.close(); } catch (Exception e) { System.out.println(e.toString()); } return imports; } static private ArrayList<String> getGoolClassesFromImport( String inputLangImport) { ArrayList<String> goolClasses = new ArrayList<String>(); try { InputStream ips = new FileInputStream( getPathOfInputImportMatchFile()); InputStreamReader ipsr = new InputStreamReader(ips); BufferedReader br = new BufferedReader(ipsr); String line; while ((line = br.readLine()) != null) { line = removeSpaces(line); if (isInputMatchLine(line)) { String currentGoolClass = getLeftPartOfInputMatchLine(line); ArrayList<String> currentInputImports = parseCommaSeparatedValues(getRightPartOfInputMatchLine(line)); if (currentInputImports.contains(inputLangImport)) goolClasses.add(currentGoolClass); } } br.close(); } catch (Exception e) { System.out.println(e.toString()); } return goolClasses; } static private ArrayList<String> getGoolMethodsFromGoolClass( String goolClass) { ArrayList<String> goolMethods = new ArrayList<String>(); try { InputStream ips = new FileInputStream( getPathOfInputMethodMatchFile(goolClass + ".")); InputStreamReader ipsr = new InputStreamReader(ips); BufferedReader br = new BufferedReader(ipsr); String line; while ((line = br.readLine()) != null) { line = removeSpaces(line); if (isInputMatchLine(line)) { String currentGoolMethod = getLeftPartOfInputMatchLine(line); if (currentGoolMethod.contains(goolClass)) { goolMethods.add(currentGoolMethod); } } } br.close(); } catch (Exception e) { System.out.println(e.toString()); } return goolMethods; } /* * methods used by the GoolMatcher to parse each line of a match file */ static private String removeSpaces(String line) { for (int i = 0; i < line.length(); i++) { if (line.charAt(i) == ' ' || line.charAt(i) == '\t') { line = line.substring(0, i) + line.substring(i + 1); i -= 1; } } return line; } static private boolean isCommentLine(String line) { return line.startsWith("#"); } static private boolean isInputMatchLine(String line) { return !isCommentLine(line) && line.contains("<-"); } static private String getLeftPartOfInputMatchLine(String InputMatchLine) { return InputMatchLine.substring(0, InputMatchLine.indexOf("<-")); } static private String getRightPartOfInputMatchLine(String InputMatchLine) { return InputMatchLine.substring(InputMatchLine.indexOf("<-") + 2); } static private boolean isImportAddName(String importName) { return importName.startsWith("+"); } static private String getImportAddName(String importName) { return importName.substring(1); } static private ArrayList<String> parseCommaSeparatedValues(String csv) { ArrayList<String> parsedValues = new ArrayList<String>(); csv+=";"; while (!csv.isEmpty()) { int ind1 = csv.indexOf(","); int ind2 = csv.indexOf(";"); if (ind1 != -1) { parsedValues.add(csv.substring(0, ind1)); csv = csv.substring(ind1 + 1); } else { parsedValues.add(csv.substring(0, ind2)); csv = csv.substring(ind2 + 1); } } return parsedValues; } /* * methods used by the GoolMatcher to compute the path to match files */ static private String getPathOfInputMatchDir(String goolClass) { String goolPackageName = goolClass.substring(0, goolClass.lastIndexOf(".")); goolPackageName = goolPackageName.replace('.', '/'); return "src/gool/recognizer/" + InputLang.toString().toLowerCase() + "/matching/" + goolPackageName + "/"; } static private String getPathOfInputImportMatchFile() { return "src/gool/recognizer/" + InputLang.toString().toLowerCase() + "/matching/ImportMatching.properties"; } static private String getPathOfInputClassMatchFile(String goolClass) { return getPathOfInputMatchDir(goolClass) + "ClassMatching.properties"; } static private String getPathOfInputMethodMatchFile(String goolMethod) { String goolClassName = goolMethod.substring(0, goolMethod.lastIndexOf(".")); return getPathOfInputMatchDir(goolClassName) + "MethodMatching.properties"; } // The following method may be used for debugging issues: it prints the // content of the match tables. public static void printMatchTables() { System.out.println("[RecognizerMatcher] Printing ClassMatchTable..."); for (String goolClass : ClassMatchTable.keySet()) { System.out.print("[RecognizerMatcher] -- " + goolClass + " <- "); for (String inputLangClass : ClassMatchTable.get(goolClass)) System.out.print(inputLangClass + " "); System.out.println(); } System.out.println("[RecognizerMatcher] Printing MethodMatchTable..."); for (String goolMethod : MethodMatchTable.keySet()) { System.out.print("[RecognizerMatcher] -- " + goolMethod + " <- "); for (String inputLangMethodSignature : MethodMatchTable .get(goolMethod)) System.out.print(inputLangMethodSignature + " "); System.out.println(); } } public static boolean copyFile(File source, File dest){ try{ // Declaration et ouverture des flux java.io.FileInputStream sourceFile = new java.io.FileInputStream(source); try{ java.io.FileOutputStream destinationFile = null; try{ destinationFile = new FileOutputStream(dest); // Lecture par segment de 0.5Mo byte buffer[] = new byte[512 * 1024]; int nbLecture; while ((nbLecture = sourceFile.read(buffer)) != -1){ destinationFile.write(buffer, 0, nbLecture); } } finally { destinationFile.close(); } } finally { sourceFile.close(); } } catch (IOException e){ e.printStackTrace(); return false; // Erreur } return true; // Résultat OK } }