Package com.dubture.symfony.core.parser

Source Code of com.dubture.symfony.core.parser.XMLConfigParser

/*******************************************************************************
* This file is part of the Symfony eclipse plugin.
*
* (c) Robert Gruendler <r.gruendler@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
******************************************************************************/
package com.dubture.symfony.core.parser;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.dubture.symfony.core.log.Logger;
import com.dubture.symfony.index.model.Route;
import com.dubture.symfony.index.model.Service;

/**
*
* {@link XMLConfigParser} retrieves project configuration
* from xml files and contributes it to the Symfony2 model.
*
*
* @author Robert Gruendler <r.gruendler@gmail.com>
*
*/
public class XMLConfigParser implements IConfigParser {

  private XPath xPath;
  private Document doc;

  private HashMap<String, String> parameters;
  private HashMap<String, Service> services;
  private Stack<Route> routes = new Stack<Route>();

  public XMLConfigParser(InputStream inputStream) throws Exception {

      doc = PositionalXMLReader.readXML(inputStream);
      xPath = XPathFactory.newInstance().newXPath();
    parameters = new HashMap<String, String>();
    services = new HashMap<String, Service>();
   
  }


  @Override
  public void parse() throws Exception {

    // get parameters
    parseParameters();

    // get services
    parseServices();

    // get aliased services
    parseAliases();
   
    // parse synthetic services
    parseSynthetic();

    // parse routes
    parseRoutes();

  }

  private void parseRoutes() {

    try {

      String servicePath = "/routes/route";
      NodeList routeNodes = getNodes(servicePath);

      for (int i = 0; i < routeNodes.getLength(); i++) {

        Node node = routeNodes.item(i);       
        NamedNodeMap atts = node.getAttributes();

        String name = null;
        String pattern = null;

        for (int j = 0; j < atts.getLength(); j++) {

          Attr attr = (Attr) atts.item(j);

          String key = attr.getName();
          if (key.equals("id"))
            name = attr.getValue();
          else if (key.equals("pattern"))
            pattern = attr.getValue();

        }

        XPathExpression expr = xPath.compile("default[@key='_controller']");
        Object _default = expr.evaluate(node, XPathConstants.NODESET);
        NodeList defaults = (NodeList) _default;

        if (defaults.getLength() == 1) {
          Node controllerNode = defaults.item(0);     
          routes.push(new Route(name, pattern, controllerNode.getTextContent()));         
        }

      }

    } catch (Exception e) {
      Logger.logException(e);
    }
  }


