/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.sdt;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.osgi.framework.BundleContext;
import org.teiid.core.designer.PluginUtil;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.core.designer.util.FileUtils;
import org.teiid.core.designer.util.PluginUtilImpl;
import org.teiid.core.designer.util.StringConstants;
import org.teiid.designer.core.types.DatatypeConstants;
import org.teiid.designer.metamodels.xsd.XsdResourceFactory;
/**
* ModelerSdtPlugin
*
* @since 8.0
*/
public class ModelerSdtPlugin extends Plugin {
/**
* The plug-in identifier of this plugin (value <code>"org.teiid.designer.sdt"</code>).
*/
public static final String PLUGIN_ID = "org.teiid.designer.sdt"; //$NON-NLS-1$
public static final String PACKAGE_ID = ModelerSdtPlugin.class.getPackage().getName();
/**
* Provides access to the plugin's log and to it's resources.
*/
private static final String I18N_NAME = PACKAGE_ID + ".i18n"; //$NON-NLS-1$
public static final PluginUtil Util = new PluginUtilImpl(PLUGIN_ID, I18N_NAME, ResourceBundle.getBundle(I18N_NAME));
/** Shared resource set containing the Teiid Designer built-in types resource */
protected static ResourceSet globalResourceSet;
/** Shared resource set containing the Teiid Designer built-in types resource */
protected static Resource builtInTypesResource;
/** Logical URI of the Teiid Designer built-in types resource */
protected static URI BUILTIN_DATATYPES_URI = URI.createURI(DatatypeConstants.BUILTIN_DATATYPES_URI);
// The shared instance.
private static ModelerSdtPlugin plugin = new ModelerSdtPlugin();
protected URL baseURL;
public static boolean DEBUG = false;
// ==================================================================================
// C O N S T R U C T O R S
// ==================================================================================
/**
* The constructor.
*/
public ModelerSdtPlugin() {
}
// ==================================================================================
// P U B L I C M E T H O D S
// ==================================================================================
/**
* @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext)
* @since 4.3.2
*/
@Override
public void start( BundleContext context ) throws Exception {
super.start(context);
plugin = this;
// This must be called to initialize the platform logger!
((PluginUtilImpl)Util).initializePlatformLogger(this);
}
/**
* This method is called when the plug-in is stopped
*/
@Override
public void stop( BundleContext context ) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance.
*
* @since 4.0
*/
public static ModelerSdtPlugin getDefault() {
return plugin;
}
/**
* Return the shared resource set containing the Teiid Designer built-in types resource
*
* @return
* @since 4.3
*/
public static synchronized ResourceSet getGlobalResourceSet() {
if (globalResourceSet == null) {
globalResourceSet = createResourceSet();
loadBuiltInTypesResource(globalResourceSet);
}
return globalResourceSet;
}
/**
* Return the shared Teiid Designer built-in types resource
*
* @return
* @since 4.3
*/
public static synchronized Resource getBuiltInTypesResource() {
if (builtInTypesResource == null) {
builtInTypesResource = getGlobalResourceSet().getResource(BUILTIN_DATATYPES_URI, true);
}
return builtInTypesResource;
}
// ==================================================================================
// P R O T E C T E D M E T H O D S
// ==================================================================================
protected static ResourceSet createResourceSet() {
ResourceSet result = new ResourceSetImpl();
Map map = result.getResourceFactoryRegistry().getExtensionToFactoryMap();
if (!map.containsKey(StringConstants.XSD)) {
map.put(StringConstants.XSD, new XsdResourceFactory());
}
return result;
}
protected static void loadBuiltInTypesResource( final ResourceSet rs ) {
try {
String baseURL = ModelerSdtPlugin.getDefault().getBaseURL().getFile();
File baseFolder = new File(baseURL);
File xsdFile = new File(baseFolder, "cache/www.metamatrix.com/metamodels/builtInDataTypes.xsd"); //$NON-NLS-1$
File zipFile = new File(baseFolder, DatatypeConstants.DATATYPES_ZIP_FILE_NAME);
URI uri = null;
Resource r = null;
if (xsdFile.exists()) {
uri = URI.createFileURI(xsdFile.getAbsolutePath());
r = rs.getResource(uri, true);
addLogicalToPhysicalUriMapping(rs, r);
} else if (zipFile.exists()) {
InputStream is = null;
ZipFile archive = null;
try {
archive = new ZipFile(zipFile);
ZipEntry entry = archive.getEntry(DatatypeConstants.DATATYPES_MODEL_FILE_NAME);
if (entry != null) {
is = archive.getInputStream(entry);
xsdFile = new File(baseURL + DatatypeConstants.DATATYPES_MODEL_FILE_NAME);
FileUtils.write(is, xsdFile);
}
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
// Nothing to do
}
}
if (archive != null)
archive.close();
}
uri = URI.createFileURI(xsdFile.getAbsolutePath());
r = rs.getResource(uri, true);
addLogicalToPhysicalUriMapping(rs, r);
}
} catch (Throwable e) {
Object[] params = new Object[] {DatatypeConstants.DATATYPES_MODEL_FILE_NAME,
DatatypeConstants.DATATYPES_ZIP_FILE_NAME};
String msg = ModelerSdtPlugin.Util.getString("ModelerSdtPlugin.Error_loading_builtin_types_resource", params); //$NON-NLS-1$
Util.log(IStatus.ERROR, e, msg);
e.printStackTrace();
}
}
protected static void addLogicalToPhysicalUriMapping( final ResourceSet rs,
final Resource r ) {
CoreArgCheck.isNotNull(rs);
CoreArgCheck.isNotNull(r);
URI logicalURI = BUILTIN_DATATYPES_URI;
URI physicalURI = r.getURI();
rs.getURIConverter().getURIMap().put(logicalURI, physicalURI);
}
public URL getBaseURL() {
if (baseURL == null && plugin != null && plugin.getBundle() != null) {
try {
baseURL = FileLocator.resolve(plugin.getBundle().getEntry("/")); //$NON-NLS-1$
} catch (final IOException err) {
baseURL = null;
}
}
if (baseURL == null) {
try {
// Determine the base URL by looking for the plugin.properties file in the standard way.
Class theClass = getClass();
URL pluginPropertiesURL = theClass.getResource("plugin.properties"); //$NON-NLS-1$
if (pluginPropertiesURL == null) {
String className = theClass.getName();
int index = className.lastIndexOf("."); //$NON-NLS-1$
URL classURL = theClass.getResource((index == -1 ? className : className.substring(index + 1)) + ".class"); //$NON-NLS-1$
URI uri = URI.createURI(classURL.toString());
// Trim off the segements corresponding to the package nesting.
int count = 1;
for (int i = 0; (i = className.indexOf('.', i)) != -1; ++i) {
++count;
}
uri = uri.trimSegments(count);
// For an archive URI, check for the plugin.properties in the archive.
if (URI.isArchiveScheme(uri.scheme())) {
try {
// If we can open an input stream, then the plugin.properties is there, and we have a good base URL.
InputStream inputStream = new URL(uri.appendSegment("plugin.properties").toString()).openStream(); //$NON-NLS-1$
inputStream.close();
baseURL = new URL(uri.toString());
} catch (IOException exception) {
// If the plugin.properties isn't within the root of the archive,
// create a new URI for the folder location of the archive,
// so we can look in the folder that contains it.
uri = URI.createURI(uri.authority()).trimSegments(1);
}
}
// If we didn't find the plugin.properties in the usual place nor in the archive...
if (baseURL == null) {
// Trim off the "bin" or "runtime" segement.
String lastSegment = uri.lastSegment();
if ("bin".equals(lastSegment) || "runtime".equals(lastSegment)) { //$NON-NLS-1$ //$NON-NLS-2$
uri = uri.trimSegments(1);
}
uri = uri.appendSegment("plugin.properties"); //$NON-NLS-1$
try {
// If we can open an input stream, then the plugin.properties is in the folder,
// and we have a good base URL.
InputStream inputStream = new URL(uri.toString()).openStream();
inputStream.close();
baseURL = new URL(uri.trimSegments(1).toString() + "/"); //$NON-NLS-1$
} catch (IOException exception) {
}
}
// If we still don't have a good base URL, complain about it.
if (baseURL == null) {
String resourceName = index == -1 ? "plugin.properties" : className.substring(0, index + 1).replace('.', '/') //$NON-NLS-1$
+ "plugin.properties"; //$NON-NLS-1$
throw new MissingResourceException("Missing properties: " + resourceName, theClass.getName(), //$NON-NLS-1$
"plugin.properties"); //$NON-NLS-1$
}
} else {
baseURL = new URL(URI.createURI(pluginPropertiesURL.toString()).trimSegments(1).toString() + "/"); //$NON-NLS-1$
}
} catch (IOException exception) {
throw new WrappedException(exception);
}
}
return baseURL;
}
}