001: /*
002: * @(#)CompositePackage.java 1.2 04/12/06
003: *
004: * Copyright (c) 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.ext;
010:
011: import java.util.Hashtable;
012:
013: import pnuts.lang.Context;
014: import pnuts.lang.NamedValue;
015: import pnuts.lang.Package;
016:
017: /**
018: * Composed hierarchical names space based on a Package.
019: *
020: * A read access first looks for the symbol in the local symbol table, if not
021: * found, then looks for the base package.
022: *
023: * A write access never affect the base package.
024: */
025: public class CompositePackage extends Package {
026:
027: private Package pkg;
028:
029: public CompositePackage() {
030: this (Package.getGlobalPackage());
031: }
032:
033: /**
034: * Constructor
035: *
036: * @param base
037: * the base package
038: */
039: public CompositePackage(Package base) {
040: this .pkg = base;
041: Package p = base;
042: if (p.getParent() == null) {
043: this .root = this ;
044: this .parent = null;
045: this .packages = new Hashtable();
046: } else {
047: this .parent = new CompositePackage(p.getParent());
048: while (p.getParent() != null) {
049: p = getParent();
050: }
051: this .root = new CompositePackage(p);
052: }
053: }
054:
055: /**
056: * Creates a sub-package
057: *
058: * @param name
059: * the name of the sub-package
060: */
061: public Package newInstance(String name) {
062: return new CompositePackage(pkg.newInstance(name));
063: }
064:
065: /**
066: * Gets the base package
067: */
068: public Package getBasePackage() {
069: return pkg;
070: }
071:
072: /**
073: * First looks for the symbol in the local symbol table. If not found looks
074: * for the symbol in the base package.
075: *
076: * @param symbol
077: * the symbol to look for
078: * @param context
079: * the context
080: * @return the pnuts.lang.NamedValue object that holds the value of the
081: * symbol if it exists. null, otherwise.
082: */
083: public NamedValue lookup(String symbol, Context context) {
084: NamedValue v = super .lookup(symbol, context);
085: if (v != null) {
086: return v;
087: }
088: return pkg.lookup(symbol, context);
089: }
090:
091: /**
092: * Looks for a name-value binding in the symbol table chain.
093: *
094: * @param symbol the name of the variable, which must be intern'd
095: * @return the value
096: */
097: public NamedValue lookup(String symbol) {
098: NamedValue v = super.lookup(symbol);
099: if (v != null) {
100: return v;
101: }
102: return pkg.lookup(symbol);
103: }
104: }
|