  /**
   * Parse the service parameters from the XML file.
   *
   *
   * @throws Exception
   */
  private void parseParameters() throws Exception {

    String expr = "/container/parameters/parameter[@key]";
    XPathExpression xpathExpr = xPath.compile(expr);     

    Object result = xpathExpr.evaluate(doc,XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;

    for (int i = 0; i < nodes.getLength(); i++) {     
      Node node = nodes.item(i);
      NamedNodeMap atts = node.getAttributes();     
      for (int j = 0; j < atts.getLength(); j++) {

        Attr attr = (Attr) atts.item(j)

        if (attr != null && attr.getName() != null && attr.getName().equals("key")) {
          parameters.put(attr.getValue(), node.getTextContent());
          break;         
        }
      }
    }
  }

  /**
   * Parse services if available from the xml file.
   *
   * @throws Exception
   */
  @SuppressWarnings("rawtypes")
  private void parseServices() throws Exception {

      NodeList nodeList = doc.getElementsByTagName("service");
     
      for (int i=0; i < nodeList.getLength(); i++) {
         
          Node childNode = nodeList.item(i);
          NamedNodeMap attributes = childNode.getAttributes();
         
            Node idItem = attributes.getNamedItem("id");
           
            if (idItem == null)  {
              continue;
            }
           
            String id = idItem.getNodeValue();
           
            String phpClass = null;
            Node namedItem = attributes.getNamedItem("class");
           
            if (namedItem != null) {
              phpClass =  namedItem.getNodeValue();
            } else {
              Logger.log(Logger.INFO, "Unable to parse class attribute from service " + childNode);
            }
           
            Node publicItem = attributes.getNamedItem("public");
            String _public = null;
           
            if (publicItem != null) {
                _public = attributes.getNamedItem("public").getNodeValue();   
            }
           
            if (phpClass != null && id != null) {

                Service _service = null;
                if (phpClass.startsWith("%") && phpClass.endsWith("%")) {

                    String placeHolder = phpClass.replace("%", "");
                    Iterator it = getParameters().keySet().iterator();

                    while (it.hasNext()) {
                        String key = (String) it.next();                       
                        String val = (String) getParameters().get(key);

                        if (placeHolder.equals(key)) {                 
                            _service = new Service(id, val, null);                             
                        }
                    }                      
                } else {
                    _service = new Service(id, phpClass, null);                
                }
               
                NodeList children = childNode.getChildNodes();
               
                List<Node> tags = new ArrayList<Node>();
                List<Node> arguments = new ArrayList<Node>();
                List<Node> calls = new ArrayList<Node>();
               
                for (int j=0; j < children.getLength(); j++) {
                    Node child = children.item(j);
                    if ("tag".equals(child.getNodeName())) {
                        tags.add(child);
                    } else if ("argument".equals(child.getNodeName())) {
                        arguments.add(child);
                    } else if ("call".equals(child.getNodeName())) {
                        calls.add(child);
                    }
                }
               
                if (_service != null) {
                    _service.setPublic(_public);
                    _service.setLine(Integer.parseInt((String) childNode.getUserData("lineNumber")));
                   
                    for(Node tag : tags) {
                        NamedNodeMap map = tag.getAttributes();                                
                        Node tagName = map.getNamedItem("name");
                        if (tagName != null && tagName.getNodeValue() != null) {
                            _service.addTag(tagName.getNodeValue());
                        }
                    }
                }
               
                synchronized (services) {
                    services.put(id, _service);
                }
            }         

      }
     
/*     
    String servicePath = "/container/services/service[@class]";
    NodeList serviceNodes = getNodes(servicePath);
   
    for (int i = 0; i < serviceNodes.getLength(); i++) {

      Element service = (Element) serviceNodes.item(i);
     
      //TODO: Check the services visibility and if it's abstract
     
      Object userData = service.getUserData(LocationRecordingHandler.KEY_LINE_NO);
     
      System.err.println(userData);
     
      String id = service.getAttribute("id");
      String phpClass = service.getAttribute("class");     
      String _public = service.getAttribute("public");
     
      NodeList tags = service.getElementsByTagName("tag");     
     
      if (_public == null || _public.equals(""))
        _public = "true";     
     
      if (phpClass != null && id != null) {

        Service _service = null;
        if (phpClass.startsWith("%") && phpClass.endsWith("%")) {

          String placeHolder = phpClass.replace("%", "");
          Iterator it = getParameters().keySet().iterator();

          while (it.hasNext()) {
            String key = (String) it.next();           
            String val = (String) getParameters().get(key);

            if (placeHolder.equals(key)) {         
              _service = new Service(id, val, null);               
            }
          }           
        } else {
          _service = new Service(id, phpClass, null);         
        }
       
        for(int k=0; k < tags.getLength(); k++) {
         
          Node tag = tags.item(k);
          NamedNodeMap map = tag.getAttributes();                 
          Node tagName = map.getNamedItem("name");

          if (tagName != null && tagName.getNodeValue() != null)
            _service.addTag(tagName.getNodeValue());
         
        }
       
        if (_service != null)
          _service.setPublic(_public);
       
        synchronized (services) {
          services.put(id, _service); 
        }
      }
    }
    */
  }

  @SuppressWarnings("rawtypes")
  private void parseAliases() throws Exception {

    String servicePath = "/container/services/service[@alias]";
    NodeList serviceNodes = getNodes(servicePath);

    for (int i = 0; i < serviceNodes.getLength(); i++) {

      Element service = (Element) serviceNodes.item(i);
      String id = service.getAttribute("id");
      String alias = service.getAttribute("alias");

      if (alias != null && id != null) {

        synchronized (services) {
          Iterator it = services.keySet().iterator();
          HashMap<String, Service> newServices = new HashMap<String, Service>();
          while (it.hasNext()) {
            String aliasID = (String) it.next();           
            Service _s=  services.get(aliasID);
            if (_s != null) {
                _s.addAlias(aliasID);
                if (alias.equals(aliasID)) {
                    newServices.put(id, _s);
                }
            }
          }
          services.putAll(newServices);
        }
      }
    }
  }

  private void parseSynthetic() throws Exception {

    String servicePath = "/container/services/service[@synthetic]";
    NodeList serviceNodes = getNodes(servicePath);

    for (int i = 0; i < serviceNodes.getLength(); i++) {

      Element service = (Element) serviceNodes.item(i);

      //TODO: Check the services visibility and if it's abstract
      String id = service.getAttribute("id");
      String isSynthetic = service.getAttribute("synthetic");

      if (isSynthetic != null && id != null) {
       
        services.put(id, new Service(id, "synthetic", null));
      }    
    }   
  }

  /**
   * Retrieve a list of nodes for a given xpath expression
   *
   * @param path
   * @return
   * @throws Exception
   */
  private NodeList getNodes(String path) throws Exception {

    XPathExpression xpathExpr = xPath.compile(path);
    Object result = xpathExpr.evaluate(doc,XPathConstants.NODESET);
    return (NodeList) result;

  }

  /**
   * Get all loades services.
   *
   *
   * @return
   */
  public HashMap<String, Service> getServices() {
    return services;
  }


  /**
   * Did the parser find any services definitions?
   *
   * @return
   */
  public boolean hasServices() {

    return services.size() > 0;
  }


  public HashMap<String, String> getParameters() {
    return parameters;
  }

  public boolean hasRoutes() {

    return routes.size() > 0;
  }

  public Stack<Route> getRoutes() {

    return routes;
  }

}
TOP

Related Classes of com.dubture.symfony.core.parser.XMLConfigParser

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.