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.name; 009 010import java.util.List; 011 012import javax.jmi.reflect.InvalidNameException; 013import javax.jmi.reflect.JmiException; 014import javax.jmi.reflect.RefBaseObject; 015import javax.jmi.reflect.RefClass; 016import javax.jmi.reflect.RefEnum; 017import javax.jmi.reflect.RefPackage; 018 019import net.mdatools.modelant.core.api.name.EnumValueName; 020import net.mdatools.modelant.core.api.name.Name; 021import net.mdatools.modelant.core.api.name.PackageName; 022 023/** 024 * A key in package/type/value mapping 025 * @author Rusi Popov (popovr@mdatools.net) 026 */ 027public class EnumValueNameImpl extends NameImpl<Name<?>> implements EnumValueName { 028 029 public EnumValueNameImpl(String name) { 030 super(name); 031 } 032 033 public EnumValueNameImpl(Name<?> parentName, String name) { 034 super(parentName, name); 035 } 036 037 public EnumValueNameImpl(RefPackage targetExtent, RefEnum enumValue) { 038 this(constructEnumClassName(enumValue.refTypeName(), targetExtent), enumValue.toString()); 039 } 040 041 /** 042 * @param qualifiedName not null, not empty qualified name of the Enum Class 043 * @param targetExtent not null 044 * @return the class name of that Enum 045 */ 046 private static Name<?> constructEnumClassName(List<String> qualifiedName, RefPackage targetExtent) { 047 Name<?> result; 048 String name; 049 Name packageName; 050 RefBaseObject namespace; 051 052 namespace = targetExtent; 053 packageName = null; 054 for (int i=0; i<qualifiedName.size()-1; i++) { 055 name = qualifiedName.get( i ); 056 057 if ( namespace instanceof RefPackage ) { // the current name is a name of a package or class, packageName is a name of a package so far 058 try { 059 namespace = ((RefPackage) namespace).refPackage( name ); 060 packageName = new PackageNameImpl((PackageName) packageName, name); 061 062 } catch (InvalidNameException ex) { // name is not a package, it could be only a class 063 namespace = ((RefPackage) namespace).refClass( name ); 064 packageName = new ClassNameImpl((PackageName) packageName, name); 065 } 066 } else { // namespace is a Class owning at most an enumeration 067 throw new IllegalArgumentException("Resolving "+qualifiedName 068 +" enumeration name, reached "+PRINT_MODEL_ELEMENT.execute( namespace ) 069 +" which cannot contain nested "+name); 070 } 071 } 072 if ( qualifiedName.size() > 0 ) { 073 result = new ClassNameImpl(packageName, qualifiedName.get( qualifiedName.size()-1 )); 074 } else { 075 result = null; 076 } 077 return result; 078 } 079 080 /** 081 * @see net.mdatools.modelant.core.api.name.Name#constructName(net.mdatools.modelant.core.api.name.Name, java.lang.String) 082 */ 083 public Name<Name<?>> constructName(Name<?> parent, String name) { 084 return new EnumValueNameImpl(parent, name); 085 } 086 087 /** 088 * @see net.mdatools.modelant.core.api.name.EnumValueName#lookupValue(javax.jmi.reflect.RefPackage) 089 */ 090 public RefEnum lookupValue(RefPackage targetExtent) throws JmiException { 091 RefEnum result; 092 Name enumClassName; 093 Name enumClassNamespace; 094 PackageName enumClassNamespaceNamespace; 095 RefPackage enumClassNamespacePackage; 096 RefPackage enumClassPackage; 097 RefClass enumClassClass; 098 099 if ( getOwner() == null 100 || getOwner().getOwner() == null) { 101 throw new InvalidNameException( toString(), "Expected a parent class and package name provided"); 102 } 103 104 enumClassName = getOwner(); 105 enumClassNamespace = enumClassName.getOwner(); 106 enumClassNamespaceNamespace = (PackageName) enumClassNamespace.getOwner(); 107 108 if ( enumClassNamespaceNamespace != null ) { 109 enumClassNamespacePackage = enumClassNamespaceNamespace.getMetaPackage( targetExtent ); 110 } else { 111 enumClassNamespacePackage = targetExtent; 112 } 113 114 // in enumClassNamespaceNamespace, enumClassNamespace could be a class or package 115 // try both options, which one will work 116 try { 117 enumClassPackage = enumClassNamespacePackage.refPackage( enumClassNamespace.getName() ); 118 result = enumClassPackage.refGetEnum( enumClassName.getName(), getName() ); 119 120 } catch (InvalidNameException ex) { 121 enumClassClass = enumClassNamespacePackage.refClass( enumClassNamespace.getName() ); 122 result = enumClassClass.refGetEnum( enumClassName.getName(), getName() ); 123 } 124 return result; 125 } 126}