blob: 0cd9a22a614ca4f348a98850e244b9140e7661fd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* 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:
* Pierre Allard,
* Regent L'Archeveque,
* Olivier L. Larouche - initial API and implementation
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.common.emf.impl;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.measure.unit.Unit;
import org.eclipse.apogy.common.ApogyCommonFacade;
import org.eclipse.apogy.common.emf.AbstractFeatureListNode;
import org.eclipse.apogy.common.emf.AbstractFeatureNode;
import org.eclipse.apogy.common.emf.AbstractFeatureSpecifier;
import org.eclipse.apogy.common.emf.AbstractFeatureTreeNode;
import org.eclipse.apogy.common.emf.AbstractRootNode;
import org.eclipse.apogy.common.emf.ApogyCommonEMFFacade;
import org.eclipse.apogy.common.emf.ApogyCommonEMFPackage;
import org.eclipse.apogy.common.emf.EClassFilter;
import org.eclipse.apogy.common.emf.EMFAnnotationConstants;
import org.eclipse.apogy.common.emf.ListFeatureNode;
import org.eclipse.apogy.common.emf.ListRootNode;
import org.eclipse.apogy.common.emf.Named;
import org.eclipse.apogy.common.emf.Ranges;
import org.eclipse.apogy.common.emf.Startable;
import org.eclipse.apogy.common.emf.Timed;
import org.eclipse.apogy.common.emf.TreeFeatureNode;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.URIConverter.ReadableInputStream;
import org.eclipse.emf.ecore.resource.URIConverter.WriteableOutputStream;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ApogyCommonEMFFacadeCustomImpl extends ApogyCommonEMFFacadeImpl {
private static final Logger Logger = LoggerFactory.getLogger(ApogyCommonEMFFacadeImpl.class);
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT_STRING_EDEFAULT);
private static List<EClass> availableTypes = null;
@Override
public void setDateFormatString(String newDateFormatString) {
// Validate that the date format string is valid.
boolean stringValid = validateDateFormatString(newDateFormatString);
if (stringValid) {
this.simpleDateFormat = new SimpleDateFormat(newDateFormatString);
super.setDateFormatString(newDateFormatString);
} else {
throw new RuntimeException("Invalid Date format string specified <" + newDateFormatString + "> !");
}
}
@Override
public List<EClass> getAllAvailableEClasses() {
try {
if (availableTypes == null) {
availableTypes = new ArrayList<EClass>();
List<EPackage> ePackages = new ArrayList<EPackage>();
List<String> ePackagesDescriptor = new ArrayList<String>();
Set<Entry<String, Object>> packageSet = EPackage.Registry.INSTANCE.entrySet();
for (Entry<String, Object> mp_entry : packageSet) {
Object val = mp_entry.getValue();
if (val instanceof EPackage) {
ePackages.add((EPackage) val);
} else if (val instanceof EPackage.Descriptor) {
// instance of EPackageDescriptor, therefore we need to
// get that package
// in a seperate call because we will get a
// ConcurrentModification (since we are already
// iterating over the Registry hashmap)
ePackagesDescriptor.add(mp_entry.getKey());
}
}
// recover uninstantiate package from their description
// FIXME : This is causing a crash when installed but runs fine when in in
// workspace !
for (String description : ePackagesDescriptor) {
try {
if (description != null) {
System.err.println("Loading EPackage : " + description);
EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(description);
ePackages.add(ePackage);
}
} catch (Throwable t) {
Logger.error(t.getMessage(), t);
}
}
// retrieve EClass from EPackages
for (EPackage iPackage : ePackages) {
if (iPackage != null) {
for (EObject eObj : iPackage.eContents()) {
if (!(eObj instanceof EClass)) {
continue;
}
EClass eClass = (EClass) eObj;
availableTypes.add(eClass);
}
}
}
}
} catch (Exception e) {
Logger.error(e.getMessage(), e);
}
return availableTypes;
}
@Override
public List<EClass> getAllSubEClasses(final EClass superClass) {
List<EClass> classes = null;
if (superClass != null) {
EClassFilter filter = new EClassFilter() {
@Override
public boolean filter(EClass eClass) {
boolean result = superClass.isSuperTypeOf(eClass) && !eClass.isInterface() && !eClass.isAbstract();
return result;
}
};
List<EClass> list = ApogyCommonEMFFacade.INSTANCE.getAllAvailableEClasses();
classes = ApogyCommonEMFFacade.INSTANCE.filterEClasses(list, filter);
}
return classes;
}
@Override
public SortedSet<EClass> sortAlphabetically(List<EClass> eClasses) {
SortedSet<EClass> sortedTypes = new TreeSet<EClass>(new Comparator<EClass>() {
@Override
public int compare(EClass o1, EClass o2) {
try {
if (o1.getName().compareTo(o2.getName()) == 0) {
return o1.getInstanceClassName().compareTo(o2.getInstanceClassName());
} else {
return o1.getName().compareTo(o2.getName());
}
} catch (Exception e) {
Logger.error(e.getMessage(), e);
return -1;
}
}
});
for (EClass eClass : eClasses) {
// Keep only classes that have proper names and instance class
// names.
if ((eClass != null) && (eClass.getName() != null) && (eClass.getInstanceClassName() != null)) {
sortedTypes.add(eClass);
}
}
return sortedTypes;
}
@Override
public List<EOperation> getAllAvailableEOperations(EClass eClass) {
return eClass.getEAllOperations();
}
@Override
public SortedSet<EOperation> sortEOperationsAlphabetically(List<EOperation> eOperations) {
SortedSet<EOperation> sortedTypes = new TreeSet<EOperation>(new Comparator<EOperation>() {
@Override
public int compare(EOperation o1, EOperation o2) {
try {
return o1.getName().compareTo(o2.getName());
} catch (Exception e) {
Logger.error(e.getMessage(), e);
return -1;
}
}
});
for (EOperation eOperation : eOperations) {
// Keep only eOperations that have proper names
if ((eOperation != null) && (eOperation.getName() != null)) {
sortedTypes.add(eOperation);
}
}
return sortedTypes;
}
public String getDocumentation(EAnnotation eAnnotation) {
if (eAnnotation != null) {
EMap<String, String> map = eAnnotation.getDetails();
if (map != null) {
String rawDocumentation = map.get("documentation");
if (rawDocumentation != null) {
return stripCommentDelimiters(rawDocumentation);
}
}
}
return null;
}
@Override
public String getDocumentation(EModelElement eModelElement) {
return stripCommentDelimiters(
getEAnnotationDetailValue(getGenModelEAnnotation(eModelElement), "documentation"));
}
@Override
public String getDocumentation(EParameter eParameter) {
String fullDocumentation = "";
String name = "Name : " + eParameter.getName();
String type = "Type : " + eParameter.getEType().getName();
String description = stripCommentDelimiters(
getEAnnotationDetailValue(getGenModelEAnnotation(eParameter), "documentation"));
if (description == null || description.length() == 0) {
description = "Description : N/A";
} else {
description = "Description : " + description;
}
String units = "" + ApogyCommonEMFFacade.INSTANCE.getEngineeringUnits(eParameter);
if (units == null || units.length() == 0) {
units = "Units : None";
} else {
units = "Units : " + units;
}
// Out Of range
Number oorMin = ApogyCommonEMFFacade.INSTANCE.getOutOfRangeMinValue(eParameter);
Number oorMax = ApogyCommonEMFFacade.INSTANCE.getOutOfRangeMaxValue(eParameter);
String oorLimits = "Out Of Range Limits : " + getRangeString(oorMin, oorMax);
// Alarm range
Number alarmMin = ApogyCommonEMFFacade.INSTANCE.getAlarmMinValue(eParameter);
Number alarmMax = ApogyCommonEMFFacade.INSTANCE.getAlarmMaxValue(eParameter);
String alarmsLimits = "Alarms Limits : " + getRangeString(alarmMin, alarmMax);
// Warning
Number warningMin = ApogyCommonEMFFacade.INSTANCE.getWarningMinValue(eParameter);
Number warningMax = ApogyCommonEMFFacade.INSTANCE.getWarningMaxValue(eParameter);
String warningLimits = "Warning Limits : " + getRangeString(warningMin, warningMax);
fullDocumentation += name + "\n";
fullDocumentation += type + "\n";
fullDocumentation += description + "\n";
fullDocumentation += units + "\n";
fullDocumentation += oorLimits + "\n";
fullDocumentation += alarmsLimits + "\n";
fullDocumentation += warningLimits + "\n";
return fullDocumentation;
}
@Override
public Unit<?> getEngineeringUnits(ETypedElement eTypedElement) {
Unit<?> unit = null;
// Gets the string defining the units.
String unitsAsString = getEngineeringUnitsAsString(eTypedElement);
if (unitsAsString != null) {
try {
unit = Unit.valueOf(unitsAsString);
} catch (Throwable t) {
Logger.warn("No units found for <" + unitsAsString + "> !", t);
}
}
return unit;
}
@Override
public String getEngineeringUnitsAsString(ETypedElement eTypedElement) {
return getEAnnotationDetailValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_ENGINEERING_UNITS);
}
@Override
public Double getValueUpdateRate(ETypedElement eTypedElement) {
Number number = getEAnnotationDetailNumberValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_UPDATE_RATE);
return number == null ? -1 : number.doubleValue();
}
@Override
public String getWarningOCLExpression(ETypedElement eTypedElement) {
return getEAnnotationDetailValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_WARNING_RANGE_OCL_EXPRESSION);
}
@Override
public String getAlarmOCLExpression(ETypedElement eTypedElement) {
return getEAnnotationDetailValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_ALARM_RANGE_OCL_EXPRESSION);
}
@Override
public String getOutOfRangeOCLExpression(ETypedElement eTypedElement) {
return getEAnnotationDetailValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_OUTSIDE_RANGE_OCL_EXPRESSION);
}
@Override
public Number getWarningMinValue(ETypedElement eTypedElement) {
return getEAnnotationDetailNumberValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_WARNING_RANGE_MIN_VALUE);
}
@Override
public Number getWarningMaxValue(ETypedElement eTypedElement) {
return getEAnnotationDetailNumberValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_WARNING_RANGE_MAX_VALUE);
}
@Override
public Number getAlarmMinValue(ETypedElement eTypedElement) {
return getEAnnotationDetailNumberValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_ALARM_RANGE_MIN_VALUE);
}
@Override
public Number getAlarmMaxValue(ETypedElement eTypedElement) {
return getEAnnotationDetailNumberValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_ALARM_RANGE_MAX_VALUE);
}
@Override
public Number getOutOfRangeMinValue(ETypedElement eTypedElement) {
return getEAnnotationDetailNumberValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_OUTSIDE_RANGE_MIN_VALUE);
}
@Override
public Number getOutOfRangeMaxValue(ETypedElement eTypedElement) {
return getEAnnotationDetailNumberValue(getApogyEAnnotation(eTypedElement),
EMFAnnotationConstants.ANNOTATION_OUTSIDE_RANGE_MAX_VALUE);
}
@Override
public Ranges getRange(ETypedElement eTypedElement, Object value) {
if (value instanceof Number) {
Number number = (Number) value;
// Check for violation for minimum values
// Check if the value is below the OutOfRange minimum.
Number outOfRangeMin = getOutOfRangeMinValue(eTypedElement);
if (outOfRangeMin != null && number.doubleValue() <= outOfRangeMin.doubleValue()) {
return Ranges.OUT_OF_RANGE;
}
// Check if the value is below the Alarm minimum.
Number alarmMin = getAlarmMinValue(eTypedElement);
if (alarmMin != null && number.doubleValue() <= alarmMin.doubleValue()) {
return Ranges.ALARM;
}
// Check if the value is below the Warning minimum.
Number warningMin = getWarningMinValue(eTypedElement);
if (warningMin != null && number.doubleValue() <= warningMin.doubleValue()) {
return Ranges.WARNING;
}
// Check for violation for maximum values
// Check if the value is above the OutOfRange maximum.
Number outOfRangeMax = getOutOfRangeMaxValue(eTypedElement);
if (outOfRangeMax != null && number.doubleValue() >= outOfRangeMax.doubleValue()) {
return Ranges.OUT_OF_RANGE;
}
// Check if the value is above the Alarm maximum.
Number alarmMax = getAlarmMaxValue(eTypedElement);
if (alarmMax != null && number.doubleValue() >= alarmMax.doubleValue()) {
return Ranges.ALARM;
}
// Check if the value is above the Warning maximum.
Number warningMax = getWarningMaxValue(eTypedElement);
if (warningMax != null && number.doubleValue() >= warningMax.doubleValue()) {
return Ranges.WARNING;
}
// If we got to here, either we are NOMINAL or no Ranges were
// defined.
if (warningMin != null || warningMax != null || alarmMin != null || alarmMax != null
|| outOfRangeMin != null || outOfRangeMax != null) {
return Ranges.NOMINAL;
} else {
return Ranges.UNKNOWN;
}
} else {
return Ranges.UNKNOWN;
}
}
@Override
public String getFullDescription(ETypedElement eTypedElement) {
String fullDocumentation = "";
String description = "Description : " + ApogyCommonEMFFacade.INSTANCE.getDocumentation(eTypedElement);
String units = "Units : " + ApogyCommonEMFFacade.INSTANCE.getEngineeringUnits(eTypedElement);
// Out Of range
Number oorMin = ApogyCommonEMFFacade.INSTANCE.getOutOfRangeMinValue(eTypedElement);
Number oorMax = ApogyCommonEMFFacade.INSTANCE.getOutOfRangeMaxValue(eTypedElement);
String oorLimits = "Out Of Range Limits : " + getRangeString(oorMin, oorMax);
// Alarm range
Number alarmMin = ApogyCommonEMFFacade.INSTANCE.getAlarmMinValue(eTypedElement);
Number alarmMax = ApogyCommonEMFFacade.INSTANCE.getAlarmMaxValue(eTypedElement);
String alarmsLimits = "Alarms Limits : " + getRangeString(alarmMin, alarmMax);
// Warning
Number warningMin = ApogyCommonEMFFacade.INSTANCE.getWarningMinValue(eTypedElement);
Number warningMax = ApogyCommonEMFFacade.INSTANCE.getWarningMaxValue(eTypedElement);
String warningLimits = "Warning Limits : " + getRangeString(warningMin, warningMax);
fullDocumentation += description + "\n";
fullDocumentation += units + "\n";
fullDocumentation += oorLimits + "\n";
fullDocumentation += alarmsLimits + "\n";
fullDocumentation += warningLimits + "\n";
return fullDocumentation;
}
private String getRangeString(Number min, Number max) {
String rangeString = "";
if (min != null && max != null) {
rangeString = min.toString() + " > value > " + max.toString();
} else if (min != null && max == null) {
rangeString = min.toString() + " > value";
} else if (min == null && max != null) {
rangeString = "value > " + max.toString();
} else {
rangeString = "N/A";
}
return rangeString;
}
@Override
public String getAncestriesString(AbstractFeatureNode abstractFeatureNode) {
String result = "";
List<AbstractFeatureNode> ancestries = getAncestries(abstractFeatureNode);
Iterator<AbstractFeatureNode> it = ancestries.iterator();
while (it.hasNext()) {
AbstractFeatureNode node = it.next();
if (node instanceof AbstractFeatureSpecifier) {
AbstractFeatureSpecifier abstractFeatureSpecifier = (AbstractFeatureSpecifier) node;
if (abstractFeatureSpecifier.getStructuralFeature() != null) {
result += abstractFeatureSpecifier.getStructuralFeature().getName();
if (abstractFeatureSpecifier.isMultiValued()) {
result += "[" + abstractFeatureSpecifier.getIndex() + "]";
}
if (it.hasNext()) {
result += ".";
}
}
}
}
return result;
}
@Override
public AbstractRootNode getFeatureRoot(AbstractFeatureNode abstractFeatureNode) {
if (abstractFeatureNode instanceof AbstractRootNode) {
return (AbstractRootNode) abstractFeatureNode;
} else {
AbstractRootNode root = null;
AbstractFeatureNode node = abstractFeatureNode;
while (root == null && node != null) {
if (node instanceof AbstractRootNode) {
root = (AbstractRootNode) node;
} else if (node instanceof ListFeatureNode) {
node = ((ListFeatureNode) node).getParent();
} else if (node instanceof TreeFeatureNode) {
node = ((TreeFeatureNode) node).getParent();
}
}
return root;
}
}
@Override
public List<AbstractFeatureNode> getAncestries(AbstractFeatureNode abstractFeatureNode) {
List<AbstractFeatureNode> ancestries = new ArrayList<AbstractFeatureNode>();
AbstractFeatureNode feature = abstractFeatureNode;
while (feature != null) {
ancestries.add(0, feature);
if (feature instanceof ListFeatureNode) {
feature = ((ListFeatureNode) feature).getParent();
} else if (feature instanceof TreeFeatureNode) {
feature = ((TreeFeatureNode) feature).getParent();
} else if (feature instanceof AbstractRootNode) {
feature = null;
}
}
return ancestries;
}
@Override
public List<AbstractFeatureNode> getDescendants(AbstractFeatureNode abstractFeatureNode) {
List<AbstractFeatureNode> descendants = new ArrayList<AbstractFeatureNode>();
// Explore the node childrens
AbstractFeatureNode node = abstractFeatureNode;
if (node instanceof AbstractFeatureTreeNode) {
getDescendants((AbstractFeatureTreeNode) node, descendants);
} else if (node instanceof AbstractFeatureListNode) {
AbstractFeatureListNode abstractFeatureListNode = (AbstractFeatureListNode) node;
getDescendants(abstractFeatureListNode, descendants);
}
return descendants;
}
private void getDescendants(AbstractFeatureTreeNode abstractFeatureTreeNode,
final List<AbstractFeatureNode> descendants) {
// Adds children of the node to the list.
descendants.addAll(abstractFeatureTreeNode.getChildren());
// Goes through the list of children
for (AbstractFeatureTreeNode child : abstractFeatureTreeNode.getChildren()) {
getDescendants(child, descendants);
}
}
private void getDescendants(AbstractFeatureListNode abstractFeatureListNode,
final List<AbstractFeatureNode> descendants) {
// Adds children of the node to the list.
if (abstractFeatureListNode.getChild() != null) {
descendants.add(abstractFeatureListNode.getChild());
getDescendants(abstractFeatureListNode.getChild());
}
}
@Override
public List<EStructuralFeature> getChildEStructuralFeatures(AbstractFeatureNode abstractFeatureNode) {
List<EStructuralFeature> features = new ArrayList<EStructuralFeature>();
if (abstractFeatureNode instanceof AbstractRootNode) {
AbstractRootNode abstractRootNode = (AbstractRootNode) abstractFeatureNode;
if (abstractRootNode.getSourceClass() instanceof EClass) {
EClass eClass = abstractRootNode.getSourceClass();
features.addAll(eClass.getEAllStructuralFeatures());
}
} else if (abstractFeatureNode instanceof AbstractFeatureSpecifier) {
AbstractFeatureSpecifier abstractFeatureSpecifier = (AbstractFeatureSpecifier) abstractFeatureNode;
EStructuralFeature eStructuralFeature = abstractFeatureSpecifier.getStructuralFeature();
if (eStructuralFeature != null) {
if (eStructuralFeature.getEType() instanceof EClass) {
EClass eClass = (EClass) eStructuralFeature.getEType();
features.addAll(eClass.getEAllStructuralFeatures());
}
}
}
return features;
}
@Override
public Object resolve(EObject sourceObject, AbstractFeatureNode abstractFeatureNode) {
AbstractRootNode featureRoot = getFeatureRoot(abstractFeatureNode);
Object result = null;
// Check that the specified source object is compatible with the tree
// root.
if (featureRoot.getSourceClass().isSuperTypeOf(sourceObject.eClass())) {
// Explore the ancestors of the abstractFeatureNode
List<AbstractFeatureNode> ancestries = getAncestries(abstractFeatureNode);
EObject eObject = sourceObject;
Iterator<AbstractFeatureNode> it = ancestries.iterator();
while (it.hasNext() && (eObject != null)) {
AbstractFeatureNode node = it.next();
if (node instanceof AbstractFeatureSpecifier) {
AbstractFeatureSpecifier featureSpecifier = (AbstractFeatureSpecifier) node;
Object object = null;
if (featureSpecifier.isMultiValued()) {
BasicEList<?> list = (BasicEList<?>) eObject.eGet(featureSpecifier.getStructuralFeature());
// Check the index of the FeatureNode is valid
if (featureSpecifier.getIndex() >= 0 && featureSpecifier.getIndex() < list.size()) {
object = list.get(featureSpecifier.getIndex());
} else {
object = null;
}
} else {
object = eObject.eGet(featureSpecifier.getStructuralFeature());
}
// If the end of the list has not been reached yet
if (it.hasNext()) {
if (object instanceof EObject) {
eObject = (EObject) object;
} else {
eObject = null;
}
} else {
result = object;
}
}
}
return result;
} else {
return null;
}
}
@Override
public void setValue(EObject sourceObject, AbstractFeatureNode abstractFeatureNode, Object value) {
if (abstractFeatureNode instanceof AbstractFeatureSpecifier) {
List<AbstractFeatureNode> ancestries = getAncestries(abstractFeatureNode);
ancestries.remove(abstractFeatureNode);
EObject eObject = sourceObject;
Iterator<AbstractFeatureNode> it = ancestries.iterator();
while (it.hasNext()) {
AbstractFeatureNode node = it.next();
if (node instanceof AbstractFeatureSpecifier) {
AbstractFeatureSpecifier specifier = (AbstractFeatureSpecifier) node;
eObject = (EObject) eObject.eGet(specifier.getStructuralFeature());
}
}
if (eObject != null) {
AbstractFeatureSpecifier s = (AbstractFeatureSpecifier) abstractFeatureNode;
eObject.eSet(s.getStructuralFeature(), value);
}
}
}
@Override
public boolean isResolved(EObject sourceObject, AbstractFeatureNode abstractFeatureNode) {
boolean result = true;
AbstractRootNode featureRoot = getFeatureRoot(abstractFeatureNode);
// Check that the specified source object is compatible with the tree
// root.
if (featureRoot.getSourceClass().isSuperTypeOf(sourceObject.eClass())) {
// Explore the ancestors of the abstractFeatureNode
List<AbstractFeatureNode> ancestries = getAncestries(abstractFeatureNode);
EObject eObject = sourceObject;
Iterator<AbstractFeatureNode> it = ancestries.iterator();
while (it.hasNext() && (eObject != null) && (result)) {
AbstractFeatureNode node = it.next();
if (node instanceof AbstractFeatureSpecifier) {
AbstractFeatureSpecifier featureSpecifier = (AbstractFeatureSpecifier) node;
Object object = null;
if (featureSpecifier.isMultiValued()) {
BasicEList<?> list = (BasicEList<?>) eObject.eGet(featureSpecifier.getStructuralFeature());
// Check the index of the FeatureNode is valid
if (featureSpecifier.getIndex() >= 0 && featureSpecifier.getIndex() < list.size()) {
object = list.get(featureSpecifier.getIndex());
} else {
object = null;
result = false;
}
} else {
object = eObject.eGet(featureSpecifier.getStructuralFeature());
}
// If the end of the list has not been reached yet
if (it.hasNext()) {
if (object instanceof EObject) {
eObject = (EObject) object;
} else {
result = false;
}
}
}
}
} else {
result = false;
}
return result;
}
@Override
public AbstractFeatureListNode getLeaf(ListRootNode listRootNode) {
AbstractFeatureListNode node = listRootNode;
if (node != null) {
while (node.getChild() != null) {
node = node.getChild();
}
}
return node;
}
@Override
public IFile getFile(Resource resource) {
if (resource != null) {
URI uri = resource.getURI();
uri = resource.getResourceSet().getURIConverter().normalize(uri);
String scheme = uri.scheme();
if ("platform".equals(scheme) && uri.segmentCount() > 1 && "resource".equals(uri.segment(0))) {
StringBuffer platformResourcePath = new StringBuffer();
for (int j = 1, size = uri.segmentCount(); j < size; ++j) {
platformResourcePath.append('/');
platformResourcePath.append(uri.segment(j));
}
return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformResourcePath.toString()));
}
}
return null;
}
@Override
public EList<EObject> getContent(URI uri) {
// Create a resource set to hold the resources.
ResourceSet resourceSet = new ResourceSetImpl();
// Register the appropriate resource factory to handle all file
// extensions.
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
.put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
Resource resource = resourceSet.getResource(uri, true);
return resource.getContents();
}
@Override
public SortedSet<Timed> sortTimed(Collection<Timed> timedCollection) {
SortedSet<Timed> sorted = new TreeSet<Timed>(new TimedComparator());
sorted.addAll(timedCollection);
return sorted;
}
@Override
public double getTimeSpan(Collection<Timed> timedCollection) {
double span = 0;
// Gets a sorted set first.
SortedSet<Timed> sorted = sortTimed(timedCollection);
if (sorted.size() > 1) {
Timed earliest = sorted.first();
Timed latest = sorted.last();
span = (latest.getTime().getTime() - earliest.getTime().getTime()) * 0.001;
}
return span;
}
@Override
public String getID(EObject eObject) {
String id = null;
if (eObject != null && eObject.eResource() instanceof XMIResource) {
id = ((XMIResource) eObject.eResource()).getID(eObject);
}
return id;
}
@Override
public EObject getEObjectById(ResourceSet resourceSet, String id) {
EObject result = null;
TreeIterator<Object> objects = EcoreUtil.getAllContents(resourceSet, true);
while (objects.hasNext() && result == null) {
Object object = objects.next();
if (object instanceof EObject) {
EObject eObject = (EObject) object;
if (getID(eObject).equals(id)) {
result = eObject;
}
}
}
return result;
}
@Override
public List<EObject> getEObjectsByType(EObject rootContainer, EClass eClass) {
List<EObject> list = new ArrayList<EObject>();
TreeIterator<Object> objects = EcoreUtil.getAllContents(rootContainer, true);
while (objects.hasNext()) {
Object object = objects.next();
if (object instanceof EObject) {
EObject eObject = (EObject) object;
if (eClass.isSuperTypeOf(eObject.eClass())) {
list.add(eObject);
}
}
}
return list;
}
@Override
public String getDefaultName(EObject eContainer, EObject eObject, ETypedElement typedElement) {
String name = "";
if (eObject != null) {
name = eObject.eClass().getName();
} else {
name = typedElement.getEType().getName();
}
/** If the container is a list */
if (typedElement.isMany()) {
int j = 1;
/** Find a name that is unique */
for (int i = 0; i < eContainer.eContents().size(); i++) {
if (eContainer.eContents().get(i) instanceof Named) {
Named named = (Named) eContainer.eContents().get(i);
if (named.getName() != null && named.getName().equals(name + "_" + Integer.toString(j))) {
j++;
i = 0;
}
}
}
return name + "_" + Integer.toString(j);
}
return name;
}
@Override
public List<EClass> getChildEClasses(EClass parentEClass) {
List<EClass> classes = null;
if (parentEClass != null) {
EClassFilter filter = new EClassFilter() {
@Override
public boolean filter(EClass eClass) {
boolean result = false;
EList<EReference> childReferences = parentEClass.getEAllContainments();
for (int i = 0; i < childReferences.size(); i++) {
if (childReferences.get(i).getEReferenceType() == eClass) {
result = true;
break;
}
}
return result && !eClass.isInterface() && !eClass.isAbstract();
}
};
List<EClass> list = ApogyCommonEMFFacade.INSTANCE.getAllAvailableEClasses();
classes = ApogyCommonEMFFacade.INSTANCE.filterEClasses(list, filter);
}
return classes;
}
@Override
public EList<EReference> getSettableEReferences(EObject eObject) {
EList<EReference> structuralFeatures = new BasicEList<EReference>();
structuralFeatures.addAll(eObject.eClass().getEAllContainments());
for (Iterator<EReference> ite = structuralFeatures.iterator(); ite.hasNext();) {
EReference eReference = ite.next();
final Object value = eObject.eGet(eReference);
if (value != null && !(value instanceof List)) {
ite.remove();
}
}
return structuralFeatures;
}
@Override
public String toString(List<? extends Named> nameds, String separator) {
String message = "";
Iterator<? extends Named> items = nameds.iterator();
while (items.hasNext()) {
Named named = items.next();
message = message + named.getName();
if (items.hasNext()) {
message = message + separator;
}
}
return message;
}
@Override
public String format(Date date) {
return this.simpleDateFormat.format(date);
}
@Override
public void stopAllStartables(EObject root) {
if (root instanceof Startable && ((Startable) root).isStarted()) {
TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(root);
if (domain != null) {
SetCommand command = new SetCommand(domain, root, ApogyCommonEMFPackage.Literals.STARTABLE__STARTED,
false);
domain.getCommandStack().execute(command);
} else {
((Startable) root).setStarted(false);
}
}
if (root.eContents() != null) {
for (EObject eObject : root.eContents()) {
stopAllStartables(eObject);
}
}
}
@Override
public String serializeEObject(EObject eObject, String uriID) {
EObject copyEObject = EcoreUtil.copy(eObject);
/** Place the copied element in a resourceSet */
ResourceSet resourceSet = new ResourceSetImpl();
Resource childResource = resourceSet.createResource(URI.createURI(uriID));
childResource.getContents().add(copyEObject);
StringWriter stringWriter = new StringWriter();
WriteableOutputStream os = new URIConverter.WriteableOutputStream(stringWriter, XMLResource.OPTION_ENCODING);
try {
childResource.save(os, Collections.EMPTY_MAP);
} catch (Throwable t) {
Logger.error("Failed to serialize : " + eObject, t);
}
return stringWriter.getBuffer().toString();
}
@Override
public EObject deserializeString(String str, String uriID) {
final ResourceSet resourceSet = new ResourceSetImpl();
Resource childResource = resourceSet.createResource(URI.createURI(uriID));
StringReader reader = new StringReader(str);
ReadableInputStream is = new URIConverter.ReadableInputStream(reader);
try {
childResource.load(is, Collections.EMPTY_MAP);
if (childResource.getContents().size() > 0) {
return childResource.getContents().get(0);
}
} catch (Throwable t) {
Logger.error("Failed to deserialize : " + uriID);
}
return null;
}
@Override
public EAnnotation getGenModelEAnnotation(EModelElement eModelElement) {
EAnnotation eAnnotation = null;
if (eModelElement != null) {
eAnnotation = eModelElement.getEAnnotation("http://www.eclipse.org/emf/2002/GenModel");
}
return eAnnotation;
}
@Override
public EAnnotation getApogyEAnnotation(EModelElement eModelElement) {
EAnnotation eAnnotation = null;
if (eModelElement != null) {
eAnnotation = eModelElement.getEAnnotation(ApogyCommonFacade.APOGY_SOURCE);
}
return eAnnotation;
}
@Override
public String getEAnnotationDetailValue(EAnnotation eAnnotation, String key) {
String value = null;
if (eAnnotation != null) {
EMap<String, String> eAnnotationDetailsMap = eAnnotation.getDetails();
if (eAnnotationDetailsMap != null) {
value = eAnnotationDetailsMap.get(key);
}
}
return value;
}
@Override
public boolean isTrue(EAnnotation eAnnotation, String key) {
boolean result = false;
String value = getEAnnotationDetailValue(eAnnotation, key);
if (value != null) {
result = Boolean.parseBoolean(value);
}
return result;
}
@Override
public Number getEAnnotationDetailNumberValue(EAnnotation eAnnotation, String key) {
Number number = null;
String value = getEAnnotationDetailValue(eAnnotation, key);
if (value != null) {
try {
number = Double.valueOf(value);
} catch (Exception e) {
}
}
return number;
}
// protected String getAnnotationDetail(ETypedElement eTypedElement, String key) {
// EAnnotation annotation = eTypedElement.getEAnnotation("http://www.eclipse.org/emf/2002/GenModel");
// if (annotation != null) {
// EMap<String, String> map = annotation.getDetails();
// if (map != null)
// return map.get(key);
// }
// return null;
// }
//
// protected Number getAnnotationDetailAsNumber(ETypedElement eTypedElement, String key) {
// EAnnotation annotation = eTypedElement.getEAnnotation("http://www.eclipse.org/emf/2002/GenModel");
// if (annotation != null) {
// EMap<String, String> map = annotation.getDetails();
// if (map != null) {
// String valueString = map.get(key);
// try {
// return Double.valueOf(valueString);
// } catch (Exception e) {
// }
// }
// }
// return null;
// }
@Override
public List<EClass> filterEClasses(List<EClass> eClasses, EClassFilter filter) {
List<EClassFilter> filters = new ArrayList<EClassFilter>();
filters.add(filter);
return filterEClasses(eClasses, filters);
}
@Override
public List<EClass> filterEClasses(List<EClass> eClasses, List<EClassFilter> filters) {
List<EClass> output = new ArrayList<EClass>();
for (EClass eClass : eClasses) {
boolean keep = true;
Iterator<EClassFilter> it = filters.iterator();
while (it.hasNext() && (keep == true)) {
EClassFilter filter = it.next();
keep = filter.filter(eClass);
}
if (keep) {
output.add(eClass);
}
}
return output;
}
@Override
public EClass findClosestMatch(EClass eClass, List<EClass> eClasses) {
EClass closestMatch = eClasses.get(0);
for (EClass matchingEClass : eClasses) {
if (closestMatch.isSuperTypeOf(matchingEClass)) {
if (eClasses.indexOf(matchingEClass) + 1 < eClasses.size()) {
closestMatch = findClosestMatch(eClass,
eClasses.subList(eClasses.indexOf(matchingEClass), eClasses.size() - 1));
} else {
return matchingEClass;
}
}
}
return closestMatch;
}
@Override
public EClass getEClass(String str) {
EClass result = null;
Iterator<EClass> classes = getAllAvailableEClasses().iterator();
while (result == null && classes.hasNext()) {
EClass clazz = classes.next();
if (clazz.getInstanceTypeName() != null && clazz.getInstanceTypeName().equals(str)) {
result = clazz;
}
}
return result;
}
protected class TimedComparator implements Comparator<Timed> {
@Override
public int compare(Timed o1, Timed o2) {
long time1 = o1.getTime().getTime();
long time2 = o2.getTime().getTime();
if (time1 < time2) {
return -1;
} else if (time1 > time2) {
return 1;
} else {
return 0;
}
}
}
protected boolean validateDateFormatString(String formatString) {
if (formatString == null || formatString.length() == 0) {
return false;
}
return true;
}
protected String stripCommentDelimiters(String commentString) {
String result = "";
if (commentString != null) {
// Removes leading ** or *
String[] lines = commentString.split("\n");
for (String line : lines) {
line = line.trim();
if (!(line.compareTo("*") == 0)) {
if (line.startsWith("*")) {
line = line.replace('*', ' ');
}
result += line + "\n";
}
}
}
return result;
}
} // ApogyCommonEMFFacadeImpl