001/* 002 * Copyright c 2018 Rusi Popov, MDA Tools.net All rights reserved. 003 * 004 * This program and the accompanying materials are made available under the terms of the 005 * Eclipse Public License v2.0 which accompanies this distribution, and is available at 006 * http://www.eclipse.org/legal/epl-v20.html 007 */ 008package net.mdatools.modelant.core.operation.model.order; 009 010import java.util.ArrayList; 011import java.util.HashSet; 012import java.util.List; 013import java.util.Set; 014 015import javax.jmi.model.GeneralizableElement; 016import javax.jmi.reflect.RefBaseObject; 017 018import net.mdatools.modelant.core.api.Order; 019 020/** 021 * State a list of metamodel classes to order their instances. 022 * The instances of different (listed) classes are ordered according to the positions of those classes in the list. 023 * Instances of not listed classes are just kept as they are, after any instances of listed classes. 024 * @author Rusi Popov (popovr@mdatools.net) 025 */ 026public class OrderByClass implements Order { 027 028 /** 029 * List of class names defining their order 030 */ 031 private final List<String> classNames = new ArrayList<String>(); 032 private final Set<String> knownNotCoveredClasses = new HashSet<String>(); 033 034 public int compare(RefBaseObject o1, RefBaseObject o2) { 035 int index1; 036 int index2; 037 038 index1 = getIndexOf((GeneralizableElement) o1.refMetaObject()); 039 index2 = getIndexOf((GeneralizableElement) o2.refMetaObject()); 040 041 return index1-index2; 042 } 043 044 /** 045 * post-condition: 046 * knownNotCoveredClasses is updated with classes known not pertaining to the list 047 * @param target not null MOF Element representing a superclass of a model element to order 048 * @return the minimal index of the model class of the target or of its superclasses in classNames list. If 049 * no (super)class found among classNames, MAX_INT is returned 050 */ 051 private int getIndexOf(GeneralizableElement target) { 052 int result; 053 String metaClassName; 054 055 metaClassName = target.getName(); 056 057 result = classNames.indexOf( metaClassName ); 058 if ( result < 0 ) { // not listed explicitly, search superclasses 059 result = Integer.MAX_VALUE; 060 061 if ( !knownNotCoveredClasses.contains( metaClassName ) ) { // still decision on the class is not made 062 for (GeneralizableElement superClass : (List<GeneralizableElement>) target.getSupertypes()) { 063 result = Math.min( result, getIndexOf( superClass ) ); 064 } 065 if ( result == Integer.MAX_VALUE ) { // the class is not covered 066 knownNotCoveredClasses.add( metaClassName ); 067 } 068 } 069 } 070 return result; 071 } 072 073 /** 074 * Add a single class name to the list of classes. The order of a model element's class name within the list 075 * compared the order other elements' class name defines the order of those elements. 076 * with the order of other 077 */ 078 public ClassName createClass() { 079 return new ClassName(); 080 } 081 082 /** 083 * State the text contents of <class> element as a single class name to order against. 084 */ 085 public class ClassName { 086 public void addText(String className) { 087 classNames.add( className ); 088 } 089 } 090}