PropertyDefinitionFactory.java :  » IDE-Netbeans » uml » org » netbeans » modules » uml » core » support » umlutils » Java Open Source

Java Open Source » IDE Netbeans » uml 
uml » org » netbeans » modules » uml » core » support » umlutils » PropertyDefinitionFactory.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.support.umlutils;

import org.netbeans.modules.uml.core.metamodel.core.constructs.PartFacade;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Vector;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Node;
import java.util.List;
import org.netbeans.modules.uml.common.ETSystem;
import org.netbeans.modules.uml.core.coreapplication.ICoreProduct;
import org.netbeans.modules.uml.core.metamodel.core.constructs.IPartFacade;
import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAssociation;
import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IParameterableElement;
import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IUMLBinding;
import org.netbeans.modules.uml.core.support.umlsupport.ProductRetriever;
import org.netbeans.modules.uml.core.support.umlsupport.XMLManip;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: </p>
 * @author not attributable
 * @version 1.0
 */

public class PropertyDefinitionFactory implements IPropertyDefinitionFactory{

  private String m_definitionFile = null;
  private Document m_Doc = null;
  private Object m_ModelElement = null;
  private Hashtable<String, IPropertyDefinition> m_DefinitionMap = new Hashtable<String, IPropertyDefinition>();
  private HashSet<String> m_NoDefinitionSet = new HashSet<String>();
  private Hashtable<String, Node> m_NodeMap = new Hashtable<String, Node>();
  private Hashtable<String, Node> m_NamedNodeMap = new Hashtable<String, Node>();

  //typedef std::map < UINT, CComPtr< IFunction > > IDMap;
  private Hashtable m_IDMap = new Hashtable();

  //typedef std::map < CComBSTR, IDMap > FunctionMap;
  private Hashtable m_FunctionMap = new Hashtable();


  public PropertyDefinitionFactory() {
  }

  /**
   * Retrieve or create the proper property definition for the passed-in element type.
   *
   * @param[in] eleStr The element type
   * @param[in] pDisp  The model element (used to build the function maps for the IDispatch for faster
   *                   lookup when doing get/set/insert/deletes.  Also used to get the help description)
   * @param[out] pVal  The property definition that has been created or found
   *
   * @return HRESULT
   *
   */
  public IPropertyDefinition getPropertyDefinitionForElement( String eleName, Object pDisp)
  {
    IPropertyDefinition propDef = null;
    if (eleName == null || eleName.length() == 0)
    {
    // have to special case part facade
    if (pDisp instanceof IPartFacade)
    {
      IPartFacade pPart = (IPartFacade)pDisp;

      // actually only need to special case a part facade representing a use case
      // unfortunately this information is on a parameterable element, not the part
      // facade
      if (pPart instanceof IParameterableElement)
      {
        IParameterableElement pParamEle = (IParameterableElement)pPart;
        eleName = "PartFacade";
        String type = pParamEle.getTypeConstraint();
        if (type != null && type.length() > 0)
        {
          eleName += type;
        }
      }
    }
    else if (pDisp instanceof IUMLBinding)
    {
      eleName = "UMLBinding";
    }

    // haven't found it yet, so now use element type
    if (eleName == null || eleName.length() == 0)
    {
      if (pDisp instanceof IElement)
      {
        IElement pUMLEle = (IElement)pDisp;
        eleName = pUMLEle.getElementType();
      }
    }
    }
    propDef = getFromDefinitionMap(eleName);

    if (propDef == null)
    {
      //buildFunctionMap(pDisp);
      
      //This member variable creates a leak.  For instance
      // Open a workspace and then close it right away.  View
      // the memory detector addin and you'll have 2 workspaces
      // still in memory (one is design center).  Then set a break in
      // FinalRelease of Workspace you'll see that this
      // being released does a final release of the IWorkspace.
      //factory 
      //m_ModelElement = pDisp;
      
      propDef = createDefinition(eleName);
      if (propDef != null)
      {
        addToDefinitionMap(eleName, propDef);
      }
    }
    setAppropriateDisplayName(propDef, pDisp);
    return propDef;
  }

