alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.schema2beans;

import java.util.*;
import java.io.*;


/**
 *  This class provides an implementation of the Iterator interface.
 *
 *  Providing a parsing string (/prop1/prop2/...), the iterator parses
 *  the specified BaseBean, searching for the specified properties.
 *  As the hasMore()/next() methods are called, the parser goes over
 *  all the instances of the BaseBean tree.
 *
 *  For example, assuming we have: /Book/Chapters/Title, the iterator
 *  would return all the titles of all the Chapters of the book.
 *
 *  The iterator always returns elements of the type specified as the
 *  last element of the parsing string. In the above example, the
 *  parser would return only Title elements.
 *
 *  If the parsing string is /EnterpriseBean/Entity, the parser would
 *  return all the Entity beans of the tree. Therefore, the type returned
 *  can be either a BaseBean or a final property type. Note that in case
 *  of a final property value, only objects are returned. Scalar types
 *  are wrapped using the appropriate class (int/Integer, ...).
 *
 *  TODO: support for attributes, keys and limited arrays (only first
 *  element for example).
 *
 */
public class DDParser implements Iterator {

    public static class DDLocation {
	BaseBean	root;
	String  	name;
	int		index;
	int 		type;
	
	public DDLocation(BaseBean r) {
	    this(r, null, -1, 0);
	}
	
	public DDLocation(BaseBean r, String n, int i, int type) {
	    this.root = r;
	    this.name = n;
	    if (i != -1) {
		//  This gets the internal index value that doesn't change
		//  even when an element of the array is removed
		this.index = r.indexToId(n, i);
	    } else
		this.index = i;
	    
	    this.type = type;
	}
	
	public void removeValue() {
	    if (this.index != -1) {
		this.root.removeValue(this.name,
		this.root.getValueById(this.name,
		this.index));
	    }
	    else
		this.root.setValue(this.name, null);
	}
	
	public void setValue(String value) {
	    Object v = value;
	    
	    if (Common.isBoolean(this.type))
		v = Boolean.valueOf(value);
	    
	    if (this.index != -1)
		this.root.setValueById(this.name, this.index, v);
	    else
		this.root.setValue(this.name, v);
	}
	
	public Object getValue() {
	    if (this.root == null || this.name == null)
		return null;

	    if (this.index != -1)
		return this.root.getValueById(this.name, this.index);
	    else
		return this.root.getValue(this.name);
	}
	
	public BaseBean getRoot() {
	    return this.root;
	}
	
	public String getName() {
	    return this.name;
	}
	
	public int getIndex() {
	    if (this.name != null)
		return this.root.idToIndex(this.name, this.index);
	    return this.index;
	}
	
	public boolean isNode() {
	    return Common.isBean(this.type);
	}
	
	public String toString() {	// BEGIN_NOI18N
	    if (this.root != null) {
		return "BaseBean(" + this.root.name() + "." +
		Integer.toHexString(this.root.hashCode()) + ") " +
		    this.name + "[" +
		    ((this.name==null)?"i"+this.index:
		    ""+this.root.idToIndex(this.name, this.index)) +
		    "] - isNode: " +
		    this.isNode();
	    } else {
		return "BaseBean(null)";
	    }
	}				// END_NOI18N
    }
    
