Package modTransf.model.jmi

Source Code of modTransf.model.jmi.JmiModelHelper

//Source file: H:\\temp\\generated\\modTransf\\model\\jmi\\JmiModelHelper.java

package modTransf.model.jmi;

import modTransf.model.ModelHelperBase;
import modTransf.model.ModelHelper;
import modTransf.model.ModelException;
import modTransf.model.NotFoundException;
import modTransf.model.factory.ModelFactory;

import java.lang.reflect.InvocationTargetException;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

import javax.jmi.reflect.RefPackage;
import javax.jmi.reflect.RefObject;
import javax.jmi.reflect.RefBaseObject;
import javax.jmi.reflect.RefClass;
import javax.jmi.reflect.RefAssociation;
import javax.jmi.reflect.RefEnum;
import javax.jmi.reflect.RefStruct;
import javax.jmi.reflect.JmiException;
import javax.jmi.reflect.InvalidNameException;
import org.apache.commons.beanutils.PropertyUtils;
import java.lang.reflect.Method;
import javax.jmi.model.EnumerationType;

public class JmiModelHelper extends ModelHelperBase implements ModelHelper
{
  public static final String[] EMPTY_STRING_ARRAY = new String[]{};

  /** The outermost RefPackage containing the current model */
  protected RefPackage outermostRefPackage;

  /** The name of the outermost RefPackage containing the current model */
  protected String outermostRefPackageName;

  /**
   * Constructor.
   * @param factory ModelFactory
   * @param refPackage RefPackage
   */
  public JmiModelHelper(RefPackage refPackage)
  {
    super( (Object)refPackage);
    outermostRefPackage = refPackage;
  }

  /**
   * Constructor.
   * @param factory ModelFactory
   * @param refPackage RefPackage
   */
  public JmiModelHelper(Object nativeModel)
  {
    super(nativeModel);
    outermostRefPackage = (RefPackage)nativeModel;
  }

  /**
   * @param object
   * @param name
   * @param args
   * @return Object
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public Object invokeMethod(Object object, String name, Object[] args)
    throws ModelException
  {
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  /**
   * @param conceptType
   * @return java.util.Collection
   */
  public Collection getAllOfType(String conceptType)
  {
    return getRefClassByConceptName(conceptType).refAllOfType();
  }

  /**
   * @param conceptType
   * @return java.util.Collection
   */
  public Collection getAllOfClass(String conceptType)
  {
    return getRefClassByConceptName(conceptType).refAllOfClass();
  }

  /**
   * Set the property.
   * Take into account Enumeration properties.
   * Try to set the property as a regular property. If IllegalArgumentException
   * is raise, catch it and check if this is an enumeration type.
   * @todo Find another way to detect enum and struct, in order to avoid the
   * error msg.
   * @param bean
   * @param name
   * @param value
   * @throws modTransf.model.ModelException
   * @throws java.lang.IllegalAccessException
   * @throws java.lang.reflect.InvocationTargetException
   * @throws java.lang.NoSuchMethodException
   */
  public void setProperty(Object bean, String name, Object value)
    throws ModelException
  {
   try
   {
     PropertyUtils.setProperty(bean, name, value);
   }
   catch(NoSuchMethodException ex)
   {
     throw new ModelException(ex);
   }
   catch(java.lang.IllegalArgumentException ex)
   { // Check if this is an enumeration
     try {
       setEnumProperty(bean, name, value.toString());
     }
     catch(ModelException ex2 )
     { // Throw surrounding exception
       //System.out.println("Fail to set '"+ bean.getClass().getName() +"." +name + "'='"+value+"' as enum:" + ex2);
       //ex2.printStackTrace();
       throw new ModelException(ex);
     }
     catch(InvalidNameException ex2 )
     { // Throw this exception
       //System.out.println("Fail to set '"+ bean.getClass().getName() +"." +name + "'='"+value+"' as enum:" + ex2);
       //ex2.printStackTrace();
       //throw new Error(ex2);
       throw new ModelException(ex2);
     }
   }
   catch(InvocationTargetException ex)
   {
     throw new ModelException(ex);
   }
   catch(IllegalAccessException ex)
   {
     throw new ModelException(ex);
   }

  }

