SqlImport.java
/* $Id$
*******************************************************************************
* Copyright (c) 2013 Contributors - see below
* 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:
* Laurent BRAUD
*******************************************************************************
*/
package org.argouml.language.sql.reveng;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.Lexer;
import org.antlr.runtime.Parser;
import org.antlr.runtime.TokenStream;
import org.argouml.i18n.Translator;
import org.argouml.kernel.Project;
import org.argouml.taskmgmt.ProgressMonitor;
import org.argouml.uml.reveng.FileImportUtils;
import org.argouml.uml.reveng.ImportInterface;
import org.argouml.uml.reveng.ImportSettings;
import org.argouml.uml.reveng.ImporterManager;
import org.argouml.uml.reveng.SettingsTypes.Setting;
import org.argouml.util.SuffixFilter;
/**
*
*
* @author BRAUD
*/
public class SqlImport implements ImportInterface {
/**
* New model elements that were added
*/
private Collection<Object> newElements;
/*
* Sql profile model.(not used now)
private Profile sqlProfile = null;
*/
/**
*
* @link SqlImportSettings#getCodeLevel()
*/
private String settingLevel;
/*
* @see org.argouml.uml.reveng.ImportInterface#parseFiles(org.argouml.kernel.Project,
* java.util.Collection, org.argouml.uml.reveng.ImportSettings,
* org.argouml.application.api.ProgressMonitor)
*/
@Override
public Collection<Object> parseFiles(Project p, Collection<File> files,
ImportSettings settings, ProgressMonitor monitor)
throws ImportException {
SqlImportSettings.getInstance().saveSettings();
SqlImportSettings sqlSettings = SqlImportSettings.getInstance();
String sgbd = sqlSettings.getCodeSgbd();
settingLevel = sqlSettings.getCodeLevel();
newElements = new HashSet<Object>();
monitor.updateMainTask(Translator.localize("dialog.import.pass1"));
// sqlProfile = getSqlProfile(p);
try {
monitor.setMaximumProgress(files.size());
doImportPass(p, files, settings, monitor, 0, 0, sgbd);
} finally {
}
return newElements;
}
private void doImportPass(Project p, Collection<File> files,
ImportSettings settings, ProgressMonitor monitor, int startCount,
int pass, String sgbdName) {
int count = startCount;
for (File file : files) {
if (monitor.isCanceled()) {
monitor.updateSubTask(Translator
.localize("dialog.import.cancelled"));
return;
}
try {
parseFile(p, file, settings, pass, sgbdName);
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new java.io.PrintWriter(sw);
e.printStackTrace(pw);
monitor.notifyMessage(
Translator.localize(
"dialog.title.import-problems"), //$NON-NLS-1$
Translator.localize("label.import-problems"), //$NON-NLS-1$
sw.toString());
if (monitor.isCanceled()) {
break;
}
}
monitor.updateProgress(count++);
monitor.updateSubTask(Translator.localize(
"dialog.import.parsingAction",
new Object[] {
file.getAbsolutePath()
}));
}
return;
}
/**
* Do a single import pass of a single file.
*
* @param p the project
* @param f the source file
* @param settings the user provided import settings
* @param pass current import pass - 0 = single pass, 1 = pass 1 of 2, 2 =
* pass 2 of 2
*/
private void parseFile(Project p, File f, ImportSettings settings, int pass, String sgbdName)
throws ImportException {
try {
// Create a scanner that reads from the input stream
String encoding = settings.getInputSourceEncoding();
FileInputStream in = new FileInputStream(f);
InputStreamReader isr;
try {
isr = new InputStreamReader(in, encoding);
} catch (UnsupportedEncodingException e) {
// fall back to default encoding
isr = new InputStreamReader(in);
}
// Create a modeller for the parser
Modeller modeller = new Modeller(
p.getUserDefinedModelList().get(0), null, f.getName());
modeller.setLevel(this.settingLevel);
try {
// MySqlLexer lexer = new MySqlLexer(new ANTLRNoCaseInputStreamReader(isr));
Class<Lexer> lexerClass = (Class<Lexer>) Class.forName("org.argouml.language.sql.reveng." + sgbdName + "Lexer");
Class[] argTypes = {CharStream.class};
Constructor<Lexer> constructor = lexerClass.getDeclaredConstructor(argTypes);
Object[] argumentsLexer = {new ANTLRNoCaseInputStreamReader(isr)};
Lexer instanceLexer = constructor.newInstance(argumentsLexer);
// Create a parser that reads from the scanner
//MySqlParser parser = new MySqlParser(new CommonTokenStream(lexer));
Class<Parser> parserClass = (Class<Parser>) Class.forName("org.argouml.language.sql.reveng." + sgbdName + "Parser");
Class[] argTypesP = {TokenStream.class};
Constructor<Parser> constructorParser = parserClass.getDeclaredConstructor(argTypesP);
Object[] arguments = {new CommonTokenStream(instanceLexer)};
Parser instanceParser = constructorParser.newInstance(arguments);
//parser.dump_read(modeller, lexer);
Class[] argTypesM = {Modeller.class, Lexer.class};
Method printMethod = parserClass.getMethod("dump_read", argTypesM);
Object[] argumentsM = {modeller, instanceLexer};
printMethod.invoke(instanceParser, argumentsM);
} catch(ClassNotFoundException e) {
StringBuilder errorString = new StringBuilder("Parser or Lexer not found : ");
errorString.append(sgbdName);
errorString.append(". ");
errorString.append(buildErrorString(f));
throw new ImportException(errorString.toString(), e);
} catch(Exception e) {
String errorString = buildErrorString(f);
//LOG.error(e.getClass().getName() + errorString, e);
throw new ImportException(errorString, e);
} finally {
newElements.addAll(modeller.getNewElements());
in.close();
}
} catch (IOException e) {
throw new ImportException(buildErrorString(f), e);
}
}
private String buildErrorString(File f) {
String path = "";
try {
path = f.getName();
path = f.getCanonicalPath();
} catch (IOException e) {
// Just ignore - we'll use the simple file name
}
return "Exception in file: " + path;
}
/*
* Get the Sql profile from project, if available.
*
* @param p the project
* @return the Java profile
private Profile getSqlProfile(Project p) {
Profile ret = null;
for (Profile profile : p.getProfileConfiguration().getProfiles()) {
if ("Sql".equals(profile.getDisplayName())) {
ret = profile;
}
}
return ret;
}*/
/*
* @see org.argouml.moduleloader.ModuleInterface#getName()
*/
@Override
public String getName() {
return "Sql-import";
}
/*
* @see org.argouml.moduleloader.ModuleInterface#getInfo(int)
* TODO : like in java module.
*/
@Override
public String getInfo(final int type) {
switch (type) {
case DESCRIPTION:
return "SQL import from dump files.";
case AUTHOR:
return "Laurent BRAUD";
case VERSION:
return "0.35.1";
case DOWNLOADSITE:
return "http://argouml-sql.tigris.org/";
default:
return null;
}
}
/*
* @see org.argouml.uml.reveng.ImportInterface#getSuffixFilters()
*/
@Override
public SuffixFilter[] getSuffixFilters() {
SuffixFilter[] result = { new SuffixFilter("sql",
Translator.localize("argouml-sql.filefilter.sql")), };
return result;
}
/*
* @see org.argouml.moduleloader.ModuleInterface#disable()
*/
@Override
public boolean disable() {
// We are permanently enabled
return false;
}
/*
* @see org.argouml.moduleloader.ModuleInterface#enable()
*/
@Override
public boolean enable() {
ImporterManager.getInstance().addImporter(this);
return true;
}
@Override
public List<Setting> getImportSettings() {
return SqlImportSettings.getInstance().getImportSettings();
}
@Override
public boolean isParseable(File file) {
return FileImportUtils.matchesSuffix(file, getSuffixFilters());
}
}