| /** |
| * 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<IItemPropertyDescriptor> getPropertyDescriptors(final Object object) |
| { |
| if (itemPropertyDescriptors == null) |
| { |
| itemPropertyDescriptors = |
| new ArrayList<IItemPropertyDescriptor>() |
| { |
| 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<Object> newResult = new ArrayList<Object>(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 <code>object</code> is a particle or an attribute use, this returns |
| * its content; otherwise, <code>object</code> 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 <code>CommandParameter</code>s |
| * 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 |
| * <code>all</code>) and adding them to a <code>newChildDescriptors</code> |
| * collection. If <code>useParticle</code> is <code>true</code>, each |
| * model group will be the content of a new particle. |
| */ |
| protected void addModelGroupChildParameters(Collection<Object> 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 |
| * <code>newChildDescriptors</code> collection. The simple type |
| * definition objects are to be added to the specified |
| * <code>feature</code> of <code>parent</code>. The varieties for which |
| * to create simple type definitions and command parameters are specified |
| * by the three boolean arguments, <code>atomic</code>, <code>list</code>, |
| * and <code>union</code>. |
| */ |
| protected void addSimpleTypeDefinitionChildParameters |
| (Collection<Object> 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 <code>XSDAttributeDeclaration</code> |
| * 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 <code>parent</code>. The created object will be initialized |
| * to resolve to itself and to have the <code>string</code> type |
| * definition. |
| * |
| * <p>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<? extends XSDAttributeUse> 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 <code>null</code> if there is no such parent. |
| */ |
| protected Collection<? extends XSDAttributeUse> getAttributeSiblings(XSDConcreteComponent parent) |
| { |
| Collection<XSDAttributeUse> 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 <code>localName</code> and |
| * <code>targetNamespace</code> is shared by an attribute declaration of |
| * an attribute use in the given collection. Returns <code>false</code> |
| * if so, <code>true</code> otherwise. Note that this method is tolerant |
| * of nulls: a result of <code>true</code> is returned if |
| * <code>attributeUse</code> is <code>null</code>, and two null strings |
| * are considered equal. |
| */ |
| protected boolean isUniqueAttributeDeclarationName(String localName, String targetNamespace, Collection<? extends XSDAttributeUse> 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 <code>XSDElementDeclaration</code> |
| * with a name that is unique globally or locally, depending on the type |
| * of the specified <code>parent</code>. The created object will be |
| * initialized to resolve to itself and to have the <code>string</code> |
| * type definition. |
| * |
| * <p>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 <code>null</code>. |
| */ |
| 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 <code>localName</code> |
| * and <code>targetNamespace</code> is shared by an element declaration in |
| * the given model group or a model group under it. Returns |
| * <code>false</code> if so, <code>true</code> otherwise. Note that this |
| * method is tolerant of nulls: a result of <code>true</code> is |
| * returned if <code>modelGroup</code> is <code>null</code>, and two |
| * null strings are considered equal. Also, note that the |
| * <code>visited</code> argument is used to avoid an infinite recursion |
| * situation, and should be <code>null</code> when the method is initially |
| * called. |
| */ |
| protected boolean isUniqueElementDeclarationName(String localName, String targetNamespace, XSDModelGroup modelGroup, HashSet<XSDModelGroup> visited) |
| { |
| if (visited == null) |
| { |
| visited = new HashSet<XSDModelGroup>(); |
| } |
| |
| 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 <code>XSDAttributeGroupDefinition</code> |
| * with a name that is unique globally, and that resolves to |
| * itself. The created object is to be added under the specified |
| * <code>parent</code>. |
| */ |
| 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 <code>XSDModelGroupDefinition</code> |
| * with a name that is unique globally, and that resolves to |
| * itself. The created object is to be added under the specified |
| * <code>parent</code>. |
| */ |
| 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 <code>XSDComplexTypeDefinition</code> |
| * 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 <code>parent</code>. |
| */ |
| 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 <code>XSDSimpleTypeDefinition</code> |
| * 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 <code>parent</code>. |
| */ |
| 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 |
| * <code>XSDIdentityConstraintDefinition</code> with a name that is unique |
| * globally. The created object is to be added under the specified |
| * <code>parent</code>. |
| */ |
| 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 <code>XSDNotationDeclaration</code> with |
| * a name that is unique globally. The created object, to be added |
| * under the specified <code>parent</code>, 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 <code>XSDAttributeUse</code> containing |
| * an object of type <code>XSDAttributeDeclaration</code> -- if |
| * <code>isReference</code> is <code>true</code>, the attribute use |
| * content will be a new attribute declaration that resolves to |
| * <code>attributeDeclaration</code>; otherwise, it will be simply |
| * <code>attributeDeclaration</code> 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 <code>XSDAttributeGroupDefinition</code> |
| * that resolves to <code>attributeGroupDefinition</code>. |
| */ |
| protected XSDAttributeGroupDefinition createAttributeGroupDefinitionReference(XSDAttributeGroupDefinition attributeGroupDefinition) |
| { |
| XSDAttributeGroupDefinition ref = |
| xsdFactory.createXSDAttributeGroupDefinition(); |
| ref.setResolvedAttributeGroupDefinition(attributeGroupDefinition); |
| return ref; |
| } |
| |
| /** |
| * This creates an object of type <code>XSDParticle</code> containing |
| * an object of type <code>XSDParticleContent</code> -- if either |
| * <code>particleContent</code> is an element declaration and |
| * <code>isReference</code> is <code>true</code> or |
| * <code>particleContent</code> is a model group definition, the particle |
| * content will be a new element declaration that resolves to |
| * <code>particleContent</code>; otherwise, it will be simply |
| * <code>particleContent</code> 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<Object> result = new ArrayList<Object>(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 <code>object</code>'s type, |
| * qualified by <code>qualifier</code>, 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; |
| } |
| } |