| /******************************************************************************* |
| * 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 |