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.Attribute;
013import javax.jmi.model.Classifier;
014import javax.jmi.model.ModelElement;
015import javax.jmi.model.NameNotFoundException;
016import javax.jmi.reflect.RefClass;
017import javax.jmi.reflect.RefObject;
018import javax.jmi.reflect.RefPackage;
019
020import net.mdatools.modelant.core.api.Procedure;
021import net.mdatools.modelant.core.api.model.ConstructProcedure;
022import net.mdatools.modelant.core.api.model.NameMapping;
023import net.mdatools.modelant.core.api.name.ClassName;
024import net.mdatools.modelant.core.api.name.FieldName;
025import net.mdatools.modelant.core.api.name.Name;
026import net.mdatools.modelant.core.operation.model.transform.CopyAttributeImpl;
027
028/**
029 * A key in field mapping
030 * @author Rusi Popov (popovr@mdatools.net)
031 */
032public class FieldNameImpl extends NameImpl<ClassName> implements FieldName {
033  public FieldNameImpl(String name) {
034    super(name);
035  }
036
037  public FieldNameImpl(ClassName parent, String name) {
038    super(parent, name);
039  }
040
041  public FieldNameImpl(Attribute attribute) {
042    super(new ClassNameImpl((Classifier) attribute.getContainer()), attribute.getName());
043  }
044
045  /* (non-Javadoc)
046   * @see net.mdatools.modelant.core.api.name.Name#construct(net.mdatools.modelant.core.api.name.Name, java.lang.String)
047   */
048  public Name<ClassName> constructName(ClassName parent, String name) {
049    return new FieldNameImpl(parent, name);
050  }
051
052  /**
053   * @see net.mdatools.modelant.core.api.name.Name#constructTransfromation()
054   */
055  public ConstructProcedure<RefObject> constructTransfromation() {
056    return new ConstructProcedure<RefObject>() {
057      private Procedure<RefObject> result;
058
059      public Procedure<RefObject> construct(RefPackage sourceExtent,
060                                            RefPackage targetExtent,
061                                            Map<RefObject, RefObject> objectsMap,
062                                            NameMapping valueMapping) {
063        RefClass ownerRefClass;
064        Classifier ownerClassifier;
065        ModelElement feature;
066
067        // lookup the attribute's description
068        if ( getOwner() == null ) {
069          throw new IllegalArgumentException("Expected "+this+" field has the owner class specified");
070        }
071        ownerRefClass = getOwner().getMetaClass( targetExtent );
072        ownerClassifier = (Classifier) ownerRefClass.refMetaObject();
073
074        try {
075          feature = ownerClassifier.lookupElement( getName() );
076          if ( feature instanceof Attribute
077              && ((Attribute) feature).isChangeable()  ) {
078
079           result = new CopyAttributeImpl( FieldNameImpl.this.getName(),
080                                           FieldNameImpl.this.getName(),
081                                           objectsMap,
082                                           sourceExtent,
083                                           targetExtent,
084                                           valueMapping );
085          } else {
086            result = Procedure.EMPTY;
087          }
088        } catch (NameNotFoundException e) {
089          throw new IllegalArgumentException(this+" field was not found in the target model");
090        }
091        return result;
092      }
093
094      /**
095       * @see java.lang.Object#toString()
096       */
097      public String toString() {
098        return String.valueOf( result );
099      }
100    };
101  }
102}