    private void setAppropriateDisplayName(IPropertyDefinition propDef, Object pDisp) {
        String expandedType = null;
        if (pDisp instanceof IAssociation) {
             expandedType = ((IElement) pDisp).getExpandedElementType();
             if (expandedType != null && expandedType.trim().length() > 0)
             {
                 propDef.setDisplayName(expandedType.replace('_', ' '));
             }
        } 
        else if (pDisp instanceof PartFacade ) {
            expandedType = ((IElement) pDisp).getExpandedElementType();
            if (expandedType != null) {
                expandedType = expandedType.toLowerCase();
                if  (expandedType.equals("partfacade_class")) {
                    propDef.setDisplayName("PSK_PE_CLASSPARTICIPANT");
                } else if (expandedType.equals("partfacade_interface")) {
                    propDef.setDisplayName("PSK_PE_INTERFACEPARTICIPANT");
                } else if (expandedType.equals("partfacade_actor")) {
                    propDef.setDisplayName("PSK_PE_ACTORPARTICIPANT");
                } else if (expandedType.equals("partfacade_usecase")) {
                    propDef.setDisplayName("PSK_PE_USECASEPARTICIPANT");
                }
            }
        }
    }
  /**
   * Transfer the information from the xml dom node to the property definition.  This handles the special case
   * processing for when the get method returns an IDispatch.  The DispatchInvokes tell us what to do with the
   * IDispatch that was returned.
   *
   * @param[in] pEle   The xml dom node to obtain the information from
   * @param[in] pDef   The property definition to add the information to
   *
   * @return HRESULT
   *
   */
  private void processOtherInvokes(Node pNode, IPropertyDefinition pDef)
  {
    // Some of the get routines return an IDispatch which may or may not need more things done
    // to it in order to display it in the property editor
    // The section in the xml file looks like:
    //       <DispatchInvoke name="{123-456}" get="Type"/>
    // and tells us if the dispatch can be cast to an object represented by the name,
    // then invoke the get="" method on the IDispatch
    String pattern = "DispatchInvoke";
    try {
      if (pNode instanceof org.dom4j.Element)
      {
        org.dom4j.Element ele = (org.dom4j.Element)pNode;
      List list = ele.elements();
      if (list != null && list.size() > 0) {
        for (int i = 0; i < list.size(); i++) {
        Node node = (Node)list.get(i);
        if (node.getName().equals(pattern)) {
          Node nameNode = XMLManip.getAttribute(node, "name");
          Node getNode = XMLManip.getAttribute(node, "get");
          //Node nameNode = XPathAPI.selectSingleNode(node, "@name");
          //Node getNode = XPathAPI.selectSingleNode(node, "@get");
          String name = null;
          String get = null;
          if (nameNode != null)
          name = nameNode.getStringValue();
          if (getNode != null)
          get = getNode.getStringValue();

          pDef.addToAttrMap("castID", name);
          pDef.addToAttrMap("castIDGet", get);
        }
        }
      }
      }
    } catch (Exception e)
    {}
  }

  /**
   * Retrieve the property definition for the passed in value
   *
   * @param[in] name    The element type of the definition to retrieve
   * @param[out] pVal   The retrieved property definition
   *
   * @return HRESULT
   *
   */
  private IPropertyDefinition getFromDefinitionMap(String eName)
  {
    IPropertyDefinition pDef = null;
    try {
      pDef = m_DefinitionMap.get(eName);
    } catch (Exception e)
    {}
    return pDef;
  }

  private Node getFromNodeMap(String eName)
  {
  Node pNode = null;
  try {
    pNode = m_NodeMap.get(eName);
  } catch (Exception e)
  {}
  return pNode;
  }

  private Node getFromNamedNodeMap(String eName)
  {
  Node pNode = null;
  try {
    pNode = m_NamedNodeMap.get(eName);
  } catch (Exception e)
  {}
  return pNode;
  }

  /**
   * Add the passed in property definition to the factory map
   *
   * @param[in] name   The element type
   * @param[in] pVal   The property definition to add to the map
   *
   * @return HRESULT
   *
   */
  private void addToDefinitionMap(String eName, IPropertyDefinition pDef)
  {
    if (eName.length() > 0)
    {
      m_DefinitionMap.put(eName, pDef);
    }
  }

  //this method is added because sub definitions references FontDefinition 
  //multiple times and each time the XPathAPI was used to get to the node,
  //now we are catching the node and using it.
  //Keeps the Node and corresponding id in the map.
  private void addToNodeMap(Node node, String eName)
  {
  if (eName != null && eName.length() > 0)
  {
    m_NodeMap.put(eName, node);
  }
  }

  //Keeps the Node and corresponding name in the map.
  private void addToNamedNodeMap(Node node, String eName)
  {
  if (eName.length() > 0)
  {
    m_NamedNodeMap.put(eName, node);
  }
  }

  /**
   * Process the sub definitions of the xml node.  These are predefined in the xml file.
   *
   * @param[in] parentNode   The xml node to process
   * @param[in] parentDef    The owning property definition to which any subs will be added
   *
   * @return HRESULT
   *
   */
  private void processSubDefinitions(Node pNode, IPropertyDefinition pDef)
  {
    if (pNode.getNodeType() == Node.ELEMENT_NODE)
    {
      org.dom4j.Element elem = (org.dom4j.Element)pNode;
      List list = elem.selectNodes("aDefinition");
      if (list != null)
      {
        int count = list.size();
        for (int i=0; i<count; i++)
        {
        Node n = (Node)list.get(i);
        testmyProcessSubDefinitions(n, pDef);          
        }
      }
    }
  }
  private void testmyProcessSubDefinitions(Node item, IPropertyDefinition pDef)
  {

  Node refNode = XMLManip.getAttribute(item, "pdref");
  //Node refNode = XPathAPI.selectSingleNode(item, "@pdref");
  if (refNode != null)
  {
    // if the sub definition references another definition, we need to build that one
    String refVal = refNode.getStringValue();
    if (refVal.length() > 0)
    {
    // if the sub definition is an on demand definition, we actually don't build
    // it at this time
    Node onDemNode = XMLManip.getAttribute(item, "onDemand");
    //Node onDemNode = XPathAPI.selectSingleNode(item, "@onDemand");
    if (onDemNode != null)
    {
      String onDemand = onDemNode.getStringValue();
      if (onDemand.equals("true"))
      {
      // build part of it because it is on demand
      buildOnDemandDefinition(item, pDef);
      }
      else
      {
      // not on demand, so build it
      Node n = findPropertyDefinitionDOMNodeForSubDef(refVal);
      if (n == null)
      {
        n = findPropertyDefinitionDOMNode(refVal);
      }
      if (n != null)
        processSubDefinitions(n, pDef);
      }
    }
    else
    {
      // not on demand, so build it
      Node n = findPropertyDefinitionDOMNodeForSubDef(refVal);
      if (n == null)
      {
        n = findPropertyDefinitionDOMNode(refVal);
      }
      if (n != null)
      processSubDefinitions(n, pDef);
    }
    }
    else
    {
    // not referencing anything else, so build straight up
    buildDefinition(item, pDef);
    }
  }
  else
  {
    // Need to special case this - the edit control which is using the definitions and
    // factory needs the structure to be like this:
    // <Params
    //   <Param <-- No on demand, but a pdref
    //     <Name
    // The property editor needs it to look like this:
    // <Params
    //   <Param <-- On demand, but a pdref
    // so then when the user clicks on the on demand, the property editor builds the right
    // stuff and replaces the definition
    // If it is not on demand, but pdref'ed, the param node is not built because then in
    // the property editor, we would get
    // <Class
    //    <Classifier
    //      <NamedElement
    // which is why the edit control now has a pdref2 not a pdref
    Node refNode2 = XMLManip.getAttribute(item, "pdref2");
    //Node refNode2 = XPathAPI.selectSingleNode(item, "@pdref2");
    if (refNode2 != null)
    {
    String refVal2 = refNode2.getStringValue();
    Node n = findPropertyDefinitionDOMNodeForSubDef(refVal2);
    if (n != null)
      buildDefinition(n, pDef);
    }
    else
    {
    buildDefinition(item, pDef);
    }
  }
  }    
  

/*  private void processSubDefinitions(Node pNode, IPropertyDefinition pDef)
  {
    try {
      String pattern = "aDefinition";
      //Sumitabh check if this is XPath
      List list = XMLManip.selectNodeListNS(pNode, pattern);
    //List list = XPathAPI.selectNodeList(pNode, pattern);
      if (list != null && list.getLength() > 0)
      {
        for (int i=0; i<list.getLength(); i++)
        {
          Node item = list.item(i);
          Node refNode = XMLManip.getAttribute(item, "pdref");
      //Node refNode = XPathAPI.selectSingleNode(item, "@pdref");
          if (refNode != null)
          {
            // if the sub definition references another definition, we need to build that one
            String refVal = refNode.getNodeValue();
            if (refVal.length() > 0)
            {
              // if the sub definition is an on demand definition, we actually don't build
              // it at this time
              Node onDemNode = XMLManip.getAttribute(item, "onDemand");
        //Node onDemNode = XPathAPI.selectSingleNode(item, "@onDemand");
              if (onDemNode != null)
              {
                String onDemand = onDemNode.getNodeValue();
                if (onDemand.equals("true"))
                {
                  // build part of it because it is on demand
                  buildOnDemandDefinition(item, pDef);
                }
                else
                {
                  // not on demand, so build it
                  Node n = findPropertyDefinitionDOMNodeForSubDef(refVal);
                  if (n != null)
                    processSubDefinitions(n, pDef);
                }
              }
              else
              {
                // not on demand, so build it
                Node n = findPropertyDefinitionDOMNodeForSubDef(refVal);
                if (n != null)
                  processSubDefinitions(n, pDef);
              }
            }
            else
            {
              // not referencing anything else, so build straight up
              buildDefinition(item, pDef);
            }
          }
          else
          {
            // Need to special case this - the edit control which is using the definitions and
            // factory needs the structure to be like this:
            // <Params
            //   <Param <-- No on demand, but a pdref
            //     <Name
            // The property editor needs it to look like this:
            // <Params
            //   <Param <-- On demand, but a pdref
            // so then when the user clicks on the on demand, the property editor builds the right
            // stuff and replaces the definition
            // If it is not on demand, but pdref'ed, the param node is not built because then in
            // the property editor, we would get
            // <Class
            //    <Classifier
            //      <NamedElement
            // which is why the edit control now has a pdref2 not a pdref
            Node refNode2 = XMLManip.getAttribute(item, "pdref2");
      //Node refNode2 = XPathAPI.selectSingleNode(item, "@pdref2");
            if (refNode2 != null)
            {
              String refVal2 = refNode2.getNodeValue();
              Node n = findPropertyDefinitionDOMNodeForSubDef(refVal2);
              if (n != null)
                buildDefinition(n, pDef);
            }
            else
            {
              buildDefinition(item, pDef);
            }
          }
        }
      }
    } catch (Exception e)
    {

    }
  }*/

