QueryBuilder.java :  » IDE-Netbeans » uml » org » netbeans » modules » uml » core » Java Open Source

Java Open Source » IDE Netbeans » uml 
uml » org » netbeans » modules » uml » core » QueryBuilder.java
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Contributor(s):
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
 * Microsystems, Inc. All Rights Reserved.
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 */


package org.netbeans.modules.uml.core;

import java.io.File;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Vector;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;

import org.netbeans.modules.uml.core.coreapplication.ICoreProduct;
import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
import org.netbeans.modules.uml.core.metamodel.core.foundation.IVersionableElement;
import org.netbeans.modules.uml.core.metamodel.structure.IProject;
import org.netbeans.modules.uml.core.support.umlsupport.ProductRetriever;
import org.netbeans.modules.uml.core.support.umlsupport.XMLManip;
import org.netbeans.modules.uml.core.typemanagement.ITypeManager;

/**
 * @author sumitabhk
 *
 */
public class QueryBuilder implements IQueryBuilder
{
  private String m_SchemaLocation = "";
  private String m_ProjID = "";
  private String m_DefaultUpdaterProgId = "";
  private String m_ResultLocation = "";

  /**
   *
   * Sets the location of the QuerySchemas.etc file. The schema file
   * does not have to be the QuerySchemas.etc file, but is must have
   * the same format.
   *
   * @param newVal[in] The absolute location of the file to use
   *                   as a schema from which queries can be built
   *
   * @return HRESULT
   *
   */
  public void setSchemaLocation(String pVal)
  {
    m_SchemaLocation = pVal;
  }

  /**
   *
   * Retrieves the location of the QuerySchemas.etc file
   * that was previously set.
   *
   * @param pVal[out] The current value
   *
   * @return 
   *
   */
  public String getSchemaLocation()
  {
    return m_SchemaLocation;
  }

  /**
   *
   * Generates out new results given the set schema file and the passed
   * in data node. This routine will create new data. No checking of existing
   * data is made.
   *
   * @param dataSourceNode[in]  The node that all queries defined in the 
   *        schema file are run against.
   * @param results[out]        The xml document that holds the results
   *
   * @return HRESULT
   *
   */
  public Document generateResults(Node node)
  {
    Document retDoc = null;
    if (node != null)
    {
      m_DefaultUpdaterProgId = "";
      verifyBuildEnvironment();
      Document doc = loadSchema();
         
         if (doc != null)
      {
        Element root = doc.getRootElement();
        if (root != null)
        {
          m_DefaultUpdaterProgId = XMLManip.getAttributeValue(root, "defaultUpdater");
        }
        
        // Gather the Query elements in the Schema file
        List nodes = doc.selectNodes("//Query");
        if (nodes != null)
        {
          int count = nodes.size();
          if (count > 0)
          {
            // Create the document that will house the results
            Document resultDoc = XMLManip.getDOMDocument();
            if (resultDoc != null)
            {
              // Create the processing instruction to make the file an xml doc
              //resultDoc.addProcessingInstruction("xml", "version = '1.0'");
              //Element rootEle = XMLManip.createElement(resultDoc, "xml");
              //Element attr = XMLManip.createElement(rootEle, "version = '1.0'");
              //rootEle.add(attr);
              
              //resultDoc.add(rootEle);
              Element cachedQueriesNode = XMLManip.createElement(resultDoc, "CachedQueries");
              if (cachedQueriesNode != null)
              {
                for (int i=0; i<count; i++)
                {
                  Node childNode = (Node)nodes.get(i);

                  // OK, we've got our first Query schema, so let's process it.
                  processQuery(node, childNode, cachedQueriesNode);
                }
              }
              retDoc = resultDoc;
            }
          }
        }
      }
    }
    return retDoc;
  }

  /**
   *
   * Executes a query defined in the schemaNode passed in against the dataSourceNode also
   * passed in.
   *
   * @param dataSourceNode[in]  The node holding the data to query against
   * @param schemaNode[in]      The node holding the query details
   * @param resultParent[in]    The parent element that will hold the results of the executed
   *                            queries.
   *
   * @return HRESULT
   *
   */
  private void processQuery(Node dataSourceNode, Node schemaNode, Element resultParent)
  {
    QuerySchema querySchema = buildSchemaNode(schemaNode);
    
    // Let's retrieve the query string first, execute, and if we have any results,
    // then we'll build the resultant elements
    if (querySchema.validate())
    {
      List dataNodes = dataSourceNode.selectNodes(querySchema.m_MainQuery);
      if (dataNodes != null)
      {
        int count = dataNodes.size();
        if (count > 0)
        {
          Node resultContNode = querySchema.createResultContainer(resultParent);
          if (resultContNode != null)
          {
            for (int i=0; i<count; i++)
            {
              Node dataNode = (Node)dataNodes.get(i);
              Node resultNode = querySchema.createResultNode(resultContNode, dataNode);
            }
          }
        }
      }
    }
  }

