|
What this is
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.*;
/**
* The DDRegistryParser is a parser/Iterator on a set of graphs, as
* registered in the schema2beans registry (DDRegistry).
*
* DDParser is a parser/Iterator on a single schema2beans graph, using
* a schema2beans path description to define what should be parsed.
* DDRegistryParser extend the functiionality of DDParser by providing
* a parsing mechanism on a set of graphs (instead of a single one) and
* by adding more syntax to the DDParser schema2beans path syntax.
*
* Where DDParser defined a DDLocation to define a location reference in
* the parsed graph, DDRegistryParser defines a DDCursor. The DDCursor
* defines a location on a set of graphs (a DDCursor might have a parent
* root defined in another graph).
*
* The DDRegistryParser instances are created by the DDRegistry.
*/
public class DDRegistryParser implements Iterator {
static final String CURRENT_CURSOR = "."; // NOI18N
/**
* Analyze and resolve the vriable references specified in the path
*/
static public class PathResolver {
static final char VARBEGIN = '{';
static final char VAREND = '}';
static final char VALUE = '#';
// Current module (display/non unique) name
static final String VAR_MODNAME = "mname"; // NOI18N
// Current module unique name
static final String VAR_UNAME = "uname"; // NOI18N
// Parent schema2beans type of the specified type {#ptype.EnvEntry}
// would be either Session or Entity.
static final String VAR_PTYPE = "ptype"; // NOI18N
static final String VAR_TYPE = "type"; // NOI18N
String result = null;
//
public PathResolver() {
}
//
public PathResolver(DDCursor cursor, String path) {
this.result = this.resolvePath(cursor, path);
}
static boolean needResolving(String path) {
if (path != null)
return (path.indexOf(VARBEGIN) != -1);
else
return false;
}
/**
* This resolve all the variables referenced in the path string
* using the knowledge of its current location. A variable is
* defined with braces {}, and might use any of the values:
*
* #mname, #uname, #ptype, #type
*
* or any reference to a property of the current graph:
*
* {NodeName} // no # in this case
*
*/
String resolvePath(DDCursor cur, String path) {
if(path.indexOf(VARBEGIN) != -1) {
int i1 = path.indexOf(VARBEGIN);
int i2 = path.indexOf(VAREND);
String v =
(String)this.resolvePathVar(cur, path.substring(i1+1, i2));
return path.substring(0, i1).trim() + v +
this.resolvePath(cur, path.substring(i2+1));
}
return path.trim();
}
Object resolvePathVar(DDCursor cur, String path) {
path.trim();
if (path.indexOf(VARBEGIN) != -1 || path.indexOf(VAREND) != -1) {
throw new IllegalArgumentException(Common.getMessage(
"CannotNestDeclaration_msg"));
}
if (path.indexOf('#') == 0 ) {
path = path.substring(1, path.length());
String remSuffix = null;
int idx = path.indexOf('-');
if (idx != -1) {
// Might have to remove a suffix from the value
remSuffix = path.substring(idx+1);
path = path.substring(0, idx);
}
if (path.startsWith(VAR_MODNAME)) {
int in = path.indexOf(':');
if (in != -1) {
String name = path.substring(in+1);
path = this.getDDNameValue(cur, name).toString();;
path = cur.getRegistry().getName(path);
} else {
path = cur.getRegistry().getName(cur);
}
} else
if (path.startsWith(VAR_UNAME)) {
path = cur.getRegistry().getID(cur);
} else
if (path.startsWith(VAR_PTYPE)) {
int i = path.indexOf('.');
if (i != -1) {
String t = path.substring(i+1);
DDCursor pc = cur;
BaseBean bean;
do {
bean = this.getBean(pc.getRoot(), t);
if (bean == null) {
pc = pc.getParent();
}
} while(bean == null && pc != null);
if (bean != null) {
path = bean.parent().name();
}
}
} else
if (path.startsWith(VAR_TYPE)) {
path = cur.getRoot().name();
}
if (remSuffix != null) {
if (path.endsWith(remSuffix)) {
path = path.substring(0, path.length() -
remSuffix.length());
}
}
return path;
} else {
return this.getDDNameValue(cur, path);
}
}
private Object getDDNameValue(DDCursor pc, String path) {
Object val = null;
// Look for the value in the DDCursors and current graph
// hierarchy (look first in the graph then in other DDCursors)
do {
val = this.getValue(pc.getRoot(), path);
if (val == null) {
pc = pc.getParent();
}
} while(val == null && pc != null);
return val;
}
BaseBean getBean(BaseBean root, String name) {
while (root != null && !root.isRoot()) {
if (root.hasName(name))
return root;
root = root.parent();
}
return null;
}
String getValue(BaseBean root, String name) {
String val = null;
if (root != null) {
do {
try {
val = (String)root.getValue(name);
break;
} catch(Exception e) {
// Unknown property name - ignore it
}
root = root.parent();
} while (root != null && !root.isRoot());
}
return val;
}
public String toString() {
return this.result;
}
}
/**
* DDCursor is a location reference in one of the DDRegistry graphs.
* Note that DDCursor can be created in two different ways: from a schema2beans
* path or from a schema2beans node (BaseBean).
*/
static public class DDCursor {
DDCursor parent;
BaseBean root;
DDRegistry registry;
public DDCursor(DDCursor parent, String path) {
this(parent, (BaseBean)null);
this.resolve(path);
}
public DDCursor(DDCursor parent, BaseBean root) {
this.parent = parent;
this.root = root;
if (this.registry == null && parent != null)
this.registry = parent.registry;
}
public DDCursor(DDRegistry reg, String path) {
this.parent = null;
this.root = null;
this.registry = reg;
this.resolve(path);
}
public DDCursor(DDRegistry reg, BaseBean root) {
this.parent = null;
this.root = root;
this.registry = reg;
}
public DDRegistry getRegistry() {
return this.registry;
}
public BaseBean getRoot() {
return this.root;
}
public DDCursor getParent() {
return this.parent;
}
public Object getValue(String name) {
if (root != null)
return this.root.getValue(name);
else
return null;
}
void resolve(String path) {
if (path == null) return;
path = path.trim();
if (path.equals("")) return; // NOI18N
if (path.startsWith("[") && path.endsWith("]")) { // NOI18N
this.resolveGraph(path.substring(1,path.length()-1));
return;
}
// Find the proper root
if (this.parent == null) {
throw new IllegalStateException(Common.getMessage(
"CantResolveBecauseMissingParent_msg", path));
}
// Resolve any embeded {} variables
if (PathResolver.needResolving(path))
path = (new PathResolver(this.parent, path)).toString();
BaseBean root = this.parent.getRoot();
if (root != null) {
DDParser p = new DDParser(root, path);
if (p.hasNext()) {
Object o = p.next();
if (o instanceof BaseBean) {
this.root = (BaseBean)o;
} else {
throw new IllegalStateException(
Common.getMessage(
"ParsingPathDoesntResolveToGraphNodeElement_msg",
path, o.getClass().getName(), o.toString()));
}
} else {
throw new IllegalStateException(Common.getMessage(
"NoElementFoundPath_msg", path));
}
} else {
throw new IllegalStateException(Common.getMessage(
"NoRootFoundForPath_msg", path));
}
}
void resolveGraph(String path) {
String pathRoot = null;
if (PathResolver.needResolving(path))
path = (new PathResolver(this.parent, path)).toString();
int idx = path.indexOf(':');
if (idx != -1) {
pathRoot = path.substring(idx+1);
path = path.substring(0, idx);
}
BaseBean[] beans = this.registry.getRoots(path);
if (beans.length > 0) {
this.root = beans[0];
if (pathRoot != null) {
DDCursor cur = new DDRegistryParser.DDCursor(this,
pathRoot);
this.root = cur.getRoot();
}
}
}
public String toString() {
String p, r;
if (this.parent != null)
p = this.parent.toString();
else
p = "-"; // NOI18N
if (this.root != null)
r = root.name();
else
r = "-"; // NOI18N
return "Parent:"+p+" Root:"+r; // NOI18N
}
public String dump() {
if (this.root != null)
return this.root.dumpBeanNode();
else
return "
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 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.