blob: e56e303feee459a8316d744a836400257fa1fd25 [file] [log] [blame]
// Utility.java
package org.eclipse.stem.core;
/*******************************************************************************
* Copyright (c) 2008 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.core.scenario.ScenarioInitializationException;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
/**
* This class contains common utility methods used in STEM.
*/
public class Utility {
/**
* EMF Save Options, for properly serializing to UTF-8
*/
private static final Map<String,String> EMF_SAVE_OPTIONS
= new HashMap<String,String>();
static {
EMF_SAVE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
}
/**
* Cached resource set
*/
public static ResourceSet resourceSet;
static {
resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("platform", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
}
/**
* @param identifableURI
* the {@link URI} of file with a serialized {@link Identifiable}
* @return the {@link Identifiable} de-serialized from the file, or
* <code>null</code> if an error occurred.
*/
public static Identifiable getIdentifiable(final URI identifableURI) {
Identifiable retValue = null;
try {
URI normalized = STEMURI.normalize(identifableURI);
Resource resource = null;
synchronized(resourceSet) { // Resource set is not thread safe
resource = resourceSet.getResource(normalized,
true);
if(resource.isModified()) {
resource.unload();
resource.load(null);
if(resource.getErrors().size() > 0) {
for(Resource.Diagnostic d: resource.getErrors())
CorePlugin.logError(d.getMessage(), new Exception());
}
}
} // Synchronized
EList<EObject>cont = resource.getContents();
if(cont.size() == 0) {
int maxretry = 10;
while(cont.size() == 0 && --maxretry > 0)
Thread.yield(); // allow other thread to load resource
if(cont.size() == 0) {
CorePlugin.logError(NLS.bind(Messages.Utility_UNABLE_TO_LOAD_CONTENT, new Object[] {normalized}), new Exception());
return null;
}
}
retValue = (Identifiable) cont.get(0);
} catch (final Exception e) {
CorePlugin.logError(NLS.bind(Messages.Utility_BAD_SERIALIZED_INSTANCE, new Object [] {identifableURI.toString()}),e);
retValue = null;
}
return retValue;
} // getIdentifiable
/**
* @param identifableURI
* the {@link URI} of file with a serialized {@link Identifiable}
* @return the {@link Identifiable} de-serialized from the file, or
* <code>null</code> if an error occurred.
*/
public static Identifiable getIdentifiableFromStream(final URI identifableURI, InputStream is, Map<String, Object>options, boolean binary) {
Identifiable retValue = null;
try {
URI normalized = STEMURI.normalize(identifableURI);
Resource resource = null;
ResourceSet rs = new ResourceSetImpl();
if(binary) {
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", STEMBinaryResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
rs.getResourceFactoryRegistry().getProtocolToFactoryMap().put("platform", STEMBinaryResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
} else {
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
rs.getResourceFactoryRegistry().getProtocolToFactoryMap().put("platform", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
}
resource = rs.createResource(normalized, null);
resource.unload();
resource.load(is, options);
if(resource.getErrors().size() > 0) {
for(Resource.Diagnostic d: resource.getErrors())
CorePlugin.logError(d.getMessage(), new Exception());
}
EList<EObject>cont = resource.getContents();
if(cont.size() == 0) {
int maxretry = 10;
while(cont.size() == 0 && --maxretry > 0)
Thread.yield(); // allow other thread to load resource
if(cont.size() == 0) {
CorePlugin.logError(NLS.bind(Messages.Utility_UNABLE_TO_LOAD_CONTENT, new Object[] {normalized}), new Exception());
return null;
}
}
retValue = (Identifiable) cont.get(0);
} catch (final Exception e) {
CorePlugin.logError(NLS.bind(Messages.Utility_BAD_SERIALIZED_INSTANCE, new Object [] {identifableURI.toString()}),e);
retValue = null;
}
return retValue;
} // getIdentifiable
/**
*
*/
public static Resource getResource(final URI identifableURI) {
try {
URI normalized = STEMURI.normalize(identifableURI);
Resource resource = null;
synchronized(resourceSet) { // Resource set is not thread safe
resource = resourceSet.getResource(normalized,
true);
if(resource.isModified()) {
resource.unload();
resource.load(null);
if(resource.getErrors().size() > 0) {
for(Resource.Diagnostic d: resource.getErrors())
CorePlugin.logError(d.getMessage(), new Exception());
}
}
} // Synchronized
return resource;
} catch (final Exception e) {
CorePlugin.logError(NLS.bind(Messages.Utility_BAD_SERIALIZED_INSTANCE, new Object [] {identifableURI.toString()}),e);
}
return null;
} // getIdentifiable
/**
* @param identifableURI
* the {@link URI} of file with a serialized {@link Identifiable}
* @return the {@link Identifiable} de-serialized from the file, or
* <code>null</code> if an error occurred.
*/
public static Identifiable getIdentifiableIgnoreException(final URI identifableURI) {
Identifiable retValue = null;
try {
URI normalized = STEMURI.normalize(identifableURI);
Resource resource = null;
ResourceSet rs = new ResourceSetImpl(); // This method uses it's own resource set
resource = rs.getResource(normalized, true);
EList<EObject>cont = resource.getContents();
if(cont.size() == 0) {
int maxretry = 10;
while(cont.size() == 0 && --maxretry > 0)
Thread.yield(); // allow other thread to load resource
if(cont.size() == 0) {
return null;
}
}
retValue = (Identifiable) cont.get(0);
} catch (final Exception e) {
retValue = null;
}
return retValue;
} // getIdentifiable
/**
* Serialize an {@link Identifiable}
* <p>
* Note this code is copied from
* org.eclipse.stem.internal.data.records.Record. That method should be
* removed and this one used instead.
*
* @param identifiable
* the {@link Identifiable} to be serialized.
* @param serializationURI
* the {@link URI} that specifies where the {@link Identifiable}
* is to be serialized.
* @throws IOException
* if there is a problem serializing the {@link Identifiable}
*/
public static void serializeIdentifiable(final Identifiable identifiable,
final URI serializationURI) throws IOException {
final List<Identifiable> set = new ArrayList<Identifiable>();
set.add(identifiable);
serializeIdentifiables(set, serializationURI);
} // serializeIdentifiable
/**
* Serialize an {@link Identifiable}
*
* @param identifiable
* the {@link Identifiable} to be serialized.
* @param serializationURI
* the {@link URI} that specifies where the {@link Identifiable}
* is to be serialized.
* @throws IOException
* if there is a problem serializing the {@link Identifiable}
*/
public static void serializeIdentifiables(final List<Identifiable> identifiables,
final URI serializationURI) throws IOException {
// This code could be running "stand alone" (i.e., not within eclipse),
// thus the default factories for the extensions are not registered as
// they would from their extension of
// "org.eclipse.emf.ecore.extension_parser". So we need to register them
// here.
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*", //$NON-NLS-1$
STEMXMIResourceFactoryImpl.INSTANCE);
Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap().put(
"platform", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
final ResourceSet rs = new ResourceSetImpl();
rs.getResourceFactoryRegistry().getExtensionToFactoryMap()
.put("*", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
rs.getResourceFactoryRegistry().getProtocolToFactoryMap().put(
"platform", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
final Resource resource = rs.createResource(serializationURI);
for (Identifiable id : identifiables) {
resource.getContents().add(id);
}
resource.save(EMF_SAVE_OPTIONS);
} // serializeIdentifiable
/**
* Serialize an {@link Identifiable}
*
* @param identifiable
* the {@link Identifiable} to be serialized.
* @param serializationURI
* the {@link URI} that specifies where the {@link Identifiable}
* is to be serialized.
* @param stream the stream to serialize to
* @throws IOException
* if there is a problem serializing the {@link Identifiable}
*/
public static void serializeIdentifiableToStream(Identifiable identifiable,
final URI serializationURI, OutputStream stream, Map<String,Object>options, boolean binary) throws IOException {
// This code could be running "stand alone" (i.e., not within eclipse),
// thus the default factories for the extensions are not registered as
// they would from their extension of
// "org.eclipse.emf.ecore.extension_parser". So we need to register them
// here.
final ResourceSet resourceSet = new ResourceSetImpl();
if(binary) {
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
.put("*", STEMBinaryResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put(
"platform", STEMBinaryResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
} else {
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
.put("*", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put(
"platform", STEMXMIResourceFactoryImpl.INSTANCE); //$NON-NLS-1$
}
final Resource resource = resourceSet.createResource(serializationURI);
resource.getContents().add(identifiable);
resource.save(stream, options);
} // serializeIdentifiable
/**
* Common method for determining the geographic level of a geographic key (last segment of a URI)
* @param key
* @return the level of the key
*/
public static int keyLevel(final String key) {
// null means unspecified and truly global for population models.
if(key == null || key.trim().equals("")) return -2; //$NON-NLS-1$
// ZZZ is special, it means the world
if(key.equalsIgnoreCase("ZZZ")) return -1; //$NON-NLS-1$
int level = 0;
int start = 0;
for (int temp = key.indexOf("-"); temp > 0;) { //$NON-NLS-1$
level++;
start += temp + 1;
temp = key.substring(start).indexOf("-"); //$NON-NLS-1$
} // for
return level;
} // keyLevel
/**
* Do the processing required to handle a {@link Exception}
*
* @param scenario
* the {@link Scenario} that caused the {@link Exception}
* @param name
* the name to use in error messages that identifies the source
* of the {@link Scenario}
* @param promptUser
* if <code>true</code> then present the user with a dialog box
* explaining the message.
* @param e
* the {@link Exception}
*/
static public void handleException(final String message, boolean promptUser, final ScenarioInitializationException se) {
CorePlugin.logError(se.getErrorMessage(), se.getOriginalException());
// Prompt the user?
if (promptUser) {
if(Display.getDefault() != null)
Display.getDefault().syncExec(new Runnable() {
public void run() {
try {
final IWorkbenchWindow window = PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
// final IStatus warning = new Status(IStatus.WARNING,
// CorePlugin.PLUGIN_ID, 1, message, null);
// ErrorDialog.openError(window.getShell(), null, null,
// warning);
String [] labels = new String[1];
labels[0] = Messages.Utility_OKAY;
MessageDialog dialog = new MessageDialog(window.getShell(), "Warning", null, message, //$NON-NLS-1$
MessageDialog.ERROR, labels, 0) {
// @Override
// protected void buttonPressed(int buttonId) {
// if(buttonId == 1)
// PlatformUI.getWorkbench().getHelpSystem().displayHelp("org.eclipse.stem.doc.invalidnesting_contextid");
// else
// super.buttonPressed(buttonId);
// }
};
dialog.open();
} catch(Exception e) {
// If we get this exception, it is because we're not running in
// eclipse.
}
} // run
});
// Yes
} // if
}
} // Utility