  /**
   * Transfer the information from the xml dom node to the property definition
   *
   * @param[in] pEle         The xml dom node to obtain the information from
   * @param[in] parentDef    The owning property definition to which to add the newly built definition to
   *
   * @return HRESULT
   *
   */
  private void buildDefinition(Node pNode, IPropertyDefinition pDef)
  {
    try {
      // we have the potential for there to be duplicate property definitions within a single "element"
      // because of multiple inheritance
      // IClass -> IClassifier -> INamespace -> INamedElement
      //           -> IRedefinableElement  -> INamedElement
      //           -> IPackageableElement  -> INamedElement
      // which was then giving us multiple name definitions
      //
      // this now checks its sub definitions for one matching the name, and only builds it if there is
      // not one present
      if (pNode != null) {
        Node pNamedNode = XMLManip.getAttribute(pNode, "name");
    //Node pNamedNode = XPathAPI.selectSingleNode(pNode, "@name");
        if (pNamedNode != null) {
          String name = pNamedNode.getStringValue();
//          Vector defs = pDef.getSubDefinitions();
//          if (defs != null) {
            IPropertyDefinition def = pDef.getSubDefinition(name);
/*            Enumeration enum = defs.elements();
            while (enum.hasMoreElements()) {
              Object obj = enum.nextElement();
              if (obj instanceof IPropertyDefinition) {
                IPropertyDefinition def1 = (IPropertyDefinition) obj;
                if (def1.getName().equals(name))
                {
                  def = def1;
          break;
                }
              }
            }*/
            if (def == null) {
              def = new PropertyDefinition();
              setAttributes(pNode, def);
              pDef.addSubDefinition(def);
              processSubDefinitions(pNode, def);
            }
//          }
        }
      }
    } catch (Exception e)
    {}
  }

  /**
   * Transfer the information from the xml dom node to the property definition for a definition that
   * has been marked as on demand.  This information is different from a node that is built right away.
   *
   * @param[in] pEle         The xml node to obtain the information from
   * @param[in] parentDef    The owning property definition to which to add the newly built definition to
   *
   * @return HRESULT
   *
   */
  private void buildOnDemandDefinition(Node pNode, IPropertyDefinition pDef)
  {
    IPropertyDefinition def = new PropertyDefinition();
    setRefAttributes(pNode, def);
    pDef.addSubDefinition(def);
  }

  /**
   * Catch all routine to build a map of attributes for this xml dom node.  This will catch any
   * attributes that do not have get/set methods for them
   *
   * @param[in] pEle   The xml node to obtain the information from
   * @param[in] pDef   The property definition to add the information to
   *
   * @return HRESULT
   *
   */
  private void processAttributes(Node pNode, IPropertyDefinition pDef)
  {
    if (pNode != null && pDef != null)
    {
      try {
      if (pNode instanceof org.dom4j.Element)
      {            
        org.dom4j.Element ele = (org.dom4j.Element)pNode;
            int count = ele.attributeCount();
            for (int i=0; i<count; i++)
            {
               Attribute attr = ele.attribute(i);
               String name = attr.getName();
               String value = attr.getValue();
               pDef.addToAttrMap(name, value);
            }
            
//        List list = ele.elements();//attributes();
//        if (list != null)
//        {
//          int count = list.size();
//          for (int i=0; i<count; i++)
//          {
//            Attribute attr = (Attribute)list.get(i);
//            String name = attr.getName();
//            String value = attr.getValue();
//            pDef.addToAttrMap(name, value);
//          }
//        }
      }
      }
      catch (Exception e)
      {
        //e.printStackTrace();
      }
    }
  }

