blob: 747211a9b81657ee1caec60749b52a822a310cb2 [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.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.stem.core.common.Identifiable;
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");
}
public final static String NESTING_WARNING = "Warning, possible scenario initialization problem detected. Check the nesting of your models";
public final static String URI_WARNING = "Warning, URI does not exist in Graph. Check the infector/innoculator URIs your models. ";
/**
* Cached resource set
*/
public static ResourceSet resourceSet;
static {
resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", STEMXMIResourceFactoryImpl.INSTANCE);
resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("platform", STEMXMIResourceFactoryImpl.INSTANCE);
}
/**
* @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 = 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());
}
}
EList<EObject>cont = resource.getContents();
if(cont.size() == 0) {
int maxretry = 10;
while(cont.size() == 0)
Thread.yield(); // allow other thread to load resource
if(cont.size() == 0)
CorePlugin.logError("Unable to load content for resource "+normalized, new Exception());
}
retValue = (Identifiable) cont.get(0);
} catch (final Exception e) {
CorePlugin.logError(
"The serialized instance of an Identifiable at \""
+ identifableURI.toString()
+ "\" was not found or was of the wrong format", 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("*",
STEMXMIResourceFactoryImpl.INSTANCE);
Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap().put(
"platform", STEMXMIResourceFactoryImpl.INSTANCE);
final ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
.put("*", STEMXMIResourceFactoryImpl.INSTANCE);
resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put(
"platform", STEMXMIResourceFactoryImpl.INSTANCE);
final Resource resource = resourceSet.createResource(serializationURI);
for (Identifiable id : identifiables) {
resource.getContents().add(id);
}
resource.save(EMF_SAVE_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;
// ZZZ is special, it means the world
if(key.equalsIgnoreCase("ZZZ")) return -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
/**
* Displays a warning that the scenario composition may be invalid.
* For example the graph nesting within a simulation may be invalid
* An infector or inoculator may point to a node that does not exist.
* @param message
*/
public static void displayScenarioCompositionWarning(final String message) {
try {
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[2];
labels[1] = "Help";
labels[0] = "Okay";
MessageDialog dialog = new MessageDialog(window.getShell(), "Warning", null, message,
MessageDialog.WARNING, 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
});
else CorePlugin.logError(message, null);
} catch (final Error ncdfe) {
// Empty
} // catch
}
} // Utility