Package tk.eclipse.plugin.xmleditor.editors

Source Code of tk.eclipse.plugin.xmleditor.editors.XMLAssistProcessor

package tk.eclipse.plugin.xmleditor.editors;

import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jp.aonir.fuzzyxml.FuzzyXMLAttribute;
import jp.aonir.fuzzyxml.FuzzyXMLElement;

import org.apache.xerces.impl.xs.SchemaGrammar;
import org.apache.xerces.impl.xs.XMLSchemaLoader;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.apache.xerces.xs.XSAttributeDeclaration;
import org.apache.xerces.xs.XSAttributeUse;
import org.apache.xerces.xs.XSComplexTypeDefinition;
import org.apache.xerces.xs.XSConstants;
import org.apache.xerces.xs.XSElementDeclaration;
import org.apache.xerces.xs.XSModelGroup;
import org.apache.xerces.xs.XSNamedMap;
import org.apache.xerces.xs.XSObject;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSParticle;
import org.apache.xerces.xs.XSTerm;
import org.apache.xerces.xs.XSTypeDefinition;
import org.eclipse.ui.IFileEditorInput;

import tk.eclipse.plugin.htmleditor.HTMLPlugin;
import tk.eclipse.plugin.htmleditor.assist.AssistInfo;
import tk.eclipse.plugin.htmleditor.assist.AttributeInfo;
import tk.eclipse.plugin.htmleditor.assist.HTMLAssistProcessor;
import tk.eclipse.plugin.htmleditor.assist.TagInfo;

import com.wutka.dtd.DTD;
import com.wutka.dtd.DTDAttribute;
import com.wutka.dtd.DTDChoice;
import com.wutka.dtd.DTDDecl;
import com.wutka.dtd.DTDElement;
import com.wutka.dtd.DTDEmpty;
import com.wutka.dtd.DTDEnumeration;
import com.wutka.dtd.DTDItem;
import com.wutka.dtd.DTDMixed;
import com.wutka.dtd.DTDName;
import com.wutka.dtd.DTDParseException;
import com.wutka.dtd.DTDParser;
import com.wutka.dtd.DTDSequence;

/**
* AssistProcessor for the XML editor.
*/
public class XMLAssistProcessor extends HTMLAssistProcessor {

  private List tagList = new ArrayList();
  private Map nsTagListMap = new HashMap();
//  private TagInfo root = null;
 
  /**
   * The constructor without DTD / XSD.
   * XMLAssistProcessor that's created by this constructor completes only close tags.
   */
  public XMLAssistProcessor(){
    super();
  }
 
  /**
   * Update informations about code-completion.
   *
   * @param input  IFileEditorInput
   * @param source JSP
   */
  public void update(IFileEditorInput input,String source){
    // nothing to do.
  }
 
  /**
   * Refresh DTD informations.
   *
   * @param in InputStream of DTD
   */
  public void updateDTDInfo(Reader in){
    // clear at fisrt
    tagList.clear();
//    root = null;
    try {
      DTDParser parser = new DTDParser(in);
      DTD dtd = parser.parse();
      Object[] obj = dtd.getItems();
      for(int i=0;i<obj.length;i++){
        if(obj[i] instanceof DTDElement){
          DTDElement element = (DTDElement)obj[i];
          String name = element.getName();
          DTDItem item = element.getContent();
          boolean hasBody = true;
          if(item instanceof DTDEmpty){
            hasBody = false;
          }
          TagInfo tagInfo = new TagInfo(name,hasBody);
          Iterator ite = element.attributes.keySet().iterator();
         
          // set child tags
          if(item instanceof DTDSequence){
            DTDSequence seq = (DTDSequence)item;
            setChildTagName(tagInfo,seq.getItem());
          } else if(item instanceof DTDMixed){
            // #PCDATA
          }
         
          while(ite.hasNext()){
            String attrName = (String)ite.next();
            DTDAttribute attr = element.getAttribute(attrName);
           
            DTDDecl decl = attr.getDecl();
            boolean required = false;
            if(decl == DTDDecl.REQUIRED){
              required = true;
            }
           
            AttributeInfo attrInfo = new AttributeInfo(attrName,true,AttributeInfo.NONE,required);
            tagInfo.addAttributeInfo(attrInfo);
           
            Object attrType = attr.getType();
            if(attrType instanceof DTDEnumeration){
              DTDEnumeration dtdEnum = (DTDEnumeration)attrType;
              String[] items = dtdEnum.getItems();
              for(int j=0;j<items.length;j++){
                attrInfo.addValue(items[j]);
              }
            }
          }
          tagList.add(tagInfo);
          // TODO root tag is an element that was found at first.
        }
      }
    } catch(DTDParseException ex){
      // ignore
    } catch(Exception ex){
      HTMLPlugin.logException(ex);
    }
  }
 