  /**
   *
   * Gather the details of a particular query defined in the QuerySchema file.
   *
   * @param rawSchemaNode[in]   The schema node pulled from the QuerySchema file
   * @param schemaNode[out]     The QuerySchema object packed with data pulled form rawSchemaNode
   *
   * @return HRESULT
   *
   */
  private QuerySchema buildSchemaNode(Node rawSchemaNode)
  {
    QuerySchema schemaNode = new QuerySchema();
    schemaNode.m_Project = getProject();
    schemaNode.m_resultContainerName = XMLManip.getAttributeValue(rawSchemaNode, "name");
    schemaNode.m_MainQuery = XMLManip.getAttributeValue(rawSchemaNode, "locate");
    schemaNode.m_Updater = XMLManip.getAttributeValue(rawSchemaNode, "updater");
    
    // Ok, we've got the outer result element that will contain all the
    // individual results. Now let's determine the name of the individual
    // result element types, as well as the xml attributes to put on those
    // elements
    Node queryResultNode = rawSchemaNode.selectSingleNode("./QueryResult");
    if (queryResultNode != null)
    {
      String includeNodeName = XMLManip.getAttributeValue(queryResultNode, "includeNodeType");
      schemaNode.m_ResultNodeName = XMLManip.getAttributeValue(queryResultNode, "name");
      if (includeNodeName != null && includeNodeName.equals("true"))
      {
        // A simple flag that instructs us to include the name of the node as an xml attribute
        // on each of the result elements
        schemaNode.m_IncludeNodeName = true;
      }
      
      // Now determine how many xml attributes to create
      List resultAttrs = queryResultNode.selectNodes("./ResultAttr");
      if (resultAttrs != null)
      {
        int count = resultAttrs.size();
        for (int i=0; i<count; i++)
        {
          Node resultAttr = (Node)resultAttrs.get(i);
          String nameOfAttr = XMLManip.getAttributeValue(resultAttr, "name");
          String queryForAttr = XMLManip.getAttributeValue(resultAttr, "query");
          String isUnique = XMLManip.getAttributeValue(resultAttr, "isUnique");
          String isProperty = XMLManip.getAttributeValue(resultAttr, "isProperty");
          schemaNode.m_ResultAttrs.add(new ResultAttr(nameOfAttr, queryForAttr,
                                isUnique, isProperty));
        }
      }
    }
    
    return schemaNode;
  }

  /**
   *
   * Loads the schema file that defines the queries to 
   * execute
   *
   * @param doc[out] The document that contains the specified queries
   *                 to execute
   *
   * @return HRESULT
   *
   */
  private Document loadSchema()
  {
    Document retDoc = null;
    if (m_SchemaLocation != null)
    {
      retDoc = XMLManip.getDOMDocument(m_SchemaLocation);
      if (retDoc == null)
      {
        //Throw parse exception
      }
    }
    return retDoc;
  }

  /**
   *
   * Checks to see if the schema and result location properties are validly
   * set.
   *
   * @return QB_E_BAD_SCHEMA_LOCATION if the SchemaLocation property is not
   *         set to a valid xml file.
   *         QB_E_BAD_RESULT_LOCATION if the ResultLocation does not point
   *         at a valid location to create a new results file,
   *         else S_OK
   *
   */
  private void verifyBuildEnvironment()
  {
    File file = new File(m_SchemaLocation);
    if (!file.exists())
    {
      //Show an error to the user that IDS_BAD_SCHEMA_LOCATION
    }
  }

  public void setProjectId(String pVal)
  {
    m_ProjID = pVal;
  }

  public String getProjectId()
  {
    return m_ProjID;
  }

  public String getDefaultUpdaterProgId()
  {
    return m_DefaultUpdaterProgId;
  }
  
  private IProject getProject()
  {
    IProject retProj = null;
    ICoreProduct prod = ProductRetriever.retrieveProduct();
    if (prod != null)
    {
      IApplication app = prod.getApplication();
      if (app != null)
      {
        retProj = app.getProjectByID(m_ProjID);
      }
    }
    return retProj;
  }

  private class ResultAttr
  {
    //Name of the xml attribute
    private String m_AttrName = "";
    //Query to pack the attribute with( i.e., the result of the query )
    private String m_Query = "";
    //true if the particular xml attribute can be used as a search id for updates
    private boolean m_IsUnique = false;
    //true if the m_Query is the name of a Property to execute
    private boolean m_PropertyGet = false;
    
    public ResultAttr(String name, String query, String isUnique, String isProperty)
    {
      m_AttrName = name;
      m_Query = query;
      if (isUnique != null && isUnique.equals("true"))
      {
        m_IsUnique = true;
      }
      if (isProperty != null && isProperty.equals("true"))
      {
        m_PropertyGet = true;
      }
    }
  }
  