 /**
 * Transfer the information from the xml dom node to the property definition
 *
 * @param[in] pEle   The xml dom node to obtain the information from
 * @param[in] pDef   The property defintion to add the information to
 *
 * @return HRESULT
 *
 */
 private void setAttributes(Node pNode, IPropertyDefinition pDef)
 {
   try {
     if (pNode instanceof org.dom4j.Element)
     {
       org.dom4j.Element ele = (org.dom4j.Element)pNode;
       
    //update the ID
       Attribute idAttr = ele.attribute("id");
    if (idAttr != null) {
      String idVal = idAttr.getValue();
      pDef.setID(idVal);
    }
    
    //update the name
    Attribute nameAttr = ele.attribute("name");
    if (nameAttr != null) {
      String nameVal = nameAttr.getValue();
      pDef.setName(nameVal);
    }
    
    //update the display name
    Attribute dispAttr = ele.attribute("displayName");
    if (dispAttr != null) {
      String dispVal = dispAttr.getValue();
      pDef.setDisplayName(dispVal);
    }

    //update the multiplicity
    long mult = 1;
    Attribute multAttr = ele.attribute("multiplicity");
    if (multAttr != null) {
      String multVal = multAttr.getValue();
      if (multVal.equals("*"))
      mult = 2;
    }
    pDef.setMultiplicity(mult);

    //update the control type
    Attribute contAttr = ele.attribute("controlType");
    if (contAttr != null) {
      String contVal = contAttr.getValue();
      pDef.setControlType(contVal);
    }

    //update valid values
    Attribute valAttr = ele.attribute("values");
    if (valAttr != null)
                {
                    String val = valAttr.getValue();
                    pDef.setValidValues(val);
                    processValues(val, pDef);
                    
                    //update valid values
                    Attribute enumAttr = ele.attribute("enumValues");
                    if (enumAttr != null)
                    {
                        String enumVals = enumAttr.getValue();
                        pDef.setEnumValues(enumVals);
                    }
                }

    //update get method name
    String getMethodName = null;
    Attribute getAttr = ele.attribute("get");
    if (getAttr != null) {
      String getVal = getAttr.getValue();
      pDef.setGetMethod(getVal);
      getMethodName = getVal;
    }

    //update set method name
    Attribute setAttr = ele.attribute("set");
    if (setAttr != null) {
      String setVal = setAttr.getValue();
      pDef.setSetMethod(setVal);
    }

    //update insert method name
    Attribute insAttr = ele.attribute("insert");
    if (insAttr != null) {
      String insVal = insAttr.getValue();
      pDef.setInsertMethod(insVal);
    }

    //update delete method name
    Attribute delAttr = ele.attribute("delete");
    if (delAttr != null) {
      String delVal = delAttr.getValue();
      pDef.setDeleteMethod(delVal);
    }

    //update create method name
    Attribute crtAttr = ele.attribute("create");
    if (crtAttr != null) {
      String crtVal = crtAttr.getValue();
      pDef.setCreateMethod(crtVal);
    }

    //update validate method name
    Attribute validAttr = ele.attribute("validate");
    if (validAttr != null) {
      String validVal = validAttr.getValue();
      pDef.setValidateMethod(validVal);
    }

    //update image name
    Attribute imgAttr = ele.attribute("image");
    if (imgAttr != null) {
      String imgVal = imgAttr.getValue();
      pDef.setImage(imgVal);
    }

    //update progID
    Attribute progAttr = ele.attribute("progID");
    if (progAttr != null) {
      String progVal = progAttr.getValue();
      pDef.setProgID(progVal);
    }

    //update help text
    Attribute helpAttr = ele.attribute("helpText");
    if (helpAttr != null) {
      String helpVal = helpAttr.getValue();
      pDef.setHelpDescription(helpVal);
    }
//    else {
//      if (m_ModelElement != null) {
//      buildHelpDocumentation(pDef, m_ModelElement, getMethodName);
//      }
//    }

    //update onDemand
    pDef.setOnDemand(false);
    Attribute demAttr = ele.attribute("onDemand");
    if (demAttr != null) {
      String demVal = demAttr.getValue();
      if (demVal.equals("true"))
      pDef.setOnDemand(true);
    }

    //update required
    pDef.setRequired(false);
    Attribute reqAttr = ele.attribute("required");
    if (reqAttr != null) {
      String reqVal = reqAttr.getValue();
      if (reqVal.equals("true"))
      pDef.setRequired(true);
    }
        
        //update force refresh
    pDef.setForceRefersh(false);
    Attribute refreshAttr = ele.attribute("forceRefresh");
    if (refreshAttr != null) {
      String refreshVal = refreshAttr.getValue();
      if (refreshVal.equals("true"))
      pDef.setForceRefersh(true);
    }

    //update defaultValue
    pDef.setDefaultExists(false);
    Attribute defAttr = ele.attribute("defaultValue");
    if (defAttr != null) {
      String defVal = defAttr.getValue();
      pDef.setDefaultValue(defVal);
      pDef.setDefaultExists(true);
    }
     }

     // call to build any other attributes that may not be listed here
     processAttributes(pNode, pDef);

     // new section in the xml file that states what to do with the information
     // we receive back from a "get" call, when that information is a IDispatch
     processOtherInvokes(pNode, pDef);
   } catch (Exception e)
   {
     //e.printStackTrace();
   }
 }

