Link to home
Start Free TrialLog in
Avatar of rmvprasad
rmvprasad

asked on

Creating a class using Generics

I have a task which is to take the element of an xml file and create a class by the name of the element and pass the attributes as parameters of the constructor of that class.
If the element is Abc a class by name Abc should be formed. The xml may consist of different elements at different times. I thought of approaching the issue using generics as the name of the class is not known ahead of time. I am getting it. Could anyone help me out of this.
//After parsing the xml file the following method should generate the class   
 public void generateClassNode()
    {
        String xmlFile="Member.xml";
        Node classNode=null;
        Document doc=null;
        System.out.println("Entered generate class node");
        NodeFilter filter = new NodeFilter() {
        public short acceptNode(Node n) {
        if (n.getNodeType() == Node.ATTRIBUTE_NODE || n.getNodeType()==Node.ELEMENT_NODE)
        {
          if (((Text) n).getData().trim().length() == 0)
            return NodeFilter.FILTER_REJECT;
        }
        return NodeFilter.FILTER_ACCEPT;
      }
    };
   
    int whattoshow = NodeFilter.SHOW_ELEMENT & NodeFilter.SHOW_ATTRIBUTE;
   
    if((doc=parseFile(xmlFile))!=null)
    {
        System.out.println("Before traversal ...");
        DocumentTraversal docTraverse =(DocumentTraversal)doc;
        TreeWalker twlk = docTraverse.createTreeWalker(doc.getDocumentElement(), whattoshow, filter, false);
        System.out.println("Before for loop");
        Node rootnode = twlk.getRoot();
        //NodeList nlist = rootnode.getChildNodes();
        NodeList nlist = doc.getElementsByTagName("*");
        System.out.println("The size of node list is "+ nlist.getLength());       
        //for(Node n=twlk.firstChild(); twlk.lastChild()=null; n=twlk.nextSibling())
        for(int i=0;i<nlist.getLength();i++)
        {
            System.out.println("Inside for loop");
            Node n=nlist.item(i);
           
            if(n.getNodeType()==Node.ELEMENT_NODE || n.getNodeType()==Node.ATTRIBUTE_NODE)
            {         
                String element=n.getNodeName();
                generateClass(element);
                System.out.println(element);  
            }
            if(n.getNodeType()==Node.ATTRIBUTE_NODE)
            {
                HashMap attributeBucket = new HashMap();
                String element=n.getNodeName();
                String value=n.getNodeValue();
                System.out.println(element+"= "+value); 
            }       
        }
    } 
  }
 
   //The following code generates the class of the string name
    void generateClass(String className)
    {
        String classStr=generateUcasechar(className);
        Class<T> tclass;
        tclass = (<T>)Class.forName(classStr);
       
    }
   
    //Following class changes the first char of the string into upper case to be suitable   //for the being created as class
    String generateUcasechar(String className)
    {
        StringBuilder name = new StringBuilder(className);
        name.setCharAt(0, (char)(name.charAt(0) -32));
        for(int i = 1 ; i < name.length() ; i++){
            if(name.charAt(i -1) == ' ' && name.charAt(i) != ' '){
                name.setCharAt(i, (char)(name.charAt(i) -32));
            }
        }
        return name.toString();
    }

Open in new window

Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

I wouldn't reinvent the wheel. Commons Digester will do this for you, along with a host of other things
Avatar of rmvprasad
rmvprasad

ASKER

Thanks. I have looked to it. Could you please explain it with using Generics so I can get used to generics.
Another main reason for not showing intrest in common Digester is it is using xpath. So the path and the element needs to be known ahead of time. Here in my case it needs to generate a class based on the name of the element. Common Digester sample code is pasted below.

    Digester digester = new Digester();
    // This method pushes this (SampleDigester) class to the Digesters
    // object stack making its methods available to processing rules.
    digester.push(this);
    // This set of rules calls the addDataSource method and passes
    // in five parameters to the method.
    digester.addCallMethod("datasources/datasource", "addDataSource", 5);
    digester.addCallParam("datasources/datasource/name", 0);
    digester.addCallParam("datasources/datasource/driver", 1);
    digester.addCallParam("datasources/datasource/url", 2);
    digester.addCallParam("datasources/datasource/username", 3);
    digester.addCallParam("datasources/datasource/password", 4);
   
    // This method starts the parsing of the document.
    digester.parse("datasource.xml");
  }
  // Example method called by Digester.
  public void addDataSource(String name,
                            String driver,
                            String url,
                            String userName,
                            String password)
its not really appropriate for generics. with generics you can wite code to operate on different classes of objects, but you need to be able to pass the type involved.

eg. to crete a collection you need to know what type of collection you want.

List s = new ArrayList();

ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial