/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.runtime.util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import javax.xml.stream.XMLStreamException;
import org.teiid.adminapi.AdminException;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.adminapi.impl.VDBMetadataParser;
import org.teiid.cache.Cache;
import org.teiid.cache.CacheFactory;
import org.teiid.core.util.LRUCache;
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.core.util.StringUtil;
import org.teiid.deployers.VirtualDatabaseException;
import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository.ConnectorManagerException;
import org.teiid.logging.LogManager;
import org.teiid.metadata.Database;
import org.teiid.metadata.MetadataStore;
import org.teiid.metadata.Schema;
import org.teiid.query.metadata.DDLStringVisitor;
import org.teiid.query.metadata.DatabaseUtil;
import org.teiid.query.sql.visitor.SQLStringVisitor;
import org.teiid.runtime.EmbeddedConfiguration;
import org.teiid.runtime.EmbeddedServer;
import org.teiid.runtime.JBossLogger;
import org.teiid.translator.ExecutionFactory;
import org.teiid.translator.TranslatorException;
public class ConvertVDB {
public static void main(String[] args) throws Exception {
if (args.length < 1) {
System.out.println("usage: CovertVDB /path/to/file-vdb.xml");
System.exit(0);
}
File f = new File(args[0]);
if (!f.exists()) {
System.out.println("vdb file does not exist");
}
if (f.getName().toLowerCase().endsWith(".xml")) {
System.out.println(convert(f));
} else {
System.out.println("Unknown file type supplied, only .XML based VDBs are supported");
}
}
public static String convert(File f)
throws VirtualDatabaseException, ConnectorManagerException, TranslatorException, IOException,
URISyntaxException, MalformedURLException, AdminException, Exception, FileNotFoundException {
LogManager.setLogListener(new JBossLogger() {
@Override
public boolean isEnabled(String context, int level) {
return false;
}
});
EmbeddedConfiguration ec = new EmbeddedConfiguration();
ec.setUseDisk(false);
ec.setCacheFactory(new CacheFactory() {
@Override
public <K, V> Cache<K, V> get(String name) {
return new MockCache<>(name, 10);
}
@Override
public void destroy() {
}
});
MyServer es = new MyServer();
LogManager.setLogListener(new JBossLogger() {
@Override
public boolean isEnabled(String context, int level) {
return false;
}
});
es.start(ec);
try {
return es.convertVDB(new FileInputStream(f));
} finally {
es.stop();
}
}
private static class MyServer extends EmbeddedServer {
@Override
public ExecutionFactory<Object, Object> getExecutionFactory(String name) throws ConnectorManagerException {
return new ExecutionFactory<Object, Object>() {
@Override
public boolean isSourceRequired() {
return false;
}
@Override
public boolean isSourceRequiredForMetadata() {
return false;
}
};
};
String convertVDB(InputStream is) throws Exception{
byte[] bytes = ObjectConverterUtil.convertToByteArray(is);
VDBMetaData metadata = null;
try {
metadata = VDBMetadataParser.unmarshell(new ByteArrayInputStream(bytes));
} catch (XMLStreamException e) {
throw new VirtualDatabaseException(e);
}
metadata.setXmlDeployment(true);
MetadataStore metadataStore = new MetadataStore();
final LinkedHashMap<String, ModelMetaData> modelMetaDatas = metadata.getModelMetaDatas();
for (ModelMetaData m:modelMetaDatas.values()) {
Schema schema = new Schema();
schema.setName(m.getName());
schema.setAnnotation(m.getDescription());
schema.setVisible(m.isVisible());
schema.setPhysical(m.isSource());
schema.setProperties(m.getPropertiesMap());
metadataStore.addSchema(schema);
}
Database db = DatabaseUtil.convert(metadata, metadataStore);
DDLStringVisitor visitor = new DDLStringVisitor(null, null) {
@Override
protected void createdSchmea(Schema schema) {
}
@Override
protected void visit(Schema schema) {
ModelMetaData m = modelMetaDatas.get(schema.getName());
String replace = "";
String sourceName = m.getSourceNames().isEmpty()?"":m.getSourceNames().get(0);
String schemaName = m.getPropertiesMap().get("importer.schemaPattern");
if (schemaName == null) {
schemaName = "%";
}
if (m.getSourceMetadataType().isEmpty()) {
// nothing defined; so this is NATIVE only
if (m.isSource()) {
replace = replaceMetadataTag(m, sourceName, schemaName, true);
}
} else {
// may one or more defined
for (int i = 0; i < m.getSourceMetadataType().size(); i++) {
String type = m.getSourceMetadataType().get(i);
if (type.equalsIgnoreCase("NATIVE")) {
replace += replaceMetadataTag(m, sourceName, schemaName, true);
} else if (!type.equalsIgnoreCase("DDL")){
replace += replaceMetadataTag(m, type, schemaName, false);
} else {
replace += m.getSourceMetadataText().get(i) + "\n"; //$NON-NLS-1$
}
}
}
buffer.append(replace);
}
};
visitor.visit(db);
return visitor.toString();
}
private String replaceMetadataTag(ModelMetaData m, String sourceName, String schemaName, boolean server) {
String replace = "IMPORT FOREIGN SCHEMA "+SQLStringVisitor.escapeSinglePart(schemaName)+" FROM " + (server?"SERVER ":"REPOSITORY ")+SQLStringVisitor.escapeSinglePart(sourceName)+" INTO "+SQLStringVisitor.escapeSinglePart(m.getName());
if (!m.getPropertiesMap().isEmpty()) {
replace += " OPTIONS (\n";
Iterator<String> it = m.getPropertiesMap().keySet().iterator();
while (it.hasNext()) {
String key = it.next();
replace += ("\t"+SQLStringVisitor.escapeSinglePart(key) +" '"+StringUtil.replaceAll(m.getPropertiesMap().get(key), "'", "''")+"'");
if (it.hasNext()) {
replace += ",\n";
}
}
replace += ")";
}
replace+=";\n\n";
return replace;
}
@Override
protected boolean allowOverrideTranslators() {
return true;
}
};
private static class MockCache<K, V> extends LRUCache<K, V> implements Cache<K, V> {
private String name;
public MockCache(String cacheName, int maxSize) {
super(maxSize<0?Integer.MAX_VALUE:maxSize);
this.name = cacheName;
}
@Override
public V put(K key, V value, Long ttl) {
return put(key, value);
}
@Override
public String getName() {
return this.name;
}
@Override
public boolean isTransactional() {
return false;
}
}
}