 /**
  * Transfer the information from the xml dom node to the property definition.  This is a special
  * case if the property definition is referencing some other definition.  Only certain things need
  * to be stored.
  *
  * @param[in] pEle   The xml dom node to transfer the information from
  * @param[in] pDef   The property definition to add the information to
  *
  * @return HRESULT
  *
  */
 private void setRefAttributes(Node pNode, IPropertyDefinition pDef)
 {
   try {
     if (pNode instanceof org.dom4j.Element)
     {
       org.dom4j.Element ele = (org.dom4j.Element)pNode;
       
    //update the ID
    Attribute idNode = ele.attribute("id");
    if (idNode != null) {
      String idVal = idNode.getValue();
      pDef.setID(idVal);
    }

    //update the name
    Attribute nameNode = ele.attribute("pdref");
    if (nameNode != null) {
      String nameVal = nameNode.getValue();
      //This is different from C++ version, as our pdref is ID
      org.dom4j.Element domEle = m_Doc.elementByID(nameVal);
      if (domEle != null)
      {
        String actualName = domEle.attributeValue("name");
      pDef.setName(actualName);
      pDef.setOnDemand(true);
      }
    }

    //update the control type
    Attribute contNode = ele.attribute("controlType");
    if (contNode != null) {
      String contVal = contNode.getValue();
      pDef.setControlType(contVal);
    }

    //update progID
    Attribute progNode = ele.attribute("progID");
    if (progNode != null) {
      String progVal = progNode.getValue();
      pDef.setProgID(progVal);
    }
     }
     
     // catch all to process any other attributes not listed here
     processAttributes(pNode, pDef);
   } catch (Exception e)
   {}
 }

 /**
  * Build the help string for the property definition based on the "get" function
  *
  * @param[in] pDef      The property definition to add the help information to
  * @param[in] pDisp     The IDispatch to obtain the help information from
  * @param[in] funcName  The function whose help documentation we are getting
  *
  * @return HRESULT
  *
  */
 private void buildHelpDocumentation(IPropertyDefinition pDef, Object pDisp, String funcName)
 {
   if (funcName != null)
   {
     pDef.setHelpDescription(funcName);
   }
   else
   {
     // just set it to the class name.
     pDef.setHelpDescription(pDisp.getClass().getName());
   }
   //Sumitabh might have to get it from getElementTypeDocMap?
 }



  /**
   * Initialize the factory
  */
  public void initialize()
  {

  }

  /**
   * Get the Method that matches the passed-in method name and parmType list in passed pDisp.
   *
   * @param[in] pDisp  The IDispatch to obtain the function information from
   * @param[in] memID  The ID of the function that we are looking for
   * @param[out] pVal  The IDispatch of the found function
   *
   * @return HRESULT
   *
   */
  public Object getFromFunctionMap( Object pDisp, String methName, String[] parmTypes )
  {
    Method func = null;
    try {
      Class clazz = pDisp.getClass();
      Class[] parms = null;
      if (parmTypes != null && parmTypes.length > 0) {
        parms = new Class[parmTypes.length];
        for (int i = 0; i < parmTypes.length; i++) {
          parms[i] = Class.forName(parmTypes[i]);
        }
      }
      func = clazz.getMethod(methName, parms);
    } catch(Exception e)
    {}
    return func;
  }


  /**
   * Retrieve documentation information from an already built map based on Object type
  */
  public void getFromElementTypeDocMap( Object pDisp, String pVal )
  {

  }

  /**
   * Gets the xml file that defines the property definitions
  */
  public String getDefinitionFile()
  {
    return m_definitionFile;
  }

  /**
   * Gets the xml file that defines the property definitions
  */
  public void setDefinitionFile( String value )
  {
    m_definitionFile = value;
  }

  /**
   * There were some cases where the property definitions are contained in a file, and we want them
   * all to be built at once.  The property editor builds them as it needs to, the preference manager
   * just builds them all at once.
   *
   * The file needs to have already been set before calling this function.
   *
   * @param pVal[out]  The property definitions that were built
   *
   * @return HRESULT
   *
   */
  public Vector<IPropertyDefinition> buildDefinitionsUsingFile()
  {
    Vector<IPropertyDefinition> vec = new Vector<IPropertyDefinition>();
    try {
      if (m_definitionFile != null && m_definitionFile.length() > 0) {
        ETSystem.out.println(m_definitionFile);
        Document doc = XMLManip.getDOMDocument(m_definitionFile);
        if (doc != null) {
          // loop through all property definitions and build them
          // wanted to use existing "create" code, so we just get the name
          // of the property definition and then ask the same mechanism that
          // was used for the property editor
          String pattern = "//PropertyDefinition";
      List list = doc.selectNodes(pattern);
          //List list = XPathAPI.selectNodeList(doc, pattern);
          if (list != null && list.size() > 0) {
            
            //just go through all PropertyDefinition nodes and store the name
            // and id in a hashtable.
      for (int i = 0; i < list.size(); i++) {
        Node node = (Node)list.get(i);
        if (node.getNodeType() == Node.ELEMENT_NODE)
        {
          String name = ((org.dom4j.Element)node).attributeValue("name");
          String id = ((org.dom4j.Element)node).attributeValue("id");
          addToNodeMap(node, id);
          addToNamedNodeMap(node, name);
        }
      }
            
            for (int i = 0; i < list.size(); i++) {
              Node node = (Node)list.get(i);
              Node nameNode = XMLManip.getAttribute(node, "name");
        //Node nameNode = XPathAPI.selectSingleNode(node, "@name");
              if (nameNode != null) {
                IPropertyDefinition def = getPropertyDefinitionForElement(
                    nameNode.getStringValue(), null);
                if (def != null) {
                  vec.add(def);
                }
              }
            }
          }
        }
      }
    } catch (Exception e)
    {
      e.printStackTrace();
    }

    return vec;
  }

