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.Map;
011
012import javax.jmi.model.Classifier;
013import javax.jmi.reflect.JmiException;
014import javax.jmi.reflect.RefClass;
015import javax.jmi.reflect.RefObject;
016import javax.jmi.reflect.RefPackage;
017
018import net.mdatools.modelant.core.api.Procedure;
019import net.mdatools.modelant.core.api.model.ConstructProcedure;
020import net.mdatools.modelant.core.api.model.NameMapping;
021import net.mdatools.modelant.core.api.name.ClassName;
022import net.mdatools.modelant.core.api.name.Name;
023import net.mdatools.modelant.core.api.name.PackageName;
024
025/**
026 * A key in class mapping
027 * @author Rusi Popov (popovr@mdatools.net)
028 */
029public class ClassNameImpl extends NameImpl<Name<?>> implements ClassName {
030  public ClassNameImpl(String packageName) {
031    super(packageName);
032  }
033
034  public ClassNameImpl(PackageName parent, String name) {
035    super(parent, name);
036  }
037
038  public ClassNameImpl(ClassName parent, String name) {
039    super(parent, name);
040  }
041
042  ClassNameImpl(Name<?> parent, String name) {
043    super(parent, name);
044  }
045
046
047  public ClassNameImpl(Classifier classifier) {
048    super(new PackageNameImpl(classifier.getContainer()), classifier.getName());
049  }
050
051
052
053  /**
054   * @param qualifiedName not null
055   * @return the Class Name that represents the qualified name provided,
056   * @throws IllegalArgumentException when qualifiedName is empty
057   */
058  public static ClassName parseQualifiedClassName(String qualifiedName) throws IllegalArgumentException {
059    ClassName result;
060    PackageName pack;
061    String[] names;
062
063    pack = null;
064    names = qualifiedName.split( METAMODEL_PATH_SEPARATOR_PARSE );
065    for (int i=0; i<names.length-1; i++) {
066      pack = new PackageNameImpl( pack, names[i] );
067    }
068    if (names.length > 0) {
069      result = new ClassNameImpl(pack, names[names.length-1]);
070    } else {
071      result = null;
072    }
073    return result;
074  }
075
076  /**
077   * @param rootPackage not null extent
078   */
079  public RefClass getMetaClass(RefPackage rootPackage) throws JmiException {
080    RefClass result;
081    RefPackage ownerPackage;
082
083    assert rootPackage != null : "Expected a non-null package";
084
085    if ( getOwner() == null ) {
086      ownerPackage = rootPackage;
087    } else if ( getOwner() instanceof PackageName ) {
088      ownerPackage = ((PackageName) getOwner()).getMetaPackage( rootPackage );
089    } else {
090      throw new IllegalArgumentException(this + " should be a class name in order to lookup the corresponding *Class instance");
091    }
092
093    try {
094      result = ownerPackage.refClass( getName() );
095    } catch (JmiException ex) {
096      throw new IllegalArgumentException("Looking up the class "+ this
097                                       + " reached " + PRINT_MODEL_ELEMENT.execute( ownerPackage )
098                                       + " for which retrieving the nested class '"+getName()+"'"
099                                       + " caused ",ex);
100    }
101    return result;
102  }
103
104  /**
105   * @see net.mdatools.modelant.core.name.NameImpl#constructName(net.mdatools.modelant.core.api.name.Name, java.lang.String)
106   */
107  public Name<Name<?>> constructName(Name<?> parent, String name) {
108    return new ClassNameImpl(parent, name);
109  }
110
111  /**
112   * @see net.mdatools.modelant.core.api.name.Name#constructTransfromation()
113   */
114  public ConstructProcedure<?> constructTransfromation() {
115    return new ConstructProcedure<RefObject>() {
116      public Procedure<RefObject> construct(RefPackage sourceExtent, RefPackage targetExtent, Map<RefObject, RefObject> objectsMap, NameMapping valueMapping) {
117        RefClass targetClass;
118
119        targetClass = ClassNameImpl.this.getMetaClass( targetExtent );
120
121        return new Procedure<RefObject>() {
122          public void execute(RefObject original) throws RuntimeException, IllegalArgumentException {
123            RefObject result;
124
125            result = targetClass.refCreateInstance( null );
126            objectsMap.put( original, result );
127          }
128        };
129      }
130    };
131  }
132}