    /**
     *	There is one such class per property specified in the parsing string.
     *	For example, if the parsing string is /Book/Chapters/Title,
     *	we would have three instances of the PropParser class. One for Book,
     *	one Chapters and another one for Title. Furthermore, the PropParser
     *	instances would be linked to each other through the parent/child
     *	attributes (Book.parent = null, Book.child = Chapters, ...)
     *
     *	This class really implements the Iterator logic, using a bottom/up
     *	algorithm: the DDParser.next() always asks for the element of the
     *	last PropParser (the one with child = null). Then this element
     *	either return what's available, either asks for its next parent
     *	in order to get new values. Its parent, in turns might asks for
     *	new values to its parents, and so on, until the root is reached and
     *	nothing else is available.
     */
    static class PropParser {
	String 		name;
	int		pos;
	Object[]	values;
	BaseProperty 	baseProp;
	PropParser	parent;
	PropParser	child;
	Object		cache;
	boolean		hasCache;
	BaseBean	curParent;
	String		keyName;
	String		keyValue;
	boolean		autoCreate;
	
	
	PropParser(String n, boolean autoCreate) {
	    int i = n.indexOf('=');
	    if (i != -1) {
		int j = n.indexOf('.');
		if (j != -1 && j < i) {
		    this.name = n.substring(0, j);
		    this.keyName = n.substring(j+1, i);
		    this.keyValue = n.substring(i+1);
		} else {
		    this.name = n.substring(0, i);
		    this.keyName = null;
		    this.keyValue = n.substring(i+1);
		}
	    } else {
		if(n.indexOf('.') != -1) {
		    throw new IllegalStateException(Common.getMessage(
		    "DDParserCannotUseKeyWithOutValue_msg", n));
		}
		
		this.name = n;
		this.keyName = null;
		this.keyValue = null;
	    }
	    
	    if (this.keyValue != null && (this.keyValue.length() > 0) &&
	    (this.keyValue.charAt(0) == '\'' ||
	    this.keyValue.charAt(0) == '"')) {	// NOI18N
		
		this.keyValue =
		this.keyValue.substring(1, this.keyValue.length()-1);
	    }
	    
	    this.autoCreate = autoCreate;
	    this.parent = null;
	    this.pos = 0;
	    this.cache = null;
	    this.parent = null;
	    this.child = null;
	    this.hasCache = false;
	    this.curParent = null;
	}
	
	DDLocation getLocation() {
	    return new DDParser.DDLocation(this.curParent, this.name,
					   ((this.baseProp.isIndexed())?
					    this.pos-1:-1),
					  ((BeanProp)this.baseProp).getType());
	}
	
	void setBaseProperty(BaseProperty bp) {
	    this.baseProp = bp;
	}
	
	BaseBean getCurBaseBean(boolean lastProp) {
	    
	    while(true) {
		int p = this.seekNext();
		if (p != -1) {
		    //	Pos for the next one if intermediate
		    if (!lastProp)
			this.pos++;
		    return (BaseBean)this.values[p];
		}
		try {
		    if (!this.updateValues())
			break;
		} catch(NoSuchElementException e) {
		    break;
		}
	    }
	    
	    return null;
	}
	
        int seekNext() {
            //	Seek doesn't move the pos - next() does
            if (this.baseProp.isBean()) {
                while(this.values.length>this.pos
                      && this.values[this.pos] == null) {
                    this.pos++;
                }
            }
            if (this.values.length == this.pos)
                return -1;
            return this.pos;
        }
	
	static final char WILD_CHAR = '*';
	private boolean checkValueMatch(Object o1, Object o2) {
	    
	    if (o1 == null || o2 == null) {
		return false;
	    } else {
		String s1 = o1.toString();
		String s2 = o2.toString();
		if (s1.charAt(0) == WILD_CHAR) {
		    return s2.endsWith(s1.substring(1));
		} else
		    if (s1.charAt(s1.length()-1) == WILD_CHAR) {
			return s2.startsWith(s1.substring(0, s1.length()-1));
		    } else {
			return s1.equals(s2);
		    }
	    }
	}
	
        //  BaseBean is the parent - get our values from it
        void setValues(BaseBean b) {
            this.curParent = b;
            if (baseProp.isIndexed()) {
                this.values = b.getValues(this.name);
            } else {
                this.values = new Object[1];
                this.values[0] = b.getValue(this.name);
            }
	    
            //  If any keyName/keyValue is used, apply it to the values
            if (this.baseProp.isBean()) {
                if (this.keyName != null && this.keyValue != null) {
		    
                    ArrayList arr = new ArrayList();
                    Object o1 =	Common.getComparableObject(this.keyValue);
                    for (int i=0; i
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.