  private class QuerySchema
  {
    //Name of the outer xml element that houses the results of the query
    private String m_resultContainerName = "";
    //Name of the outer xml element that houses the results of the query
    private boolean m_IncludeNodeName = false;
    //The query to perform on the data source
    private String m_MainQuery = "";
    //Name of the element to house each result. One per found result node
    private String m_ResultNodeName = "";
    //The progid of the IQueryUpdater object that will be loaded by the QueryManager
    private String m_Updater = "";
    //The xml attributes and queries for each result node
    private Vector/*<ResultAttr>*/ m_ResultAttrs = new Vector();
    private IProject m_Project = null;
    
    /**
     *
     * Makes sure that the QuerySchema object is in a valid state
     *
     * @return true if data is good, else false
     *
     */
    public boolean validate()
    {
      boolean isValid = false;
      if (m_resultContainerName != null && m_resultContainerName.length() > 0)
      {
        if (m_ResultNodeName != null && m_ResultNodeName.length() > 0)
        {
          if (m_MainQuery != null && m_MainQuery.length() > 0)
          {
            isValid = true;
          }
        }
      }
      return isValid;
    }
    
    /**
     *
     * Creates the Xml element that is the result container for the individual result
     * elements to be created
     *
     * @param resultParent[in] The parent to own the result container. The returned container
     *                         element will be properly parented to resultParent if successful.
     * @param container[out]   The new element
     *
     * @return HRESULT
     *
     */
    public Node createResultContainer(Element resultParent)
    {
      Node retNode = null;
      retNode = XMLManip.createElement(resultParent, m_resultContainerName);
      if (retNode != null)
      {
        XMLManip.setAttributeValue(retNode, "updater", m_Updater);
      }
      return retNode;
    }
    
    /**
     *
     * Creates a new node that is placed as a child on container, and fills in the appropriate xml attributes
     * based on the data found in dataNode
     *
     * @param container[in]    The xml element that will own the new node
     * @param dataNode[in]     The data node that data is getting pulled from
     * @param resultNode[out]  The new node, properly packed with appropriate data.
     *
     * @return HRESULT
     *
     */
    private Node createResultNode(Node container, Node dataNode)
    {
      Node retNode = null;
      if (m_ResultAttrs != null && m_ResultAttrs.size() > 0)
      {
        if (container.getNodeType() == Node.ELEMENT_NODE)
        {
          retNode = XMLManip.createElement((Element)container, m_ResultNodeName);
        }
        if (retNode != null)
        {
          // If we had been told to include the node name, do it now
          if (m_IncludeNodeName)
          {
            XMLManip.setAttributeValue(retNode, "nodeType_", XMLManip.retrieveSimpleName(dataNode));
          }
          ITypeManager typeMan = null;
          if (m_Project != null)
          {
            typeMan = m_Project.getTypeManager();
          }
          
          int count = m_ResultAttrs.size();
          for (int i=0; i<count; i++)
          {
            String result = "";
            ResultAttr iter = (ResultAttr)m_ResultAttrs.get(i);
            if (typeMan != null && iter.m_PropertyGet)
            {
              String xmiid = XMLManip.getAttributeValue(dataNode, "xmi.id");
              if (xmiid != null && xmiid.length() > 0)
              {
                // We encountered a problem where system upgrade created a bogus node type and
                // we threw at this location.  So rather then abort the entire loop, just skip
                // over anything that fails to Get
                IVersionableElement ver = typeMan.getElementByID(xmiid);
                if (ver != null && ver instanceof IElement)
                {
                  try
                  {
                    Class clazz = ver.getClass();
                    Method meth = null;
                    Method[] meths = clazz.getMethods();
                    if (meths != null)
                    {
                      for (int j=0; j<meths.length; j++)
                      {
                        Method method1 = meths[j];
                        if (method1.getName().equals(iter.m_Query))
                        {
                          meth = method1;
                          break;
                        }
                      }
                    }
                    if (meth != null)
                    {
                      Object obj = meth.invoke(ver, (Object[])null);
                      if (obj != null && obj instanceof String)
                      {
                        result = (String)obj;
                      }
                    }
                  }
                  catch (Exception e)
                  {
                    e.printStackTrace();
                  }
                }
              }
            }
            else
            {
              Node tempNode = dataNode.selectSingleNode(iter.m_Query);
              if (tempNode != null && tempNode.getNodeType() == Node.ATTRIBUTE_NODE)
              {
                result = tempNode.getStringValue();
              }
            }
            
            if (result != null && result.length() > 0)
            {
              XMLManip.setAttributeValue(retNode, iter.m_AttrName, result);
            }
          }
        }
      }
      return retNode;
    }
  }
}


java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.