// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package com.amalto.workbench.providers; import java.util.ArrayList; import java.util.List; import org.eclipse.emf.common.util.EList; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.xsd.XSDAttributeGroupDefinition; import org.eclipse.xsd.XSDComplexTypeContent; import org.eclipse.xsd.XSDComplexTypeDefinition; import org.eclipse.xsd.XSDElementDeclaration; import org.eclipse.xsd.XSDIdentityConstraintDefinition; import org.eclipse.xsd.XSDModelGroup; import org.eclipse.xsd.XSDParticle; import org.eclipse.xsd.XSDSchema; import org.eclipse.xsd.XSDSimpleTypeDefinition; import org.eclipse.xsd.XSDTerm; import org.eclipse.xsd.XSDTypeDefinition; import org.eclipse.xsd.XSDVariety; import org.eclipse.xsd.XSDWildcard; import org.eclipse.xsd.util.XSDConstants; import org.w3c.dom.Element; import com.amalto.workbench.models.TreeObject; import com.amalto.workbench.utils.Util; public class XPathTreeContentProvider extends XSDTreeContentProvider { private String conceptName; private String filter; public String getConceptName() { return conceptName; } public void setConceptName(String conceptName) { this.conceptName = conceptName; } public XPathTreeContentProvider(IWorkbenchPartSite site, XSDSchema invisibleRoot, TreeObject treeObject, String filter) { super(site, invisibleRoot, treeObject); this.filter = filter; } @Override public Object[] getChildren(Object parent) { if (parent instanceof XSDSchema) { EList xsdElementDeclarations = xsdSchema.getElementDeclarations(); return filterOutDuplicatedElems(xsdElementDeclarations); } if (parent instanceof XSDAttributeGroupDefinition) { XSDAttributeGroupDefinition attributeGroupDefinition = (XSDAttributeGroupDefinition) parent; if (attributeGroupDefinition.getContents().size() == 0) // a ref attributeGroupDefinition = attributeGroupDefinition.getResolvedAttributeGroupDefinition(); return attributeGroupDefinition.getContents().toArray(new Object[attributeGroupDefinition.getContents().size()]); } if (parent instanceof XSDParticle) { // a particle inside a choice or sequence or whatever XSDParticle xsdParticle = (XSDParticle) parent; return getXSDParticleChildren(xsdParticle); }// XSDParticle /* * if (parent instanceof XSDTypeDefinition) { * * if (parent instanceof XSDSimpleTypeDefinition) { XSDSimpleTypeDefinition std = (XSDSimpleTypeDefinition) * parent; if (std.getVariety().equals(XSDVariety.ATOMIC_LITERAL)) { ArrayList list = new ArrayList(); //add * Base Type if not a pre-defined type if (! * std.getSchema().getSchemaForSchema().getTypeDefinitions().contains(std)) * list.add(std.getBaseTypeDefinition()); list.addAll(std.getFacetContents()); return list.toArray(new * Object[list.size()]); } if (std.getVariety().equals(XSDVariety.LIST_LITERAL)) { //FIXME: How do we indicate * it is a LIST? return new XSDSimpleTypeDefinition[] {std.getBaseTypeDefinition()}; } if * (std.getVariety().equals(XSDVariety.UNION_LITERAL)) return (XSDSimpleTypeDefinition[]) * (std.getMemberTypeDefinitions().toArray(new XSDSimpleTypeDefinition[std.getMemberTypeDefinitions().size()])); * //return new Object[]{std.getBaseTypeDefinition()}; } if (parent instanceof XSDComplexTypeDefinition) { * XSDComplexTypeContent xsdComplexTypeContent = ((XSDComplexTypeDefinition) parent).getContent(); * * ArrayList<Object> list = new ArrayList<Object>(); * list.addAll(((XSDComplexTypeDefinition)parent).getAttributeContents()); * * if (xsdComplexTypeContent == null) { XSDComplexTypeDefinition ctd = (XSDComplexTypeDefinition) parent; * list.add(ctd.getBaseTypeDefinition()); return list.toArray(new Object[list.size()]); } else { if * (xsdComplexTypeContent instanceof XSDSimpleTypeDefinition) { list.add(xsdComplexTypeContent); return * list.toArray(new Object[list.size()]); } if (xsdComplexTypeContent instanceof XSDParticle) return * getXSDParticleChildren((XSDParticle)xsdComplexTypeContent); //return children * list.add(((XSDComplexTypeDefinition) parent).getContent()); return list.toArray(new Object[list.size()]); } } * * } */ /* * if (parent instanceof XSDElementDeclaration) { ArrayList<Object> list = new ArrayList<Object>(); * * //handle extensions and retrictions directly XSDTypeDefinition typeDefinition = * ((XSDElementDeclaration)parent).getTypeDefinition(); if (typeDefinition instanceof XSDComplexTypeDefinition) * { XSDComplexTypeDefinition complexTypeDefinition = (XSDComplexTypeDefinition) typeDefinition; if * (complexTypeDefinition.getContent() == null) list.add(complexTypeDefinition.getBaseTypeDefinition()); else * list.add(complexTypeDefinition); } else { list.add(((XSDElementDeclaration)parent).getTypeDefinition()); } * * list.addAll(((XSDElementDeclaration)parent).getIdentityConstraintDefinitions()); return list.toArray(new * Object[list.size()]); } */ if (parent instanceof XSDModelGroup) { XSDModelGroup modelGroup = ((XSDModelGroup) parent); EList list = modelGroup.getContents(); return list.toArray(new Object[list.size()]); } if (parent instanceof XSDSimpleTypeDefinition) { XSDSimpleTypeDefinition std = (XSDSimpleTypeDefinition) parent; if (std.getVariety().equals(XSDVariety.ATOMIC_LITERAL)) { ArrayList list = new ArrayList(); // add Base Type if not a pre-defined type if (!std.getSchema().getSchemaForSchema().getTypeDefinitions().contains(std)) list.add(std.getBaseTypeDefinition()); list.addAll(std.getFacetContents()); return list.toArray(new Object[list.size()]); } if (std.getVariety().equals(XSDVariety.LIST_LITERAL)) { // FIXME: How do we indicate it is a LIST? return new XSDSimpleTypeDefinition[] { std.getBaseTypeDefinition() }; } if (std.getVariety().equals(XSDVariety.UNION_LITERAL)) return std.getMemberTypeDefinitions().toArray(new XSDSimpleTypeDefinition[std.getMemberTypeDefinitions().size()]); // return new Object[]{std.getBaseTypeDefinition()}; } if (parent instanceof XSDElementDeclaration) { // abstract elements do not have children if (((XSDElementDeclaration) parent).isAbstract()) return new Object[0]; ArrayList<Object> list = new ArrayList<Object>(); // handle extensions and restrictions directly XSDTypeDefinition typeDefinition = ((XSDElementDeclaration) parent).getTypeDefinition(); if (typeDefinition instanceof XSDComplexTypeDefinition) { list.addAll(getComplexTypeDefinitionChildren((XSDComplexTypeDefinition) typeDefinition)); } else { list.add(((XSDElementDeclaration) parent).getTypeDefinition()); } // the keys // list.addAll(((XSDElementDeclaration)parent).getIdentityConstraintDefinitions()); // the annotations // XSDAnnotation annotation = ((XSDElementDeclaration)parent).getAnnotation(); // if (annotation!=null) { // list.add(annotation); // } return list.toArray(new Object[list.size()]); } if (parent instanceof XSDIdentityConstraintDefinition) { ArrayList list = new ArrayList(); // list.add(((XSDIdentityConstraintDefinition)parent).getSelector()); // list.addAll(((XSDIdentityConstraintDefinition)parent).getFields()); return list.toArray(new Object[list.size()]); } // if (parent instanceof XSDAnnotation) { // XSDAnnotation annotation = (XSDAnnotation) parent; // ArrayList list = new ArrayList(); // list.addAll(annotation.getUserInformation()); // list.addAll(annotation.getApplicationInformation()); // return list.size()== 0 ? new Object[0] : list.toArray(new Object[list.size()]); // } if (parent instanceof Element) { // appinfos return new Object[0]; } // System.out.println("getChildren: UNPROCESSED PARENT: "+parent.getClass().getName()+": "+parent); return new Object[0]; } private Object[] getXSDParticleChildren(XSDParticle particle) { // System.out.println("getXSDParticleChildren() CLASS "+particle.getClass().getName()); // System.out.println("getXSDParticleChildren() TERM "+particle.getTerm().getClass().getName()+": "+particle.getTerm()); XSDTerm term = particle.getTerm(); if (term instanceof XSDElementDeclaration) { XSDTypeDefinition typeDef = ((XSDElementDeclaration) term).getTypeDefinition(); if (typeDef == null) return new Object[0]; // elements with not type declaration (allowed) ArrayList<Object> list = new ArrayList<Object>(); if (typeDef instanceof XSDComplexTypeDefinition) { list.addAll(getComplexTypeDefinitionChildren((XSDComplexTypeDefinition) typeDef)); } else { list.add(typeDef); } // list.addAll(((XSDElementDeclaration)term).getIdentityConstraintDefinitions()); // XSDAnnotation annotation = ((XSDElementDeclaration)term).getAnnotation(); // if (annotation!=null) { // list.add(annotation); // } return list.toArray(new Object[list.size()]); } if (term instanceof XSDModelGroup) {// a ModelGroup skip it and get children directtly EList list = ((XSDModelGroup) term).getContents(); return list.toArray(new XSDParticle[list.size()]); } if (term instanceof XSDWildcard) { } return new Object[] {}; } private ArrayList<Object> getComplexTypeDefinitionChildren(XSDComplexTypeDefinition complexTypeDefinition) { // System.out.println("getComplexTypeDefinitionChildren "+complexTypeDefinition+": "+complexTypeDefinition.getContent()); // System.out.println( // "getComplexTypeDefinitionChildren BASE TYPE "+ // complexTypeDefinition.getBaseTypeDefinition().getName()+" : "+ // complexTypeDefinition.getDerivationMethod().getName() // ); XSDComplexTypeContent xsdComplexTypeContent = complexTypeDefinition.getContent(); ArrayList<Object> list = new ArrayList<Object>(); // Now determine whether ref. If ref look at the base Type definition if (xsdComplexTypeContent == null) { XSDTypeDefinition typeDefinition = complexTypeDefinition.getBaseTypeDefinition(); // if a simple type return the simple type if (typeDefinition instanceof XSDSimpleTypeDefinition) { list.add(typeDefinition); return list; } else { } // it is a complex Type xsdComplexTypeContent = ((XSDComplexTypeDefinition) typeDefinition).getContent(); } // check if we are extending a complex Definition // if ("extension".equals(complexTypeDefinition.getDerivationMethod().getName())) { // if (complexTypeDefinition.getBaseTypeDefinition() instanceof XSDComplexTypeDefinition) { // list.addAll(getComplexTypeDefinitionChildren((XSDComplexTypeDefinition)complexTypeDefinition.getBaseTypeDefinition())); // } // } // Attributes if (complexTypeDefinition.getAttributeContents() != null) { list.addAll(complexTypeDefinition.getAttributeContents()); // XSDTypeDefinition baseTypeDef = complexTypeDefinition.getBaseTypeDefinition(); // while (baseTypeDef instanceof XSDComplexTypeDefinition // && (baseTypeDef.getTargetNamespace() == null || !baseTypeDef.getTargetNamespace().equals( // XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001))) { // XSDComplexTypeDefinition parentType = (XSDComplexTypeDefinition) baseTypeDef; // list.addAll(((XSDComplexTypeDefinition) baseTypeDef).getAttributeContents()); // list.addAll(getComplexTypeDefinitionChildren(parentType)); // baseTypeDef = baseTypeDef.getBaseType(); // } list.addAll(Util.getComplexTypeDefinitionChildren(complexTypeDefinition, true)); list.removeAll(complexTypeDefinition.getAnnotations()); return list; } // //Annotations // if (complexTypeDefinition.getAnnotations()!=null) // list.addAll(complexTypeDefinition.getAnnotations()); // now check what we have in the content // simple type return the simple type if (xsdComplexTypeContent instanceof XSDSimpleTypeDefinition) { list.add(xsdComplexTypeContent); return list; } // // xsd Particle: we have a model group // if (xsdComplexTypeContent instanceof XSDParticle) { // // System.out.println("Model Group?: "+((XSDParticle)xsdComplexTypeContent).getTerm()); // if (((XSDParticle) xsdComplexTypeContent).getTerm() instanceof XSDModelGroup) { // // return the model group // list.add(((XSDParticle) xsdComplexTypeContent).getTerm()); // return list; // } else { // wild card or element declaration '?) // list.add(((XSDParticle) xsdComplexTypeContent).getTerm()); // return list; // } // } // what else could it be ? list.add(xsdComplexTypeContent); return list; } private Object[] filterOutDuplicatedElems(List<XSDElementDeclaration> xsdElementDeclarations) { List<XSDElementDeclaration> list = new ArrayList<XSDElementDeclaration>(); for (XSDElementDeclaration el : (XSDElementDeclaration[]) xsdElementDeclarations .toArray(new XSDElementDeclaration[xsdElementDeclarations.size()])) { boolean exist = false; for (XSDElementDeclaration xsdEl : list) { if (xsdEl.getName().equals(el.getName()) && xsdEl.getTargetNamespace() != null && el.getTargetNamespace() != null && xsdEl.getTargetNamespace().equals(el.getTargetNamespace())) { exist = true; break; } else if (xsdEl.getName().equals(el.getName()) && xsdEl.getTargetNamespace() == null && el.getTargetNamespace() == null) { exist = true; break; } } if (!exist) { if ((conceptName != null && el.getName().equals(conceptName)) || (conceptName == null && (el.getTargetNamespace() != null && !el.getTargetNamespace().equals( XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001)) || (conceptName == null && el .getTargetNamespace() == null))) { // Add filter for the contentprovider which is used to construct the xpath tree. if (filter.equalsIgnoreCase("") || el.getName().toLowerCase().startsWith(filter.toLowerCase()))//$NON-NLS-1$ list.add(el); } } } return list.toArray(); } }