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.selector; 009 010import java.util.ArrayList; 011import java.util.Collection; 012 013import javax.jmi.model.ModelElement; 014import javax.jmi.reflect.JmiException; 015import javax.jmi.reflect.RefObject; 016import javax.jmi.reflect.RefPackage; 017 018import net.mdatools.modelant.core.api.Selector; 019import net.mdatools.modelant.core.api.name.Name; 020import net.mdatools.modelant.core.util.Navigator; 021 022/** 023 * Selector of a metamodel class with the provided qualified name 024 * @author popovr 025 */ 026public class SelectByQualifiedName implements Selector<RefPackage, RefObject> { 027 028 /** 029 * The qualified name of the object(s) to retrieve 030 * not null 031 */ 032 private final String qualifiedName; 033 034 /** 035 * @param qualifiedName not null, not empty name of a MOF Class instance in the metamodel 036 */ 037 public SelectByQualifiedName(String qualifiedName) { 038 if ( qualifiedName == null || qualifiedName.trim().isEmpty() ) { // iteration on model class instances 039 throw new IllegalArgumentException( "Empty qualified name provided "); 040 } 041 this.qualifiedName = qualifiedName; 042 } 043 044 /** 045 * @param sourceExtent not null extent where to collect objects in 046 * @return non-null list of one element - the metaobject, describing the metaclass 047 */ 048 public Collection<RefObject> execute(RefPackage sourceExtent) throws JmiException { 049 Collection<RefObject> result; 050 Collection<RefObject> allObjects; 051 String[] parsedQualifiedName; 052 053 parsedQualifiedName = Name.parseQualifiedName( qualifiedName ); 054 055 result = new ArrayList<>(); 056 057 allObjects = Navigator.getAllObjects( sourceExtent ); 058 for (RefObject object : allObjects) { 059 if ( matches((ModelElement) object, parsedQualifiedName, parsedQualifiedName.length-1) ) { 060 result.add(object); 061 } 062 } 063 064 assert !result.isEmpty() 065 : "Expected a non-empty selection found for qualified name: "+qualifiedName; 066 return result; 067 } 068 069 /** 070 * @param object not null 071 * @param parsedQualifiedName not null parsed qualified name 072 * @param i < parsedQualifiedName.length 073 * @return true if object's name = parsedQualifiedName[i] and object's namespace matches the 074 * parsed name [i-1] 075 */ 076 private boolean matches(ModelElement object, String[] parsedQualifiedName, int i) { 077 boolean result; 078 079 if ( i < 0 ) { 080 result = true; 081 082 } else if ( object == null ) { // nothing to match 083 result = false; 084 085 } else { 086 result = parsedQualifiedName[i].equals( object.getName() ) 087 && ( i == 0 088 && object.getContainer() == null // matched the root package 089 || i > 0 090 && matches( object.getContainer(), parsedQualifiedName, i-1 )); 091 } 092 return result; 093 } 094}