  /**
   * The property definition can have several values for its "values" field: it can be
   * a hardcoded string ("public|private"), a string ("FormatString"), a xpath query(#//UML:Class/@name),
   * or an xpath query plus file (Languages.etc#//Language/@type).
   *
   * This method interprets the value and fills in the appropriate information
   *
   *
   * @param pVal[in]  String stored in definition attribute "values"
   * @param pDef[in]  property definition to process
   *
   * @return
   *
   */
  private void processValues(String pVal, IPropertyDefinition pDef)
  {
    //only do something if pVal has some value
    if (pVal != null && pVal.length() > 0)
    {
      // if it has a "#" in it, then this is an xpath query
      // it could either be a xpath query on a given file
      // or an empty file means perform the query on the current project
      int pos = pVal.indexOf("#");
      if (pos >=0)
      {
        // have found a #, but now need to check if it is a protected value in a list
        int pos2 = pVal.indexOf("|#|");
        if (pos2 >= 0)
        {
          pDef.setValidValues2(pVal);
        }
        else
        {
          // this is a # in a string that should represent a file and an xpath
          String[] strs = pVal.split("#");
          if (strs != null && strs.length > 1)
          {
            String fileName = strs[0];
            String xpath = strs[1];
            if (fileName.length() > 0)
            {
              //Sumitabh use IConfigManager to get the document using home etc.
              
        String configLoc = ProductRetriever.retrieveProduct().getConfigManager().getDefaultConfigLocation();
        //m_ConMan.getDefaultConfigLocation();
        configLoc += fileName;
              Document doc = XMLManip.getDOMDocument(configLoc);
              if (doc != null) {
                try {
                  List list = XMLManip.selectNodeList(doc, xpath);
                  if (list != null && list.size() > 0) {
                    String val = "";
                    for (int i = 0; i < list.size(); i++) {
                      Node lNode = (Node)list.get(i);
                      if (val.length() > 0)
                        val += "|";
                      val += lNode.getStringValue();
                    }
                    pDef.setValidValues2(val);
                  }
                } catch(Exception e)
                {}
              }
            }
            else
            {
                    // we do not have a file, so our requirements are to search the current project
                    // unfortunately at this time, we do not have that information
                    // the values for the property definition will have to be built at a later time
            }
          }
        }
      }
      else
      {
        // the values string did not contain any xpath stuff
        // so check for other known values
        pos = pVal.indexOf("FormatString");
        if( pos >= 0)
        {
                // the definition has been marked to contain a format string
                // unfortunately at this time, we do not have that information
                // the values for the property definition will have to be built at a later time
        }
        else
        {
          pos = pVal.indexOf("::");
          if (pos >= 0)
          {
            // the definition has an object and a method stored in it that needs to be
            // created and then invoked in order to have the value
            String[] strs = pVal.split("::");
            if (strs != null && strs.length > 1)
            {
              //first element will be object name and second will be method name
              String objName = strs[0];
              String methName = strs[1];
              if (objName.length() >0 && methName.length()>0)
              {
                 Object objInstance = null;
                 if(objName.equals("org.netbeans.modules.uml.core.metamodel.core.foundation.ConfigManager") == true)
                 {
                    objInstance = retrieveConfigManagerAsObject();   
                 }
                 else if(objName.equals("org.netbeans.modules.uml.core.reverseengineering.reframework.parsingframework.LanguageManager") == true)
                 {
                    objInstance = retrieveLanguageManagerAsObject(); 
                 }
                 
                //now invoke this method on this object and get the result -
                //these are values
                try 
                {
                   objInstance = retrieveObject(objName);
//                  Class clazz = Class.forName(objName);
//                  objInstance = clazz.newInstance();
                  
                   if(objInstance != null)
                   { 
                      //Sumitabh need to figure out the parameters - may be we need third
                      //parameter in pVal :: separated.
                      Method meth = objInstance.getClass()
                        .getMethod(methName, (Class[])null);
                      
                      Object obj = meth.invoke(objInstance, (Object[])null);
                      if (obj != null)
                      {
                         //if (obj.getClass().getName().equals("java.lang.String"))
            pDef.setValidValues(obj.toString());
                         pDef.setValidValues2(obj.toString());
                      }
                   }
                }catch (Exception e)
                {
                   //e.printStackTrace();
                }
              }
            }
          }
          else
            pDef.setValidValues2(pVal);
        }
      }
    }
  }


   protected Object retrieveConfigManagerAsObject()
   {
      Object retVal = null;
      
      ICoreProduct product = ProductRetriever.retrieveProduct();
      if(product != null)
      {
         retVal = product.getConfigManager();
      }
      
      return retVal;
   }
   
   protected Object retrieveLanguageManagerAsObject()
   {
      Object retVal = null;
      
      ICoreProduct product = ProductRetriever.retrieveProduct();
      if(product != null)
      {
         retVal = product.getLanguageManager();
      }
      
      return retVal;
   }

