All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.xsd.provider.XSDItemProviderAdapter Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2002-2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 */
package org.eclipse.xsd.provider;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;

import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeGroupDefinition;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDCompositor;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDForm;
import org.eclipse.xsd.XSDIdentityConstraintDefinition;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDModelGroupDefinition;
import org.eclipse.xsd.XSDNotationDeclaration;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDParticleContent;
import org.eclipse.xsd.XSDRedefine;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.XSDVariety;
import org.eclipse.xsd.XSDWildcard;
import org.eclipse.xsd.XSDXPathDefinition;


/**
 * This is the base for all adapters.
 * It takes handles the {@link #getParent getParent()} implementation that
 * is need for {@link org.eclipse.xsd.provider.XSDParticleItemProvider} 
 * and {@link org.eclipse.xsd.provider.XSDAttributeUseItemProvider} 
 * to skip up to a particle or attribute use.
 * It also supports {@link CreateChildCommand} by supplying text and icons,
 * and provides methods that assist the derived adapters in overriding
 * {@link ItemProviderAdapter#collectNewChildDescriptors}.
 */
public class XSDItemProviderAdapter extends ItemProviderAdapter
  implements CreateChildCommand.Helper
{
  protected static final XSDPackage xsdPackage = XSDPackage.eINSTANCE;
  protected static final XSDFactory xsdFactory = XSDFactory.eINSTANCE;

  protected AdapterFactoryItemDelegator itemDelegator;

  /**
   * This creates an instance from an adapter factory.
   */
  protected XSDItemProviderAdapter(AdapterFactory adapterFactory)
  {
    super(adapterFactory);
    itemDelegator = new AdapterFactoryItemDelegator(adapterFactory);
  }

  /**
   * This returns the parent.
   */
  @Override
  public Object getParent(Object object)
  {
    EObject eObject = (EObject)object;
    EObject parent = eObject.eContainer();
    if (parent != null)
    {
      EObject grandParent = parent.eContainer();
      if (grandParent instanceof XSDParticle ||
          grandParent instanceof XSDAttributeUse)
      {
        return grandParent;
      }
    }
    if (parent == null)
    {
      return eObject.eResource();
    }
    return parent;
  }

  @Override
  public List getPropertyDescriptors(final Object object)
  {
    if (itemPropertyDescriptors == null)
    {
      itemPropertyDescriptors = 
        new ArrayList()
        {
          private static final long serialVersionUID = 1L;

          @Override
          public boolean add(IItemPropertyDescriptor o)
          {
            String id = o.getId(object);
            for (IItemPropertyDescriptor propertyDescriptor : this)
            {
              if (id.equals(propertyDescriptor.getId(object)))
              {
                return false;
              }
            }
            return super.add(o);
          }
        };

    }
    return itemPropertyDescriptors;
  }

  public static class ItemPropertyDescriptorWithDefault extends ItemPropertyDescriptor
  {
    public ItemPropertyDescriptorWithDefault
       (AdapterFactory adapterFactory,
        String displayName,
        String description,
        EStructuralFeature feature,
        boolean isSettable,
        Object staticImage)
    {
      super(adapterFactory, displayName, description, feature, isSettable, staticImage);
    }

    @Override
    public Object getPropertyValue(Object o)
    {
      if (feature instanceof EAttribute)
      {
        EObject refObject = (EObject)o;
        EAttribute attribute = (EAttribute)feature;
        if (!attribute.isMany() && !refObject.eIsSet(attribute))
        {
          return createPropertyValueWrapper(o, getPropertyDefaultValue(o));
        }
      }
      return super.getPropertyValue(o);
    }

    @Override
    public void setPropertyValue(Object o, Object value)
    {
      if (feature instanceof EAttribute)
      {
        EAttribute attribute = (EAttribute)feature;
        if (!attribute.isMany())
        {
          Object propertyDefaultValue = getPropertyDefaultValue(o);
          if (propertyDefaultValue.equals(value))
          {
            resetPropertyValue(o);
            return;
          }
        }
      }
      super.setPropertyValue(o, value);
    }

    @Override
    public Collection getChoiceOfValues(Object o)
    {
      Collection result = super.getChoiceOfValues(o);
      if (result != null && feature instanceof EAttribute)
      {
        EAttribute attribute = (EAttribute)feature;
        if (!attribute.isMany())
        {
          List newResult = new ArrayList(result);
          Object propertyDefaultValue = getPropertyDefaultValue(o);
          newResult.add(propertyDefaultValue);
          result = newResult;
        }
      }
      return result;
    }

    public Object getPropertyDefaultValue(Object o)
    {
      if (feature instanceof EAttribute)
      {
        EAttribute attribute = (EAttribute)feature;
        if (!attribute.isMany())
        {
          Object result = attribute.getDefaultValue();
          if (result == null)
          {
            result = getDefaultValue(attribute.getEType());
          }
          if (result == null)
          {
            return XSDEditPlugin.INSTANCE.getString("_UI_DefaultValue_label", new Object [] { "" });
          }
          else
          {
            return XSDEditPlugin.INSTANCE.getString("_UI_DefaultValue_label", new Object [] { this.itemDelegator.getText(result) });
          }
        }
      }
      return null;
    }
  }

  /**
   * If object is a particle or an attribute use, this returns
   * its content; otherwise, object itself.
   */
  protected Object getParticleOrAttributeUseContent(Object object)
  {
    if (object instanceof XSDParticle)
    {
      return ((XSDParticle) object).getContent();
    }
    else if (object instanceof XSDAttributeUse)
    {
      return ((XSDAttributeUse) object).getContent();
    }
    return object;
  }

  /**
   * This is a convenience method for creating CommandParameters
   * for a given parent feature and child object.
   */
  protected CommandParameter createChildParameter(EReference feature,
                                                  XSDConcreteComponent child)
  {
    return new CommandParameter(null, feature, child);
  }

  /**
   * This is a convenience method for creating {@link CommandParameter}s
   * for model groups of two or all of the three compositor types
   * (choice, sequence, and optionally all, depending on the value of
   * all) and adding them to a newChildDescriptors
   * collection.  If useParticle is true, each
   * model group will be the content of a new particle.
   */
  protected void addModelGroupChildParameters(Collection newChildDescriptors,
                                              EReference feature,
                                              boolean all,
                                              boolean useParticle)
  {
    XSDCompositor[] compositor = { XSDCompositor.ALL_LITERAL, XSDCompositor.CHOICE_LITERAL, XSDCompositor.SEQUENCE_LITERAL };
    for (int i = all ? 0 : 1; i < compositor.length; i++)
    {
      XSDModelGroup mg = xsdFactory.createXSDModelGroup();
      mg.setCompositor(compositor[i]);
      XSDConcreteComponent child = mg;
      if (useParticle)
      {
        child = createParticle(mg, false);
      }
      newChildDescriptors.add(createChildParameter(feature, child));
    }
  }

  /**
   * This is a convenience method for creating {@link CommandParameter}s
   * for simple type definitions of zero, one, two, or all of three
   * varieties (atomic, list, and union), and adding them to a
   * newChildDescriptors collection.  The simple type
   * definition objects are to be added to the specified
   * feature of parent.  The varieties for which
   * to create simple type definitions and command parameters are specified
   * by the three boolean arguments, atomic, list,
   * and union.
   */
  protected void addSimpleTypeDefinitionChildParameters
    (Collection newChildDescriptors, 
     XSDConcreteComponent parent,
     EReference feature, 
     boolean atomic, 
     boolean list, 
     boolean union)
  {
    XSDSchema xsdSchema = parent.getSchema();
    if (xsdSchema != null)
    {
      XSDSimpleTypeDefinition baseType = parent.getSchema().getSchemaForSchema().resolveSimpleTypeDefinition("string");
  
      if (atomic)
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition = createSimpleTypeDefinition(parent);
        xsdSimpleTypeDefinition.setVariety(XSDVariety.ATOMIC_LITERAL);
        xsdSimpleTypeDefinition.setBaseTypeDefinition(baseType);
        newChildDescriptors.add(createChildParameter(feature, xsdSimpleTypeDefinition));
      }
  
      if (list)
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition = createSimpleTypeDefinition(parent);
        xsdSimpleTypeDefinition.setVariety(XSDVariety.LIST_LITERAL);
        xsdSimpleTypeDefinition.setItemTypeDefinition(baseType);
        newChildDescriptors.add(createChildParameter(feature, xsdSimpleTypeDefinition));
      }
  
      if (union)
      {
        XSDSimpleTypeDefinition xsdSimpleTypeDefinition = createSimpleTypeDefinition(parent);
        xsdSimpleTypeDefinition.setVariety(XSDVariety.UNION_LITERAL);
        xsdSimpleTypeDefinition.getMemberTypeDefinitions().add(baseType);
        newChildDescriptors.add(createChildParameter(feature, xsdSimpleTypeDefinition));
      }
    }
  }

  /**
   * This determines whether an object represents a global element,
   * based on the type of its parent.
   */
  protected boolean isGlobal(Object parent)
  {
    return (parent instanceof XSDSchema || parent instanceof XSDRedefine);
  }

  /**
   * This creates an object of type XSDAttributeDeclaration
   * with a name that is unique globally (compared to other global attribute
   * declarations) or locally (compared to sibling attribute declarations
   * and children of sibling attribute groups), depending on the type of the
   * specified parent.  The created object will be initialized
   * to resolve to itself and to have the string type
   * definition.
   * 
   * 

Note: in determining local uniqueness, we do not consider any * referenced uses of the parent group or type elsewhere in the schema. */ protected XSDAttributeDeclaration createAttributeDeclaration(XSDConcreteComponent parent) { XSDAttributeDeclaration child = null; String baseName = getNewObjectName(xsdPackage.getXSDAttributeDeclaration().getName()); if (isGlobal(parent)) { String name = null; int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; child = parent.resolveAttributeDeclaration(name); } while (((EObject) child).eContainer() != null); } else { XSDSchema schema = parent.getSchema(); // use the namespace from the schema in determining local uniqueness // only if new local declarations will be qualified by default String namespace = null; if (schema != null && schema.getAttributeFormDefault() == XSDForm.QUALIFIED_LITERAL) { namespace = schema.getTargetNamespace(); } Collection siblings = getAttributeSiblings(parent); String name = null; int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; } while (!isUniqueAttributeDeclarationName(name, namespace, siblings)); child = xsdFactory.createXSDAttributeDeclaration(); child.setName(name); if (namespace != null) { child.setTargetNamespace(namespace); } child.setResolvedAttributeDeclaration(child); } // initialize element type to be string child.setTypeDefinition(parent.getSchema().getSchemaForSchema().resolveSimpleTypeDefinition("string")); return child; } /** * This gathers and returns the siblings by stepping up through any * attribute group definitions to the top-most parent attribute definition * or complex type definition, and returning the attribute uses for it. * Returns null if there is no such parent. */ protected Collection getAttributeSiblings(XSDConcreteComponent parent) { Collection siblings = null; if (parent instanceof XSDAttributeGroupDefinition) { XSDAttributeGroupDefinition group = (XSDAttributeGroupDefinition)parent; while (group.eContainer() instanceof XSDAttributeGroupDefinition) { group = (XSDAttributeGroupDefinition) group.eContainer(); } if (group.eContainer() instanceof XSDComplexTypeDefinition) { parent = (XSDComplexTypeDefinition) group.eContainer(); } else { siblings = group.getAttributeUses(); } } if (parent instanceof XSDComplexTypeDefinition) { siblings = ((XSDComplexTypeDefinition) parent).getAttributeUses(); } return siblings; } /** * This tests whether the combination of given localName and * targetNamespace is shared by an attribute declaration of * an attribute use in the given collection. Returns false * if so, true otherwise. Note that this method is tolerant * of nulls: a result of true is returned if * attributeUse is null, and two null strings * are considered equal. */ protected boolean isUniqueAttributeDeclarationName(String localName, String targetNamespace, Collection attributeUses) { if (attributeUses != null) { for (XSDAttributeUse attributeUse : attributeUses) { if (attributeUse.getAttributeDeclaration() != null) { XSDAttributeDeclaration other = attributeUse.getAttributeDeclaration(); if (other.hasNameAndTargetNamespace(localName, targetNamespace)) { return false; } } } } return true; } /** * This creates an object of type XSDElementDeclaration * with a name that is unique globally or locally, depending on the type * of the specified parent. The created object will be * initialized to resolve to itself and to have the string * type definition. * *

Note: in determining local uniqueness, we do not consider any * referenced uses of the parent group or type elsewhere in the schema. */ protected XSDElementDeclaration createElementDeclaration(XSDConcreteComponent parent) { XSDElementDeclaration child = null; String baseName = getNewObjectName(xsdPackage.getXSDElementDeclaration().getName()); if (isGlobal(parent)) { String name = null; int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; child = parent.resolveElementDeclaration(name); } while (((EObject) child).eContainer() != null); } else { XSDSchema schema = parent.getSchema(); // use the namespace from the schema in determining local uniqueness // only if new local declarations will be qualified by default String namespace = null; if (schema != null && schema.getElementFormDefault() == XSDForm.QUALIFIED_LITERAL) { namespace = schema.getTargetNamespace(); } XSDModelGroup modelGroup = getTopModelGroup(parent); String name = null; int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; } while (!isUniqueElementDeclarationName(name, namespace, modelGroup, null)); child = xsdFactory.createXSDElementDeclaration(); child.setName(name); if (namespace != null) { child.setTargetNamespace(namespace); } child.setResolvedElementDeclaration(child); } // initialize attribute type to be string child.setTypeDefinition(parent.getSchema().getSchemaForSchema().resolveSimpleTypeDefinition("string")); return child; } /** * If the specified parent is a model group, this finds and returns the * top-most model group above it (within the same complex type or model * group definition). Otherwise, returns null. */ protected XSDModelGroup getTopModelGroup(XSDConcreteComponent parent) { XSDModelGroup modelGroup = null; if (parent instanceof XSDModelGroup) { modelGroup = (XSDModelGroup) parent; while (parent.eContainer() instanceof XSDParticle || parent.eContainer() instanceof XSDModelGroup) { parent = (XSDConcreteComponent) parent.eContainer(); if (parent instanceof XSDModelGroup) { modelGroup = (XSDModelGroup) parent; } } } return modelGroup; } /** * This tests whether the combination of given localName * and targetNamespace is shared by an element declaration in * the given model group or a model group under it. Returns * false if so, true otherwise. Note that this * method is tolerant of nulls: a result of true is * returned if modelGroup is null, and two * null strings are considered equal. Also, note that the * visited argument is used to avoid an infinite recursion * situation, and should be null when the method is initially * called. */ protected boolean isUniqueElementDeclarationName(String localName, String targetNamespace, XSDModelGroup modelGroup, HashSet visited) { if (visited == null) { visited = new HashSet(); } if (modelGroup != null && visited.add(modelGroup) && modelGroup.getParticles() != null) { for (XSDParticle particle : modelGroup.getParticles()) { if (particle.getTerm() instanceof XSDElementDeclaration) { XSDElementDeclaration other = (XSDElementDeclaration) particle.getTerm(); if (other.hasNameAndTargetNamespace(localName, targetNamespace)) { return false; } } else if (particle.getTerm() instanceof XSDModelGroup) { XSDModelGroup others = (XSDModelGroup) particle.getTerm(); if (!isUniqueElementDeclarationName(localName, targetNamespace, others, visited)) { return false; } } } } return true; } /** * This creates an object of type XSDAttributeGroupDefinition * with a name that is unique globally, and that resolves to * itself. The created object is to be added under the specified * parent. */ protected XSDAttributeGroupDefinition createAttributeGroupDefinition(XSDConcreteComponent parent) { XSDAttributeGroupDefinition child = null; String name = null; String baseName = getNewObjectName(xsdPackage.getXSDAttributeGroupDefinition().getName()); int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; child = parent.resolveAttributeGroupDefinition(name); } while (((EObject) child).eContainer() != null); return child; } /** * This creates an object of type XSDModelGroupDefinition * with a name that is unique globally, and that resolves to * itself. The created object is to be added under the specified * parent. */ protected XSDModelGroupDefinition createModelGroupDefinition(XSDConcreteComponent parent) { XSDModelGroupDefinition child = null; String name = null; String baseName = getNewObjectName(xsdPackage.getXSDModelGroupDefinition().getName()); int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; child = parent.resolveModelGroupDefinition(name); } while (((EObject) child).eContainer() != null); return child; } /** * This creates an object of type XSDComplexTypeDefinition * with a name that is unique globally, if this is to be a global * definition; otherwise, with no name. The created object is to be * added under the specified parent. */ protected XSDComplexTypeDefinition createComplexTypeDefinition(XSDConcreteComponent parent) { XSDComplexTypeDefinition child = null; if (isGlobal(parent)) { String name = null; String baseName = getNewObjectName(xsdPackage.getXSDComplexTypeDefinition().getName()); int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; child = parent.resolveComplexTypeDefinition(name); } while (((EObject) child).eContainer() != null); } else { child = xsdFactory.createXSDComplexTypeDefinition(); } return child; } /** * This creates an object of type XSDSimpleTypeDefinition * with a name that is unique globally, if this is to be a global * definition; otherwise, with no name. The created object is to be * added under the specified parent. */ protected XSDSimpleTypeDefinition createSimpleTypeDefinition(XSDConcreteComponent parent) { XSDSimpleTypeDefinition child = null; if (isGlobal(parent)) { String name = null; String baseName = getNewObjectName(xsdPackage.getXSDSimpleTypeDefinition().getName()); int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; child = parent.resolveSimpleTypeDefinition(name); } while (((EObject) child).eContainer() != null); } else { child = xsdFactory.createXSDSimpleTypeDefinition(); } return child; } /** * This creates an object of type * XSDIdentityConstraintDefinition with a name that is unique * globally. The created object is to be added under the specified * parent. */ protected XSDIdentityConstraintDefinition createIdentityConstraintDefinition(XSDConcreteComponent parent) { XSDIdentityConstraintDefinition child = null; String name = null; String baseName = getNewObjectName(xsdPackage.getXSDIdentityConstraintDefinition().getName()); int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; child = parent.resolveIdentityConstraintDefinition(name); } while (((EObject) child).eContainer() != null); return child; } /** * This creates an object of type XSDNotationDeclaration with * a name that is unique globally. The created object, to be added * under the specified parent, will have an empty string as * its public identifier. */ protected XSDNotationDeclaration createNotationDeclaration(XSDConcreteComponent parent) { XSDNotationDeclaration child = null; String name = null; String baseName = getNewObjectName(xsdPackage.getXSDNotationDeclaration().getName()); int i = 0; do { name = baseName + ((i > 0) ? String.valueOf(i) : ""); i = (i > 0) ? i + 1 : 1; child = parent.resolveNotationDeclaration(name); } while (((EObject) child).eContainer() != null); child.setPublicIdentifier(""); return child; } /** * This creates an object of type XSDAttributeUse containing * an object of type XSDAttributeDeclaration -- if * isReference is true, the attribute use * content will be a new attribute declaration that resolves to * attributeDeclaration; otherwise, it will be simply * attributeDeclaration itself. */ protected XSDAttributeUse createAttributeUse(XSDAttributeDeclaration attributeDeclaration, boolean isReference) { XSDAttributeUse au = xsdFactory.createXSDAttributeUse(); if (isReference) { XSDAttributeDeclaration ref = xsdFactory.createXSDAttributeDeclaration(); ref.setResolvedAttributeDeclaration(attributeDeclaration); au.setContent(ref); } else { au.setContent(attributeDeclaration); } return au; } /** * This creates an object of type XSDAttributeGroupDefinition * that resolves to attributeGroupDefinition. */ protected XSDAttributeGroupDefinition createAttributeGroupDefinitionReference(XSDAttributeGroupDefinition attributeGroupDefinition) { XSDAttributeGroupDefinition ref = xsdFactory.createXSDAttributeGroupDefinition(); ref.setResolvedAttributeGroupDefinition(attributeGroupDefinition); return ref; } /** * This creates an object of type XSDParticle containing * an object of type XSDParticleContent -- if either * particleContent is an element declaration and * isReference is true or * particleContent is a model group definition, the particle * content will be a new element declaration that resolves to * particleContent; otherwise, it will be simply * particleContent itself. */ protected XSDParticle createParticle(XSDParticleContent particleContent, boolean isReference) { XSDParticle p = xsdFactory.createXSDParticle(); if (particleContent instanceof XSDModelGroupDefinition) { XSDModelGroupDefinition ref = xsdFactory.createXSDModelGroupDefinition(); ref.setResolvedModelGroupDefinition((XSDModelGroupDefinition) particleContent); p.setContent(ref); } else if (particleContent instanceof XSDElementDeclaration && isReference) { XSDElementDeclaration ref = xsdFactory.createXSDElementDeclaration(); ref.setResolvedElementDeclaration((XSDElementDeclaration) particleContent); p.setContent(ref); } else { p.setContent(particleContent); } return p; } /** * This returns the translated name for a new object with the specified * type name. */ protected String getNewObjectName(String typeName) { return XSDEditPlugin.INSTANCE.getString("_UI_" + typeName + "_new_object"); } /** * This returns the default result collection for {@link CreateChildCommand}. */ @Override public Collection getCreateChildResult(Object child) { Collection result = new ArrayList(1); result.add(child); return result; } /** * This returns the translated label for {@link CreateChildCommand}. */ @Override public String getCreateChildText(Object parent, Object feature, Object child, Collection selection) { child = getParticleOrAttributeUseContent(child); EReference refFeature = feature instanceof EReference ? (EReference) feature : null; String qualifier = getTypeTextQualifier(parent, refFeature, child); return getTypeText(child, qualifier); } /** * This returns the translated description for {@link CreateChildCommand}. */ @Override public String getCreateChildDescription(Object parent, Object feature, Object child, Collection selection) { child = getParticleOrAttributeUseContent(child); EReference refFeature = feature instanceof EReference ? (EReference) feature : null; String qualifier = getTypeTextQualifier(parent, refFeature, child); Object selectedObject = selection == null || selection.isEmpty() ? null : getParticleOrAttributeUseContent(selection.iterator().next()); if (parent != selectedObject) { return XSDEditPlugin.INSTANCE.getString ("_UI_CreateSibling_description", new Object [] { getTypeText(child, qualifier), getTypeText(selectedObject, null) }); } else { return XSDEditPlugin.INSTANCE.getString ("_UI_CreateChild_description", new Object [] { getTypeText(child, qualifier), getTypeText(parent, null) }); } } /** * This returns the translated tool tip for {@link CreateChildCommand}. */ @Override public String getCreateChildToolTipText(Object parent, Object feature, Object child, Collection selection) { child = getParticleOrAttributeUseContent(child); EReference refFeature = feature instanceof EReference ? (EReference) feature : null; String qualifier = getTypeTextQualifier(parent, refFeature, child); Object selectedObject = selection == null || selection.isEmpty() ? null : getParticleOrAttributeUseContent(selection.iterator().next()); if (parent != selectedObject) { return XSDEditPlugin.INSTANCE.getString ("_UI_CreateSibling_tooltip", new Object [] { getTypeText(child, qualifier), getTypeText(selectedObject, null) }); } else { return XSDEditPlugin.INSTANCE.getString ("_UI_CreateChild_tooltip", new Object [] { getTypeText(child, qualifier), getTypeText(parent, null) }); } } /** * This gets the translated string for object's type, * qualified by qualifier, if it is non-null. */ protected String getTypeText(Object object, String qualifier) { StringBuffer typeKey = new StringBuffer("_UI_"); typeKey.append(object instanceof EObject ? ((EObject) object).eClass().getName() : "Unknown"); typeKey.append("_type"); if (qualifier != null) { typeKey.append('_'); typeKey.append(qualifier); } return XSDEditPlugin.INSTANCE.getString(typeKey.toString()); } /** * This returns the icon for {@link CreateChildCommand}. */ @Override public Object getCreateChildImage(Object parent, Object feature, Object child, Collection selection) { child = getParticleOrAttributeUseContent(child); Object image = null; if (child instanceof EObject) { StringBuffer imageName = new StringBuffer("full/obj16/"); String typeName = ((EObject) child).eClass().getName(); EReference refFeature = feature instanceof EReference ? (EReference) feature : null; String qualifier = getImageNameQualifier(parent, refFeature, child); // kludge: drop Declaration or Definition when qualifier is Use int i = "Use".equals(qualifier) ? typeName.lastIndexOf('D') : 0; if (i > 0) { typeName = typeName.substring(0, i); } imageName.append(typeName); if (qualifier != null) { imageName.append(qualifier); } image = XSDEditPlugin.INSTANCE.getImage(imageName.toString()); } return image; } /** * This generates and returns a qualifier string, for use in forming the * type key, based on the state of the child object, its parent, and the * feature under which it is to be added. */ protected String getTypeTextQualifier(Object parent, EReference feature, Object child) { return getQualifier(parent, feature, child); } /** * This generates and returns a qualifier string, for use in forming the * icon filename, based on the state of the child object, its parent, and * the feature under which is to be added. */ protected String getImageNameQualifier(Object parent, EReference feature, Object child) { // kludge: there is only one annotation icon Object p = child instanceof XSDAnnotation ? null : parent; String qualifier = getQualifier(p, feature, child); // a little translation if ("keyref".equals(qualifier)) { qualifier = "KeyReference"; } else if ("reference".equals(qualifier)) { qualifier = "Use"; } else if (qualifier != null && qualifier.length() > 0) { // capitalize StringBuffer buffer = new StringBuffer(qualifier); char c = buffer.charAt(0); buffer.setCharAt(0, Character.toUpperCase(c)); qualifier = buffer.toString(); } return qualifier; } /** * This does common stuff for getTypeTextQualifier() and * getImageNameQualifier(). */ private String getQualifier(Object parent, EReference feature, Object child) { String qualifier = null; // qualification for feature declaration or group definition reference if ((child instanceof XSDElementDeclaration && ((XSDElementDeclaration) child).isElementDeclarationReference()) || (child instanceof XSDAttributeDeclaration && ((XSDAttributeDeclaration) child).isAttributeDeclarationReference()) || (child instanceof XSDModelGroupDefinition && ((XSDModelGroupDefinition) child).isModelGroupDefinitionReference()) || (child instanceof XSDAttributeGroupDefinition && ((XSDAttributeGroupDefinition) child).isAttributeGroupDefinitionReference())) { qualifier = "reference"; } // qualification by compositor for model group else if (child instanceof XSDModelGroup) { qualifier = ((XSDModelGroup) child).getCompositor().getName(); } // qualification by variety for simple type definition else if (child instanceof XSDSimpleTypeDefinition) { qualifier = ((XSDSimpleTypeDefinition) child).getVariety().getName(); } // qualification by category for identity constraint definition else if (child instanceof XSDIdentityConstraintDefinition) { qualifier = ((XSDIdentityConstraintDefinition) child).getIdentityConstraintCategory().getName(); } // qualification by variety for xpath definition else if (child instanceof XSDXPathDefinition) { qualifier = ((XSDXPathDefinition) child).getVariety().getName(); } // qualification according to parent for wildcard else if (child instanceof XSDWildcard) { if (parent instanceof XSDAttributeGroupDefinition || parent instanceof XSDComplexTypeDefinition) { qualifier = "attribute"; } else if (parent instanceof XSDModelGroup) { qualifier = "element"; } } // qualification by feature name for annotation under type definition else if (child instanceof XSDAnnotation && parent instanceof XSDTypeDefinition && feature != null) { qualifier = feature.getName(); } return qualifier; } }