Package org.eclipse.wst.xml.ui.internal.contentassist.tapestry

Source Code of org.eclipse.wst.xml.ui.internal.contentassist.tapestry.TapestryRootComponentsProposalComputer

/*******************************************************************************
* Copyright (c) 2012 gavingui2011@gmail.com
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     gavingui2011@gmail.com  - initial API and implementation
*    
*******************************************************************************/

package org.eclipse.wst.xml.ui.internal.contentassist.tapestry;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.tapestrytools.ui.internal.tcc.editor.ComponentPackage;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.core.ClassFile;
import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.wst.xml.core.internal.contentmodel.tapestry.travelpackage.TapestryClassLoader;
import org.eclipse.wst.xml.core.internal.contentmodel.tapestry.travelpackage.TapestryCoreComponents;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class TapestryRootComponentsProposalComputer {
  private String webXMLPath = null;
  private List<Template> components = new ArrayList<Template>();
 
  public List<Template> getRootComponentsAttributes(IProject project, String contextTypeId, String nodeName){
    try {
      IJavaElement[] elements = getComponentsJavaElements(project);
      components.clear();
      for(IJavaElement ele : elements){
        if(ele.getElementType() == IJavaElement.COMPILATION_UNIT && ele.getElementName().endsWith(".java")){
          String name = ele.getElementName().substring(0, ele.getElementName().indexOf('.'));
          if( ("t:" + name).toLowerCase().equals(nodeName.toLowerCase())){
            goThroughClass((ICompilationUnit) ele, contextTypeId);
          }
        }
      }
      return components;
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
   
    return null;
  }
 
  private void goThroughClass(ICompilationUnit ClassContent, final String contextTypeId) {
    ASTParser parser = ASTParser.newParser(AST.JLS3);
    parser.setSource(ClassContent);
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
    cu.accept(new ASTVisitor() {
      private boolean parameter = false;
      private String paramName = "";
      public void endVisit(FieldDeclaration node) {
        paramName = "";
        parameter = false;
        node.accept(new ASTVisitor() {
          public void endVisit(MarkerAnnotation node) {
            parameter = node.getTypeName().toString()
                .equals(TapestryContants.ANNOTATION_PARAMETER);
            super.endVisit(node);
          }

          public void endVisit(NormalAnnotation node) {
            parameter = node.getTypeName().toString()
                .equals(TapestryContants.ANNOTATION_PARAMETER);
            List values = node.values();
            for (int i = 0; i < values.size(); i++) {
              MemberValuePair pair = (MemberValuePair) values
                  .get(i);
              if (pair.getName().toString().equals("read")
                  && pair.getValue().toString()
                      .equals("false"))
                parameter = false;
            }
            super.endVisit(node);
          }

          public void endVisit(VariableDeclarationFragment node) {
            paramName = node.getName().toString();
            super.endVisit(node);
          }
        });
        super.endVisit(node);
        if (parameter){
          Template template = new Template(paramName, "add attribute " + paramName, contextTypeId, buildAttributeInsertCode(paramName), true);
          components.add(template);
        }
      }
    });
  }
 
  private static String buildAttributeInsertCode(String parameter){
    String ret = parameter + "=\"${cursor}\"";
    return ret;
  }
 
  /**
   * Get components template list in situation:<span t:type="${component name here}"></span>
   *
   * @param project
   * @param contextTypeId
   * @return
   */
  public List<Template> getRootComponentsNameTemplates(IProject project, String contextTypeId){
    try {
      IJavaElement[] elements = getComponentsJavaElements(project);
      List<Template> components = new ArrayList<Template>();
      for(IJavaElement ele : elements){
        if(ele.getElementType() == IJavaElement.COMPILATION_UNIT && ele.getElementName().endsWith(".java")){
          TapestryCoreComponents component = new TapestryCoreComponents();
          String name = ele.getElementName().substring(0, ele.getElementName().indexOf('.'));
          component.setName(name);
          component.setElementLabel("t:" + name.toLowerCase());
          components.add(new Template("t:" + component.getName(), buildDescription(component, "root package"), contextTypeId, component.getName(), true));
        }
      }
      return components;
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
   
    return null;
  }
 
  public List<Template> getRootComponentsTemplates(IProject project, String contextTypeId, int type){
    try {
      IJavaElement[] elements = getComponentsJavaElements(project);
      List<Template> components = new ArrayList<Template>();
      for(IJavaElement ele : elements){
        if(ele.getElementType() == IJavaElement.COMPILATION_UNIT && ele.getElementName().endsWith(".java")){
          TapestryCoreComponents component = new TapestryCoreComponents();
          String name = ele.getElementName().substring(0, ele.getElementName().indexOf('.'));
          component.setName(name);
          component.setElementLabel("t:" + name.toLowerCase());
          components.add(new Template("t:" + component.getName(), buildDescription(component, "root package"), contextTypeId, buildInsertCode(component, type), true));
        }
      }
      return components;
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
   
    return null;
  }
 
  private IJavaElement[] getComponentsJavaElements(IProject project) throws JavaModelException{
    findWEBXML(project);
    if(this.webXMLPath == null)
      return null;
    String rootPackage = parseRootPackage(project);
    if(rootPackage == null || rootPackage.isEmpty())
      return null;
    rootPackage = rootPackage + ".components";
    IPackageFragment pack = getTapestryRootComponentsPackage(project, rootPackage);
    IJavaElement[] elements = pack.getChildren();
    return elements;
  }
 
  private String buildDescription(TapestryCoreComponents component, String rootPackage){
    return "Custom Component in " + rootPackage;
  }
 
  private String buildInsertCode(TapestryCoreComponents element, int type){
    String ret = "";
    String insertLabel = element.getElementLabel();
    switch(type){
    case 1:
      ret = "<"+insertLabel+"></"+insertLabel+">";
      break;
    case 2:
      ret = insertLabel+"></"+insertLabel+">";
      break;
    case 3:
      ret = insertLabel+"></"+insertLabel+">";
      int prefixLength = insertLabel.indexOf(':') + 1;
      if(ret.length() > prefixLength)
        ret = ret.substring(prefixLength);
      break;
    }
   
    return ret;
  }
 
  public IPackageFragment getTapestryRootComponentsPackage(IProject project, String packageName) {
    IPackageFragmentRoot[] roots2;
    try {
      roots2 = JavaCore.create(project).getAllPackageFragmentRoots();
      for (IPackageFragmentRoot root : roots2) {
        if (!root.isArchive()){
          IPackageFragment packInstance = root.getPackageFragment(packageName);
          if(packInstance != null)
            return packInstance;
        }
      }
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
    return null;
  }
 
  private void findWEBXML(IProject project){
    IResource[] fileList = null;
    try {
      fileList = project.members(false);
      travelAllFolder(fileList);
    } catch (CoreException e) {
      e.printStackTrace();
    }
  }
 
  private void travelAllFolder(IResource[] fileList)
      throws CoreException {
    for (int i = 0; i < fileList.length; i++) {
      IResource eachFile = fileList[i];
       if(eachFile.getType() == IResource.FILE && eachFile.getName().equals(TapestryContants.WEB_XML)){
        this.webXMLPath = eachFile.getFullPath().toString();
        return;
      } else if (eachFile.getType() == IResource.FOLDER) {
        IFolder file = (IFolder) eachFile;
        travelAllFolder(file.members());
      }
    }
  }
 
  private String parseRootPackage(IProject project){
    IResource webRes = project.findMember(webXMLPath.substring(("/" + project.getName()).length()));
    if(webRes != null && webRes.getType() == IResource.FILE){
      InputStream webStream;
      try {
        webStream = ResourcesPlugin.getWorkspace().getRoot()
            .getFile(webRes.getFullPath()).getContents();
        DocumentBuilder db=DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document document=db.parse(webStream);
        Element web = document.getDocumentElement();
        NodeList filters = web.getChildNodes();
        boolean tapestryContext = false;
        String rootPath = null;
        for(int i=0; i<filters.getLength(); i++){
                Node filter=filters.item(i);
                if(filter.getNodeType() != Node.ELEMENT_NODE || !filter.getNodeName().equals(TapestryContants.CONTEXT_PARAM))
                  continue;
                NodeList filterChildren = filter.getChildNodes();
                for(int j=0; j<filterChildren.getLength(); j++){
                  Node element = filterChildren.item(j);
                  if(element.getNodeType() != Node.ELEMENT_NODE)
                    continue;
                  if(element.getNodeName().equals(TapestryContants.PARAM_NAME)){
                    if(element.getTextContent().trim().equals(TapestryContants.PARAM_NAME_DEFINE)){
                      tapestryContext = true;
                    }
                  }else if(element.getNodeName().equals(TapestryContants.PARAM_VALUE)){
                    rootPath = element.getTextContent().trim();
                  }
                }
                if(rootPath != null && tapestryContext)
                  return rootPath;
            }
      } catch (CoreException e) {
        e.printStackTrace();
      } catch (ParserConfigurationException e) {
        e.printStackTrace();
      } catch (SAXException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
     
    }
    return null;
  }
 
  /**
   * Get all the prefixes including "t:" in current project
   *
   * @param project
   * @return
   */
  public Set<String> getComponentsPrefixList(IProject project){
    Set<String> prefixList = new HashSet<String>();
    prefixList.add("t");
    final IFile res = project.getFile(TapestryContants.CUSTOM_COMPONENTS_FILE);
    if(res == null)
      return prefixList;
    List<ComponentPackage> packageList = loadPackageList(res, 1, "");
    for(ComponentPackage cp : packageList){
      prefixList.add(cp.getPrefix());
    }
    return prefixList;
  }
 
  /**
   * Get custom component attribute templates
   *
   * @param project
   * @param contextTypeId
   * @param nodeName
   * @param tapestryClassLoader
   * @return
   */
  public List<Template> getCustomComponentsAttributes(IProject project, String contextTypeId, String nodeName, TapestryClassLoader tapestryClassLoader){
    components.clear();
    String prefix = nodeName.substring(0, nodeName.indexOf(':'));
    try {
      final IFile res = project.getFile(TapestryContants.CUSTOM_COMPONENTS_FILE);
      if(res == null || prefix == null)
        return components;
      List<ComponentPackage> packageList = loadCustomComponentsPackageListWithPrefix(res, prefix);
      IPackageFragmentRoot[] roots = JavaCore.create(project).getAllPackageFragmentRoots();
      for(ComponentPackage cp : packageList){
        for (IPackageFragmentRoot root : roots) {
          if(cp.isArchive() == root.isArchive() && cp.getFragmentRoot().equals(root.getElementName())){
            IPackageFragment packInstance = root.getPackageFragment(cp.getPath());
            if (!root.isArchive()){
              //If current custom component is in source directory
              if(packInstance != null){
                IJavaElement[] elements = packInstance.getChildren();
                for(IJavaElement ele : elements){
                  if(ele.getElementType() == IJavaElement.COMPILATION_UNIT && ele.getElementName().endsWith(".java")){
                    String name = ele.getElementName().substring(0, ele.getElementName().indexOf('.'));
                    if((prefix + ":" + name).toLowerCase().equals(nodeName)){
                      goThroughClass((ICompilationUnit) ele, contextTypeId);
                      return components;
                    }
                  }
                }
              }
            }else if(packInstance instanceof PackageFragment){
              //Current custom component is in jar files
              for(Object packo : ((PackageFragment) packInstance).getChildrenOfType(IJavaElement.CLASS_FILE)){
                ClassFile packi = (ClassFile) packo;
                String className = packi.getElementName().substring(0, packi.getElementName().indexOf('.'));
                if(className.indexOf('$') < 0 && (prefix + ":" + className.toLowerCase()).equals(nodeName)){
                  TapestryCoreComponents component = null;
                  try {
                    component = tapestryClassLoader.loadComponentAttributesFromClassFile(root, prefix, packi);
                  } catch (ClassFormatException e) {
                    e.printStackTrace();
                  }
                  if(component != null){
                    for(String paramName : component.getPamameters()){
                      Template template = new Template(paramName, "add attribute " + paramName, contextTypeId, buildAttributeInsertCode(paramName), true);
                      components.add(template);
                    }
                    return components;
                  }
                }
              }
            }
          }
        }
      }
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
   
    return null;
  }
 
  /**
   * Get Tapestry custom components in situation: <span t:type="${component name here}"></span>
   *
   * @param project
   * @param contextTypeId
   * @param type
   * @param prefix
   * @return
   */
  public List<Template> getCustomComponentsNameTemplates(IProject project, String contextTypeId){
    List<Template> templateList = new ArrayList<Template>();
    final IFile res = project.getFile(TapestryContants.CUSTOM_COMPONENTS_FILE);
    if(res == null)
      return templateList;
    List<ComponentPackage> packageList = loadPackageList(res, 1, "*");
    IPackageFragmentRoot[] roots;
    try {
      roots = JavaCore.create(project).getAllPackageFragmentRoots();
      for(ComponentPackage cp : packageList){
        loadCustomComponentsNameFromPackage(roots, contextTypeId, templateList, cp);
      }
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
   

    return templateList;
  }
 
  /**
   * Get all the template list(including core templates, root templates and custom component templates) in current project
   *
   * @param project
   * @param contextTypeId
   * @param type
   * @param prefix
   * @return
   */
  public List<Template> getCustomComponentsTemplates(IProject project, String contextTypeId, int type, String prefix){
    List<Template> templateList = new ArrayList<Template>();
    final IFile res = project.getFile(TapestryContants.CUSTOM_COMPONENTS_FILE);
    if(res == null)
      return templateList;
    List<ComponentPackage> packageList = loadPackageList(res, type, prefix);
    try {
      IPackageFragmentRoot[] roots = JavaCore.create(project).getAllPackageFragmentRoots();
      for(ComponentPackage cp : packageList){
        loadCustomComponentsFromPackage(roots, contextTypeId, type, templateList, cp, prefix);
      }
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
   
    return templateList;
  }
 
  /**
   * Load component name template list, used in situation:<span t:type="${component name here}"></span>
   *
   * @param roots
   * @param contextTypeId
   * @param type
   * @param templateList
   * @param cp
   */
  private void loadCustomComponentsNameFromPackage(IPackageFragmentRoot[] roots, String contextTypeId, List<Template> templateList, ComponentPackage cp){
    List<String> componentNameList = getCustomComponentsNameList(roots, cp)
    for(String componentName : componentNameList){
      TapestryCoreComponents component = new TapestryCoreComponents();
      component.setName(componentName);
      component.setElementLabel(cp.getPrefix() + ":" + componentName.toLowerCase());
      templateList.add(new Template(cp.getPrefix() + ":" + component.getName(), buildDescription(component, cp.getPath()), contextTypeId, cp.getPrefix()+ "/" +component.getName(), true));
    }
  }
 
  /**
   * Load custom component template list, used in situation:<t:prefix/compName
   *
   * @param roots
   * @param contextTypeId
   * @param type
   * @param templateList
   * @param cp
   * @param prefix
   */
  private void loadCustomComponentsFromPackage(IPackageFragmentRoot[] roots, String contextTypeId, int type, List<Template> templateList, ComponentPackage cp, String prefix){
    List<String> componentNameList = getCustomComponentsNameList(roots, cp)
    //Build templates from name list
    for(String componentName : componentNameList){
      TapestryCoreComponents component = new TapestryCoreComponents();
      component.setName(componentName);
      if (prefix == null || prefix.equals("t"))
        component.setElementLabel("t:" + cp.getPrefix() + "." + componentName.toLowerCase());
      else
        component.setElementLabel(cp.getPrefix() + ":" + componentName.toLowerCase());
      templateList.add(new Template(cp.getPrefix() + ":" + component.getName(), buildDescription(component,
          cp.getPath()), contextTypeId, buildInsertCode(component, type), true));
    }
  }
 
  private List<String> getCustomComponentsNameList(IPackageFragmentRoot[] roots, ComponentPackage cp){
    List<String> componentNameList = new ArrayList<String>();
    try {
      for (IPackageFragmentRoot root : roots) {
        if(root instanceof JarPackageFragmentRoot == cp.isArchive() && root.getElementName().equals(cp.getFragmentRoot())) {
          if (!root.isArchive()) {
            // Load custom components from source directory
            IPackageFragment packInstance = root.getPackageFragment(cp.getPath());
            if (packInstance != null) {
              IJavaElement[] elements = packInstance.getChildren();
              for (IJavaElement ele : elements) {
                if (ele.getElementType() == IJavaElement.COMPILATION_UNIT
                    && ele.getElementName().endsWith(".java")) {
                  String name = ele.getElementName().substring(0, ele.getElementName().indexOf('.'));
                  componentNameList.add(name);
                }
              }
            }
          } else {
            // Load custom components from jar files
            for (IJavaElement pack : root.getChildren()) {
              if (pack != null && pack instanceof PackageFragment && pack.getElementName().equals(cp.getPath())) {
                for(Object packo : ((PackageFragment) pack).getChildrenOfType(IJavaElement.CLASS_FILE)){
                  ClassFile packi = (ClassFile) packo;
                  String itemName = packi.getElementName();
                  if(itemName.indexOf('$') < 0 && itemName.endsWith(".class"))
                    componentNameList.add(itemName.substring(0, itemName.length()-6));
                }
                break;
              }
            }
          }
          return componentNameList;
        }
      }
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
    return componentNameList;
  }
 
  private List<ComponentPackage> loadPackageList(IFile res, int type, String prefix){
    List<ComponentPackage> packageList = new ArrayList<ComponentPackage>();
    DocumentBuilder db = null;
    try {
      db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document document=db.parse(res.getContents());
      Element root = document.getDocumentElement();
      NodeList bundles = root.getChildNodes();
      if (bundles != null) {
        for (int i = 0; i < bundles.getLength(); i++) {
          Node classCycles = bundles.item(i);
          if (classCycles.getNodeType() == Node.ELEMENT_NODE
              && classCycles.getNodeName().trim().equals(TapestryContants.CUSTOM_COMPONENTS_PACKAGES)) {
            NodeList classes = classCycles.getChildNodes();
            for(int j=0; j<classes.getLength(); j++){
              Node classItem = classes.item(j);
              if(classItem.getNodeType() == Node.ELEMENT_NODE && classItem.getNodeName().trim().equals(TapestryContants.CUSTOM_COMPONENTS_PACKAGE)){
                ComponentPackage ci = new ComponentPackage();
                getPackageBasicInfo(ci, classItem);
                if(type != 3 || ci.getPrefix().equals(prefix) || prefix.equals("t"))
                  packageList.add(ci);
              }
            }
            break;
          }
        }
      }
    } catch (ParserConfigurationException e) {
      e.printStackTrace();
    } catch (SAXException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (CoreException e) {
      e.printStackTrace();
    }
   
    return packageList;
  }
 
  private List<ComponentPackage> loadCustomComponentsPackageListWithPrefix(IFile res, String prefix){
    List<ComponentPackage> packageList = new ArrayList<ComponentPackage>();
    DocumentBuilder db = null;
    try {
      db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document document=db.parse(res.getContents());
      Element root = document.getDocumentElement();
      NodeList bundles = root.getChildNodes();
      if (bundles != null) {
        for (int i = 0; i < bundles.getLength(); i++) {
          Node classCycles = bundles.item(i);
          if (classCycles.getNodeType() == Node.ELEMENT_NODE
              && classCycles.getNodeName().trim().equals(TapestryContants.CUSTOM_COMPONENTS_PACKAGES)) {
            NodeList classes = classCycles.getChildNodes();
            for(int j=0; j<classes.getLength(); j++){
              Node classItem = classes.item(j);
              if(classItem.getNodeType() == Node.ELEMENT_NODE && classItem.getNodeName().trim().equals(TapestryContants.CUSTOM_COMPONENTS_PACKAGE)){
                ComponentPackage ci = new ComponentPackage();
                getPackageBasicInfo(ci, classItem);
                if(ci.getPrefix().equals(prefix))
                  packageList.add(ci);
              }
            }
            break;
          }
        }
      }
    } catch (ParserConfigurationException e) {
      e.printStackTrace();
    } catch (SAXException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (CoreException e) {
      e.printStackTrace();
    }
   
    return packageList;
  }
 
  /**
   * Parse XML node
   *
   * @param ci
   * @param classItem
   */
  private void getPackageBasicInfo(ComponentPackage ci, Node classItem){
    Node prefix = classItem.getAttributes().getNamedItem(TapestryContants.CUSTOM_COMPONENTS_PREFIX);
    if (prefix != null)
      ci.setPrefix(prefix.getNodeValue());
    Node path = classItem.getAttributes().getNamedItem(TapestryContants.CUSTOM_COMPONENTS_PATH);
    if (path != null)
      ci.setPath(path.getNodeValue());
    Node isArchive = classItem.getAttributes().getNamedItem(TapestryContants.CUSTOM_COMPONENTS_ISARCHIVE);
    if(isArchive != null)
      ci.setArchive(isArchive.getNodeValue().equals("true"));
    Node fragmentRoot = classItem.getAttributes().getNamedItem(TapestryContants.CUSTOM_COMPONENTS_FRAGMENTROOT);
    if(fragmentRoot != null)
      ci.setFragmentRoot(fragmentRoot.getNodeValue());
  }
}
TOP

Related Classes of org.eclipse.wst.xml.ui.internal.contentassist.tapestry.TapestryRootComponentsProposalComputer

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.