private TypeNode addNode()

in CasViewerEclipsePlugin/uimaj-ep-casviewer-core/src/main/java/org/apache/uima/casviewer/core/internal/TypeTree.java [299:470]


    private TypeNode addNode (String parentName, TypeDescription childTypeMetadata) 
    {	
        // Find "parent" node
        if (parentName != null && parentName.trim().length() == 0) {
            parentName = null;
        }
        TypeNode nodeParent = null;
        if (parentName != null) {
            nodeParent = (TypeNode) _nodesHashtable.get(parentName);
        }
        
        // Find "child" node
        String childName = childTypeMetadata.getName();
    	TypeNode node = (TypeNode) _nodesHashtable.get(childName);

    	// System.err.println(" parentName: " + parentName + " ; childName: " + childName);
    
        // NEW type definition ?
    	if ( node == null ) {		
    		// Not found "child". NEW type definition.
    		if ( nodeParent == null ) {
                // Parent is NEW
                // TOP has null parent
                if (parentName != null) {
                  TypeDescription typeParent = getBuiltInType(parentName);
                    if (typeParent != null) {
                        // Built-in Type as Parent
                        nodeParent = addNode (typeParent.getSupertypeName(), typeParent);
                        // Trace.trace(" -- addNode: " + childName + " has New Built-in Parent: " + parentName);
                    } else {                    
            			// NEW parent also.
                        // "parentName" is FORWARD Reference Node
            			nodeParent = insertForwardedReferenceNode(_rootSuper, parentName);  
                        // Trace.trace(" -- addNode: " + childName + " has New FORWARD Parent: " + parentName);
                    }
                }
    		}
    		// System.out.println(" -- addNode: New child");		
    		return insertNewNode (nodeParent, childTypeMetadata);
    	}
    	
        //
        // childTypeMetadata is ALREADY in Hierarchy
        //
        
    	// This node can be a Forwarded Reference type
    	if (node.getObject() == null) {
    		// Set Object for type definition
    		// Reset label.
    		// Trace.trace("Update and define previously forwarded reference type: "
    		//		+ node.getLabel() + " -> " + parentName);
            // Need to "remove" and "put" back for TreeMap (no modification is allowed ?)
            node.getParent().removeChild(node);
    		node.setObject(childTypeMetadata);
            node.setLabel(childTypeMetadata.getName());
            node.getParent().addChild(node);
            
            // Remove from undefined types
            // Trace.trace("Remove forward ref: " + childTypeMetadata.getName());
            _undefinedTypesHashtable.remove(childTypeMetadata.getName());
    	}
    	
    	if (parentName == null) {
    		// NO Parent
            if (childTypeMetadata.getName().compareTo(UIMA_CAS_TOP) != 0) {
                Trace.err("??? Possible BUG ? parentName==null for type: "
                        + childTypeMetadata.getName());
            }
    		return node;
    	}
    	
    	// Found "child".
    	// This node can be the "parent" of some nodes 
    	// and it own parent is "root" OR node of "parentName".
    	if ( node.getParent() == _rootSuper ) {
    		// Current parent is SUPER which may not be the right parent
    		// if "node" has a previously forward referenced parent of some type.
    		// Find the real "parent".
    		if ( nodeParent != null ) {
    		    // Parent node exists. 
    			if ( nodeParent != _rootSuper ) {
    			    // Move "node" from "root" and put it as child of "nodeParent"
    				// Also, remove "node" from "root"
    			    // _rootSuper.getChildren().remove(node.getLabel());
                    // System.out.println("B remove");
    			    if (_rootSuper.removeChild(node) == null) {
                        System.out.println("??? [.addNode] Possible BUG 1 ? cannot remove "
                                + node.getLabel() + " from SUPER");
                        System.out.println("  node: " + ((Object)node).toString());  
                        Object[] objects = _rootSuper.getChildrenArray();
                        for (int i=0; i<objects.length; ++i) {
                            System.out.println("    " + objects[i].toString());              
                        }                  
                    }
                    // System.out.println("E remove");
    			} else {
    				// "nodeParent" is "SUPER".
    				return node;
    			}
    		} else {
    			// NEW parent
				// Remove "node" from "SUPER" and insert it as child of "nodeParent"
			    // _rootSuper.getChildren().remove(node);
                if (_rootSuper.removeChild(node) == null) {
                    System.err.println("??? [.addNode] Possible BUG 2 ? cannot remove "
                            + node.getLabel() + " from SUPER");
                }			    
                TypeDescription typeParent = getBuiltInType(parentName);
                if (typeParent != null) {
                    // Built-in Type as Parent
                    nodeParent = addNode (typeParent.getSupertypeName(), typeParent);
                    // Trace.trace(" -- addNode 2: " + childName + " has New Built-in Parent: " + parentName);
                } else {                
    			    // It is a NEW parent and this parent is forwarded reference (not defined yet). 
    			    // Insert this parent as child of "SUPER"
    				nodeParent = insertForwardedReferenceNode(_rootSuper, parentName);
                    // Trace.trace(" -- addNode 2: " + childName + " has New FORWARD Parent: " + parentName);
                }
    		}				
    		TypeNode tempNode;
    		if ( (tempNode = nodeParent.insertChild(node)) != null && tempNode != node) {
    			// Duplicate Label
                Trace.err("Duplicate Label 1");
//    			node.setShowFullName(true);
    			if (node.getObject() != null) {
    				node.setLabel(((TypeDescription)node.getObject()).getName());
    			}				
    			nodeParent.insertChild(node);
    		}
    	} else if ( node.getParent() != null ) {
    	    //
    	    //	ERROR !!!
    		//  "duplicate definition" or "have different parents"
    	    //
    	    
    	    // "nodeParent" should be non-null and be the same as "node.getParent"
    	    // In this case, it is duplicate definition
    	    if ( nodeParent != null ) {
    	        if (nodeParent == node.getParent()) {
    				// Error in descriptor
    		        // Duplicate definition
    				// System.err.println("[TypeSystemHierarchy - addNode] Duplicate type: child=" + childName + " ; parent =" + parentName);
    	        } else {
    	            // Error: "node" has different parents
    	            // Both parents are registered
    				System.err.println("[TypeSystemHierarchy - addNode] Different registered parents: child=" + childName 
    				        + " ; old node.getParent() =" + node.getParent().getLabel()
    				        + " ; new parent =" + parentName);
    	        }
    	    } else {
    	        // Error 
                // Error: "node" has different parents
                // Old parent is registered
    	        // New parent is NOT registered
    			System.err.println("[TypeSystemHierarchy - addNode] Different parents: child=" + childName 
    			        + " ; old registered node.getParent() =" + node.getParent().getLabel()
    			        + " ; new NON-registered parent =" + parentName);
    	    }
    	    return null;   // ERROR
    
    	} else {
    		//
    	    // Program BUG !!!
    		// since Parent of "registered" node cannot be null.
            // if (childTypeMetadata.getName().compareTo(UIMA_CAS_TOP) != 0) {
                System.err.println("[TypeSystemHierarchy - addNode] Program BUG !!! (node.getParent() == null): child=" + childName + " ; parent =" + parentName);
                return null;
            // }
    	}
    		
    	return node;
    } // addNode