  /**
   * Is this ModelUtil owner of the specified object ?
   * If a model is owner of an object, it means that the methods of the
   * model can called on the object.
   * This method return true if this ModelUtil implementation can manage the
   * specified object (method of this class can be called on the object).
   * @param object The object to test.
   * @return true if the associated model is owner of the object, false otherwise.
   */
  public boolean isOwnerOf(Object object)
  {
    if( (object instanceof RefBaseObject))
    {
      return( (RefBaseObject)object).refOutermostPackage()==outermostRefPackage;
    }

    else if(object instanceof RefStruct)
    {
      return getOutermostRefPackageName().equals( ( (RefStruct)object).refTypeName().get(0));
    }
    else if(object instanceof RefEnum)
    {
      return getOutermostRefPackageName().equals( ( (RefEnum)object).refTypeName().get(0));
    }
    else
    {
      return false;
    }

  }

  /**
   * Is the object instance of the specified type ?
   * @param object
   * @param instanceName
   * @return boolean
   */
  public boolean isInstanceOf(Object object, String instanceName)
  {
    //System.out.println("isInstanceOf(Object=" + object.getClass().getName() + ")" );
    if(object instanceof RefObject)
    {
      RefClass conceptClass = getRefClassByConceptName(instanceName);
      return conceptClass.refAllOfType().contains(object);
      //return ((RefObject)object).refIsInstanceOf( conceptClass.refMetaObject(), true );
      //return ((RefObject)object).refClass() == conceptClass;
    }
    else if(object instanceof RefStruct)
    {
      // TODO: Check also for subclasses !!
      //System.out.println( "check " + ((RefStruct)object).refTypeName()  + ".isIntanceof("
      //                  + instanceName + ")" );
      return pathnameToList(instanceName).equals( ( (RefStruct)object).refTypeName());
    }
    else if(object instanceof RefAssociation)
    {
      throw new UnsupportedOperationException(
        "JMI Helper Method 'isInstanceOf()' not yet implemented for RefAssociation (object.type="
        +object.getClass().getName()+").");
    }
    else if(object instanceof RefEnum)
    {
      return pathnameToList(instanceName).equals( ( (RefEnum)object).refTypeName());
    }
    else
    {
      return false;
    }
  }

  /**
   * Is the object of the specified class ?
   * @param object
   * @param instanceName
   * @return boolean
   */
  public boolean isOfClass(Object modelElement, String instanceName)
  {
    //
    RefClass conceptClass = getRefClassByConceptName(instanceName);
    //System.out.println("isInstanceOf(Object=" + object.getClass().getName() + ")" );
    if(modelElement instanceof RefObject)
    {

      //return conceptClass.refAllOfClass().contains(modelElement);
      //return ((RefObject)object).refIsInstanceOf( conceptClass.refMetaObject(), true );
      return( (RefObject)modelElement).refClass()==conceptClass;
    }
    else if(modelElement instanceof RefStruct)
    {
      return pathnameToList(instanceName).equals( ( (RefStruct)modelElement).refTypeName());
    }
    else if(modelElement instanceof RefAssociation)
    {
      throw new UnsupportedOperationException(
        "JMI Helper Method 'isOfClass()' not yet implemented for RefAssociation (object.type="
        +modelElement.getClass().getName()+").");
    }
    else if(modelElement instanceof RefEnum)
    {
      return pathnameToList(instanceName).equals( ( (RefEnum)modelElement).refTypeName());
    }
    else
    {
      return false;
    }
  }

  /**
   * Create an instance of specified model element.
   * @param instanceName Name of the instance to create.
   * @return
   * @throws InstantiationException If the model element can't be created.
   */
  public Object createInstance(String conceptName)
    throws InstantiationException
  {
    //System.out.println( "Create Instance " + conceptName  );
    try
    {
      return getRefClassByConceptName(conceptName).refCreateInstance(Collections.EMPTY_LIST);
    }
    catch(JmiException ex)
    { // This exception can come from getRefClassByConceptName or refCreateInstance
      throw new InstantiationException("Can't instanciate '"+conceptName
                                       +"' : "+ex.getClass().getName()
                                       + (ex.getMessage()!=null?" : "+ex.getMessage():"")
                                       +".");
    }
  }

  /**
   * @param instance
   */
  public void deleteInstance(Object instance)
  {
    throw new UnsupportedOperationException("Not yet implemented.");
  }

  /**
   * getModelRoots
   *
   * @return Collection
   */
  public Collection getModelRoots()
  {
    return getRoots(getOutermostRefPackage());
  }