   protected Object retrieveObject(String objName)
      throws ClassNotFoundException, InstantiationException, IllegalAccessException
   {
      Object retVal = null;
      
      ICoreProduct product = ProductRetriever.retrieveProduct();
      if(product != null)
      {
         Class clazz = Class.forName(objName);         
         retVal = clazz.newInstance();
      }
      
      return retVal;
   }
   
  /**
   * Gets the xml document that defines the property definitions
  */
  public Document getXMLDocument()
  {
    return m_Doc;
  }

  /**
   * Gets the xml document that defines the property definitions
  */
  public void setXMLDocument( Document value )
  {
    m_Doc = value;
  }

  /**
   * Retrieve or create the proper property definition for the passed-in name.
   *
   * @param[in] eleStr The name of the property definition
   * @param[out] pVal  The property definition that has been created or found
   *
   * @return HRESULT
   *
   */
  public IPropertyDefinition getPropertyDefinitionByName( String name)
  {
    IPropertyDefinition def = null;
    if (name != null && name.length() > 0)
    {
      def = getFromDefinitionMap(name);
      if (def == null)
      {
        if (m_NoDefinitionSet.contains(name)) 
        {
          return null;
        }
        def = createDefinition(name);
      }
      if (def != null)
      {
        addToDefinitionMap(name, def);
      }
      else 
      {
        m_NoDefinitionSet.add(name);
      }
    }
    return def;
  }

  /**
   *  Given a xml node, build the corresponding property definition
   *
   *
   * @param pNode[in]        The node for which we want to build a definition
   * @param pDef[out]        The newly created definition
   *
   * @return HRESULT
   *
   */
  public IPropertyDefinition buildDefinitionFromNode( Node pNode )
  {
    IPropertyDefinition def = null;
    if (pNode != null)
    {
      Document doc = pNode.getDocument();
      setXMLDocument(doc);
      def = new PropertyDefinition();
      setAttributes(pNode, def);
      processSubDefinitions(pNode, def);
    }
    return def;
  }

  /**
   *  Given a xml node, build the corresponding property definition
   *
   *
   * @param pNode[in]        The node for which we want to build a definition
   * @param pDef[out]        The newly created definition
   *
   * @return HRESULT
   *
   */
  public IPropertyDefinition buildDefinitionFromString( String str )
  {
    IPropertyDefinition def = null;
    try {
      if (str != null && str.length() > 0) {
        Document doc = XMLManip.getDOMDocumentFromString(str);
        if (doc != null) {
          String pattern = "PropertyDefinition";
          List list = doc.selectNodes(pattern);
          if (list != null && list.size() > 0)
          {
      Node n = (Node)list.get(0);
      //Node n = XPathAPI.selectSingleNode(doc, pattern);
      if (n != null) {
        def = new PropertyDefinition();
        setAttributes(n, def);
        processSubDefinitions(n, def);
      }
          }
        }
      }
    } catch (Exception e)
    {}
    return def;
  }

  /**
   * Find the xml dom node that defines the passed in value.  The definition file is created based on element
   * type.
   *
   * @param[in] name   The element type
   * @param[out] pVal  The dom node in the definition file matching the element type
   *
   * @return HRESULT
   *
   */
  private Node findPropertyDefinitionDOMNode(String name)
  {
    Node node = null;
    try {
      if (name != null && name.length() > 0) 
      {
        if (m_NamedNodeMap != null)
        {
          node = getFromNamedNodeMap(name);
        }
        if (node == null)
        {
          if (m_Doc != null) {
          String pattern = "//PropertyDefinition[@name=\'";
          pattern += name;
          pattern += "\']";
          node = m_Doc.selectSingleNode(pattern);
          }
        }
      }
    } catch (Exception e)
    {}
    return node;
  }

  //used for building sub definitions.
  private Node findPropertyDefinitionDOMNodeForSubDef(String name)
  {
  Node retNode = getFromNodeMap(name);
    if (retNode == null)
    {
    retNode = m_Doc.elementByID(name);
      if (retNode != null)
      {
        addToNodeMap(retNode, name);
      }
    }
  return retNode;
  }
  /**
   * Build a property definition
   *
   * @param[in] name   The element type
   * @param[out] pVal  The property definition that was just built
   *
   * @return HRESULT
   *
   */
  private IPropertyDefinition createDefinition(String name)
  {
    IPropertyDefinition def = null;
    if (name != null && name.length()>0)
    {
      try {
        if (m_definitionFile != null && m_definitionFile.length() > 0) {
          if (m_Doc == null) {
            m_Doc = XMLManip.getDOMDocument(m_definitionFile);
          }
          if (m_Doc != null) {
            Node domNode = findPropertyDefinitionDOMNode(name);
            if (domNode != null) {
              def = new PropertyDefinition();
              setAttributes(domNode, def);
              processSubDefinitions(domNode, def);
              addToNodeMap(domNode, name);
            }
          }
        }
      } catch (Exception e)
      {}
    }
    return def;
  }
}
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.