  /**
   * Refresh XML schema informations
   *
   * @param uri URI of XML schema
   * @param in InputStream of XML schema
   */
  public void updateXSDInfo(String uri,Reader in){
    try {
      SchemaGrammar grammer = (SchemaGrammar)new XMLSchemaLoader().loadGrammar(
          new XMLInputSource(null,null,null,in,null));
     
      // clear at first
      String targetNS = grammer.getTargetNamespace();
      nsTagListMap.put(targetNS,new ArrayList());
      List tagList = (List)nsTagListMap.get(targetNS);
//      root = null;
     
      XSNamedMap map = grammer.getComponents(XSConstants.ELEMENT_DECLARATION);
      for(int i=0;i<map.getLength();i++){
        XSElementDeclaration element = (XSElementDeclaration)map.item(i);
        parseXSDElement(tagList,element);
      }
    } catch(Exception ex){
     
    }
  }
 
  private void parseXSDElement(List tagList, XSElementDeclaration element){
    TagInfo tagInfo = new TagInfo(element.getName(),true);
    if(tagList.contains(tagInfo)){
      return;
    }
    tagList.add(tagInfo);
   
    XSTypeDefinition type = element.getTypeDefinition();
    if(type instanceof XSComplexTypeDefinition){
      XSParticle particle = ((XSComplexTypeDefinition)type).getParticle();
      if(particle!=null){
        XSTerm term = particle.getTerm();
        if(term instanceof XSElementDeclaration){
          parseXSDElement(tagList,(XSElementDeclaration)term);
          tagInfo.addChildTagName(((XSElementDeclaration)term).getName());
        }
        if(term instanceof XSModelGroup){
          parseXSModelGroup(tagInfo, tagList, (XSModelGroup)term);
        }
      }
      XSObjectList attrs = ((XSComplexTypeDefinition)type).getAttributeUses();
      for(int i=0;i<attrs.getLength();i++){
        XSAttributeUse attrUse = (XSAttributeUse)attrs.item(i);
        XSAttributeDeclaration attr = attrUse.getAttrDeclaration();
        AttributeInfo attrInfo = new AttributeInfo(attr.getName(),true,AttributeInfo.NONE,attrUse.getRequired());
        tagInfo.addAttributeInfo(attrInfo);
      }
     
    }
  }
 
  private void parseXSModelGroup(TagInfo tagInfo, List tagList, XSModelGroup term){
    XSObjectList list = ((XSModelGroup)term).getParticles();
    for(int i=0;i<list.getLength();i++){
      XSObject obj = list.item(i);
     
      if(obj instanceof XSParticle){
        XSTerm term2 = ((XSParticle)obj).getTerm();
       
        if(term2 instanceof XSElementDeclaration){
          parseXSDElement(tagList,(XSElementDeclaration)term2);
          tagInfo.addChildTagName(((XSElementDeclaration)term2).getName());
        }
        if(term2 instanceof XSModelGroup){
          parseXSModelGroup(tagInfo, tagList, (XSModelGroup)term2);
        }
      }
    }
  }
 
  /**
   * Sets a child tag name to TagInfo.
   *
   * @param tagInfo TagInfo
   * @param items an array of DTDItem
   */
  private void setChildTagName(TagInfo tagInfo,DTDItem[] items){
    for(int i=0;i<items.length;i++){
      if(items[i] instanceof DTDName){
        DTDName dtdName = (DTDName)items[i];
        tagInfo.addChildTagName(dtdName.getValue());
      } else if(items[i] instanceof DTDChoice){
        DTDChoice dtdChoise = (DTDChoice)items[i];
        setChildTagName(tagInfo,dtdChoise.getItem());
      }
    }
  }
 