  /**
   * Get the JMI RefPackage (outermost extent) object.
   * @return RefPackage The JMI RefPackage outermost extent.
   */
  public RefPackage getOutermostRefPackage()
  {
    // For debug. To be removed
//    if( outermostRefPackage == null )
//      throw new IllegalArgumentException("outermostRefPackage is null !!!" );
    return outermostRefPackage;
  }

  /**
   * Get the JMI RefPackage (outermost extent) object.
   * @return RefPackage The JMI RefPackage outermost extent.
   */
  protected String getOutermostRefPackageName()
  {
    if(outermostRefPackageName!=null)
    {
      return outermostRefPackageName;
    }

    outermostRefPackageName = (String)outermostRefPackage.refMetaObject().refGetValue("name");
    return outermostRefPackageName;
  }

  /**
   * Get the JMI RefPackage (outermost extent) object.
   * @return RefPackage The JMI RefPackage outermost extent.
   */
  public void setOutermostRefPackage(RefPackage outermostRefPackage)
  {
    this.outermostRefPackage = outermostRefPackage;
  }

  /**
   * Convert a pathname to a list of name. A pathname is made of names
   * separated with "."
   * @todo add "::" as separator.
   * @param pathname String
   * @return List
   */
  protected List pathnameToList(String pathname)
  {
    return Arrays.asList(pathname.split("\\."));
  }

  /**
   * Get the refClass by its concept name.
   * @param conceptName
   * @return
   * @throws InvalidNameException
   */
  protected RefClass getRefClassByConceptName(String conceptName)
    throws InvalidNameException
  {
    RefPackage extent = getOutermostRefPackage();
    String[] names = conceptName.split("\\.");
    int i = 0;
    try
    {
      for(i = 0; i<names.length-1; i++)
      {
        extent = (RefPackage)extent.refPackage(names[i]);
      } // end loop
      return extent.refClass(names[i]);
    }
    catch(IndexOutOfBoundsException ex)
    {
      throw new InvalidNameException("Bad concept name '"+conceptName
                                     +"': Can't split name in subnames.");
    }
    catch(JmiException ex)
    {
      if(i>0)
      {
        System.out.println("Can't create class '"+conceptName+"', name '"
                           +names[i]
                           +"' not found in '"+names[i-1]+"'.");
        throw new InvalidNameException("Bad concept name '"+conceptName
                                       +"': name '"+names[i]
                                       +"' not found in '"+names[i-1]+"'.");
      }
      else
      {
        System.out.println("Can't create class '"+conceptName+"', name '"
                           +names[i]
                           +"' not found in outermost package.");
        throw new InvalidNameException("Bad concept name '"+conceptName
                                       +"': name '"+names[i]
                                       +"' not found in outermost package.");
      }
    }
    catch(RuntimeException ex)
    {
      //System.out.println( "error while getting concept class '" + conceptName + "',. i=" + i );
      throw new InvalidNameException("Bad concept name '"+conceptName
                                     +"'");
    }
  }

  /**
   * Get the refPackage by its concept name. The concept name is a "."
   * separated name. Each name denote a package name, except the last name
   * which is not use.
   * @param conceptName
   * @return
   * @throws InvalidNameException
   */
  protected RefPackage getRefPackageByConceptName(String conceptName)
    throws InvalidNameException
  {
    RefPackage extent = getOutermostRefPackage();
    String[] names = conceptName.split("\\.");
    int i = 0;
    try
    {
      for(i = 0; i<names.length-1; i++)
      {
        extent = (RefPackage)extent.refPackage(names[i]);
      } // end loop
      return extent;
    }
    catch(IndexOutOfBoundsException ex)
    {
      throw new InvalidNameException("Bad concept name '"+conceptName
                                     +"': Can't split name in subnames.");
    }
    catch(JmiException ex)
    {
      if(i>0)
      {
        System.out.println("Can't create class '"+conceptName+"', name '"
                           +names[i]
                           +"' not found in '"+names[i-1]+"'.");
        throw new InvalidNameException("Bad concept name '"+conceptName
                                       +"': name '"+names[i]
                                       +"' not found in '"+names[i-1]+"'.");
      }
      else
      {
        System.out.println("Can't create class '"+conceptName+"', name '"
                           +names[i]
                           +"' not found in outermost package.");
        throw new InvalidNameException("Bad concept name '"+conceptName
                                       +"': name '"+names[i]
                                       +"' not found in outermost package.");
      }
    }
    catch(RuntimeException ex)
    {
      //System.out.println( "error while getting concept class '" + conceptName + "',. i=" + i );
      throw new InvalidNameException("Bad concept name '"+conceptName
                                     +"'");
    }
  }

