|
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
new blog posts
- Java: How to get the current date (and time) in Java 8, 11, 14, 17, etc.
- Diverticulitis: A diary of my first bout with diverticulitis (symptoms, testing, and treatment)
- How to format source code blocks in Scaladoc comments
- Functional Programming, Simplified (a best-selling FP book)
- My colectomy (colon resection) experience (diverticula, surgery, recovery, diet)
- Java/Scala/Kotlin: How to round a double (or float) to two decimal places? (formatting output)
- Scala and the two kinds of programming languages
- Sri Nisargadatta Maharaj quotes from '''I Am That'''
- How to open an Apple News URL in Apple News on a Mac
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.
|