  protected boolean supportTagRelation(){
    return true;
  }
 
  /**
   * Returns an array of an attribute value proposal to complete an attribute value.
   *
   * @param tagName tag name
   * @param value   inputed value
   * @param info    attribute information
   * @return an array of an attribute value proposal
   */
  protected AssistInfo[] getAttributeValues(String tagName,String value,AttributeInfo info){
      String[] values = info.getValues();
      AssistInfo[] infos = new AssistInfo[values.length];
      for(int i=0;i<infos.length;i++){
        infos[i] = new AssistInfo(values[i]);
      }
      return infos;
  }
 
  /**
   * Returns List of TagInfo.
   *
   * @return List of TagInfo
   */
  protected List getTagList(){
    ArrayList list = new ArrayList();
    list.addAll(this.tagList);
    // get namespace
    FuzzyXMLElement element = getOffsetElement();
    HashMap nsPrefixMap = new HashMap();
    getNamespace(nsPrefixMap,element);
    // add prefix to tag names
    Iterator ite = this.nsTagListMap.keySet().iterator();
    while(ite.hasNext()){
      String uri = (String)ite.next();
      String prefix = (String)nsPrefixMap.get(uri);
      if(prefix==null || prefix.equals("")){
        list.addAll((List)this.nsTagListMap.get(uri));
      } else {
        List nsTagList = (List)this.nsTagListMap.get(uri);
        for(int i=0;i<nsTagList.size();i++){
          TagInfo tagInfo = (TagInfo)nsTagList.get(i);
          list.add(createPrefixTagInfo(tagInfo,prefix));
        }
      }
    }
      return list;
  }
 
  /**
   * Adds prefix to TagInfo.
   */
  private TagInfo createPrefixTagInfo(TagInfo tagInfo,String prefix){
    TagInfo newTagInfo = new TagInfo(prefix + ":" + tagInfo.getTagName(),tagInfo.hasBody());
    AttributeInfo[] attrInfos = tagInfo.getAttributeInfo();
    for(int i=0;i<attrInfos.length;i++){
      AttributeInfo newAttrInfo = new AttributeInfo(
          prefix + ":" + attrInfos[i].getAttributeName(),
          true,
          AttributeInfo.NONE,
          attrInfos[i].isRequired());
      newTagInfo.addAttributeInfo(newAttrInfo);
    }
    String[] children = tagInfo.getChildTagNames();
    for(int i=0;i<children.length;i++){
      newTagInfo.addChildTagName(prefix + ":" + children[i]);
    }
    return newTagInfo;
  }
 
  /**
   * Returns mapping of namespace and prefix at the calet position.
   *
   * @param map
   * <ul>
   *   <li>key - namespace</li>
   *   <li>value - prefix</li>
   * </ul>
   * @param element FuzzyXMLElement at the calet position
   */
  private void getNamespace(Map map,FuzzyXMLElement element){
    FuzzyXMLAttribute[] attrs = element.getAttributes();
    for(int i=0;i<attrs.length;i++){
      if(attrs[i].getName().startsWith("xmlns")){
        String name = attrs[i].getName();
        String prefix = "";
        if(name.indexOf(":")>=0){
          prefix = name.substring(name.indexOf(":")+1);
        }
        if(map.get(attrs[i].getValue())==null){
          map.put(attrs[i].getValue(),prefix);
        }
      }
    }
    if(element.getParentNode()!=null){
      getNamespace(map,(FuzzyXMLElement)element.getParentNode());
    }
  }
 
  /**
   * Returns TagInfo.
   *
   * @param name tag name
   * @return TagInfo
   */
  protected TagInfo getTagInfo(String name){
    List tagList = getTagList();
    for(int i=0;i<tagList.size();i++){
      TagInfo info = (TagInfo)tagList.get(i);
      if(info.getTagName().equals(name)){
        return info;
      }
    }
    return null;
  }
}
TOP

Related Classes of tk.eclipse.plugin.xmleditor.editors.XMLAssistProcessor

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.