  /**
   * Get the refAssocaition by its association name. The concept name is a "."
   * separated name. Each name denote a package name, except the last name
   * which is not use.
   * @param conceptName
   * @return
   * @throws InvalidNameException
   */
  protected RefAssociation getRefAssociationByConceptName(String conceptName)
    throws InvalidNameException
  {
    RefPackage extent = getOutermostRefPackage();
    String[] names = conceptName.split("\\.");
    int i = 0;
    try
    {
      for(i = 0; i<names.length-1; i++)
      {
        extent = (RefPackage)extent.refPackage(names[i]);
      } // end loop
      return extent.refAssociation(names[i]);
    }
    catch(IndexOutOfBoundsException ex)
    {
      throw new InvalidNameException("Bad concept name '"+conceptName
                                     +"': Can't split name in subnames.");
    }
    catch(JmiException ex)
    {
      if(i>0)
      {

        System.out.println("Can't find class '"+conceptName+"', name '"
                           +names[i]
                           +"' not found in '"+names[i-1]+"'. (was: "
                           +ex.getMessage()+").");
        ex.printStackTrace();
        throw new InvalidNameException("Bad concept name '"+conceptName
                                       +"': name '"+names[i]
                                       +"' not found in '"+names[i-1]+"'.");
      }
      else
      {
        System.out.println("Can't find class '"+conceptName+"', name '"
                           +names[i]
                           +"' not found in outermost package.(was: "
                           +ex.getMessage()+").");
        throw new InvalidNameException("Bad concept name '"+conceptName
                                       +"': name '"+names[i]
                                       +"' not found in outermost package.");
      }
    }
    catch(RuntimeException ex)
    {
      //System.out.println( "error while getting concept class '" + conceptName + "',. i=" + i );
      throw new InvalidNameException("Bad concept name '"+conceptName
                                     +"'");
    }
  }

  /**
   * Get all roots from model.
   * @param elementName
   * @return
   */
  protected Collection getRoots(RefPackage extent)
  {
    //System.out.println("Get roots from " + extent.refMetaObject().refGetValue("name") );
    Collection roots = new ArrayList();
    addRoots(roots, extent);
    System.out.println("   Found "+roots.size()+" roots.");
    return roots;
  }

  /**
   * Add roots contained in the package
   * @param roots
   * @param extent
   */
  protected void addRoots(Collection roots, RefPackage extent)
  {
    //System.out.println("  check package'" + extent + "'.");
    // First, walk all containers
    Collection containers = extent.refAllClasses();
    Iterator iter = containers.iterator();
    while(iter.hasNext())
    {
      addRoots(roots, (RefClass)iter.next());
    } // end loop

    // Now, , walk all nested packages
    Collection packages = extent.refAllPackages();
    iter = packages.iterator();
    while(iter.hasNext())
    {
      addRoots(roots, (RefPackage)iter.next());
    } // end loop
  }

  /**
   * Add roots contained in the package
   * @param roots
   * @param extent
   */
  protected void addRoots(Collection roots, RefClass container)
  {
    //System.out.println("  check class'" + container + "'.");
    // Get the object owned by the container
    Collection objects = container.refAllOfType();
    // Get only objects wich aren't component of another object
    Iterator iter = objects.iterator();
    while(iter.hasNext())
    {
      RefObject object = (RefObject)iter.next();
      //System.out.println("  check '" + object + "'.");
      if(object.refImmediateComposite()==null)
      {
        //System.out.println("     --->  added " + object.refMetaObject().refGetValue("name") );
        // Add if not already found
        if(!roots.contains(object))
        {
          roots.add(object);
        }
      }
    } // end loop
  }

  /**
   * Get the type of the specified property on the specified object.
   * Throw NotFoundException if the property doesn't exist on the bean.
   * @param bean Object
   * @param propertyName String
   * @return List
   */
  protected String[] getPropertyType( Object bean, String propertyName )
    throws NotFoundException
  {
    RefObject propDesc = getPropertyMetaClass(bean, propertyName);
    return getFullTypeFromMetaClass( propDesc );
  }

  /**
   * Get the Enumerationtype of the specified property on the specified object.
   * Throw NotFoundException if the property doesn't exist on the bean.
   *
   * @param bean Object
   * @param propertyName String
   * @return EnumType or null if this is not an enumeration
   * @throws NotFoundException if the property doesn't exist on the bean.
   */
  protected String[] getEnumType( Object bean, String propertyName )
    throws NotFoundException
  {
    RefObject propDesc = getPropertyMetaClass(bean, propertyName);
    if(! (propDesc instanceof EnumerationType) )
      return null;
    return getFullTypeFromMetaClass( propDesc );
  }

  /**
   * Get the metaObject for the specified property of the specified bean.
   * @param bean Object
   * @param propertyName String
   * @throws NotFoundException
   * @return RefObject
   */
  protected RefObject getPropertyMetaClass( Object bean, String propertyName )
    throws NotFoundException
  {
    if( propertyName == null )
      throw new IllegalArgumentException("propertyName should be set.");

    RefObject ref = (RefObject)bean;
    RefObject descriptor = ref.refMetaObject();
    // Lookup the property descriptor.
    // Lookup the attribute with the requested name,
    // return the type pointed by the attribute.
    Iterator propertyIter = ((Collection)descriptor.refGetValue("contents")).iterator();
    while(propertyIter.hasNext())
    {
      RefObject attribute = (RefObject)propertyIter.next();
      if( propertyName.equals( attribute.refGetValue( "name" ) ) )
      {
        return (RefObject)attribute.refGetValue("type");
      }
    }

    throw new NotFoundException("No property '" + propertyName + "' in '" + descriptor.getClass().getName() + "'.");
  }

  /**
   * Get the full type associated to the metaclass.
   * The outermost package name is not part of the returned names.
   * @param metaclass RefObject
   * @return List
   */
  protected String[] getFullTypeFromMetaClass( RefObject metaclass )
  {
    List res = new ArrayList();

    res.add( metaclass.refGetValue("name") );
    RefObject parent = (RefObject)metaclass.refGetValue("container" );
    //System.out.println("metaclass.refOutermostPackage()='" + metaclass.refOutermostPackage().getClass().getName() + "'." );
    while( parent !=null  )
    {
      //System.out.println("metaclass.refOutermostPackage()='" + metaclass.refOutermostPackage().getClass().getName() + "'." );
      //System.out.println("parent='" + parent.getClass().getName() + "'." );
      String name = (String)parent.refGetValue("name");

      // Don't put the last one
      parent = (RefObject)parent.refGetValue("container" );
      if( parent == null )
        break;
      //System.out.println("add '" + name + "'." );
      res.addname );
    }
    // Remove the last one: this is the mainExtent.
//    if( res.size() > 1 )
//      res.remove(res.size()-1);

    // Revert list
    Collections.reverse(res);

    return (String[])res.toArray(EMPTY_STRING_ARRAY);
  }

  /**
   * Check if the specified property denote an enumeration.
   *
   * @param bean Object
   * @param property String
   * @param value String
   * @throws NotFoundException
   * @throws javax.jmi.reflect.InvalidNameException If the literal value doesn't match the enum.
   */
  protected void setEnumProperty( Object bean, String property, String value )
    throws NotFoundException, InvalidNameException
  {
    // Skip null and empty string: they can't be converted !!
    if(value==null || value.length() == 0 )
      return;

    // Get the enum type
    String[] proptype = getEnumType( bean, property);
    if( proptype == null )
      throw new NotFoundException("Not an enumeration.");

    String enumTypeName = (String)proptype[proptype.length-1];
    RefPackage pack = getRefPackageByType( proptype );
    RefEnum enumValue = null;
    // next one throw InvalidNameException
    enumValue = pack.refGetEnum(enumTypeName, value);

    RefObject obj = (RefObject)bean;
    obj.refSetValue( property, enumValue);
  }

  /**
   * getRefPackageByType
   *
   * @param proptype List
   * @return RefPackage
   */
  protected RefPackage getRefPackageByType(String[] names)
  {
    RefPackage extent = getOutermostRefPackage();
    int i=0;
    try
    {
      for(i = 0; i<names.length-1; i++)
      {
        extent = (RefPackage)extent.refPackage(names[i]);
      }
    }
    catch(InvalidNameException ex)
    {
      if(i>0)
      {
        throw new InvalidNameException("Can't found package '" +names[i]
                                       +"' in '"+names[i-1]+"'.");
      }
      else
      {
        System.out.println("Can't found package '" +names[i]
                                       +"' in outermost package.");
        throw new InvalidNameException("Can't found package '" +names[i]
                                       +"' in outermost package.");
      }
    }

    return extent;
  }
}
TOP

Related Classes of modTransf.model.jmi.JmiModelHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.