/*
* PropertySig.java --
*
* This class implements the internal representation of a Java
* property signature.
*
* Copyright (c) 1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and
* redistribution of this file, and for a DISCLAIMER OF ALL
* WARRANTIES.
*
* RCS: @(#) $Id: PropertySig.java,v 1.4 2000/10/29 06:00:42 mdejong Exp $
*
*/
package tcl.lang;
import tcl.lang.reflect.*;
import java.lang.reflect.*;
import java.beans.*;
/**
* This class implements the internal representation of a Java Property
* signature.
*/
class PropertySig implements InternalRep {
// The class that the property signature is used against. It is the
// class of the java object specified in the java::prop command.
// targetCls is used to test the validity of a cached PropertySig
// internal rep.
Class targetCls;
// Property descriptor of the property.
PropertyDescriptor desc;
// The PkgInvoker used to access the property.
PkgInvoker pkgInvoker;
/*
*----------------------------------------------------------------------
*
* PropertySig --
*
* Creates a new PropertySig instance.
*
* Side effects:
* Member fields are initialized.
*
*----------------------------------------------------------------------
*/
PropertySig(
Class c, // Initial value for targetCls.
PkgInvoker i, // Initial value for pkgInvoker.
PropertyDescriptor d) // Initial value for desc.
{
targetCls = c;
pkgInvoker = i;
desc = d;
}
/*
*----------------------------------------------------------------------
*
* duplicate --
*
* Make a copy of an object's internal representation.
*
* Results:
* Returns a newly allocated instance of the appropriate type.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
public InternalRep duplicate()
{
return new PropertySig(targetCls, pkgInvoker, desc);
}
/**
* Implement this no-op for the InternalRep interface.
*/
public void dispose() {}
/*
*----------------------------------------------------------------------
*
* get --
*
* Returns the FieldSig internal rep given by the field signature.
*
* Results:
* The FieldSig given by the signature.
*
* Side effects:
* When successful, the internalRep of the signature object is
* converted to FieldSig.
*
*----------------------------------------------------------------------
*/
static PropertySig
get(
Interp interp, // Current interpreter
Class targetCls, // The target class of the property signature.
TclObject signature) // The TclObject that holds a prop. signature.
throws
TclException // Standard Tcl exception.
{
InternalRep rep = signature.getInternalRep();
if ((rep instanceof PropertySig) &&
(targetCls == ((PropertySig) rep).targetCls)) {
// The cached internal rep is a valid property signature for
// the given targetCls. Return it.
return (PropertySig) rep;
}
String propName = signature.toString();
PropertyDescriptor desc = null;
search_prop : {
BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo(targetCls);
} catch (IntrospectionException e) {
break search_prop;
}
PropertyDescriptor descriptors[] = beanInfo.getPropertyDescriptors();
if (descriptors == null) {
break search_prop;
}
// Search for a property that has the same name as propName.
for (int i = 0; i < descriptors.length; i++) {
// FIXME : null tests are just for debugging
if (descriptors[i] == null) {
throw new NullPointerException("descriptor is null");
}
if (descriptors[i].getName() == null) {
throw new NullPointerException("descriptor.getName() is null");
}
if (propName == null) {
throw new NullPointerException("propName is null");
}
if (descriptors[i].getName().equals(propName)) {
if (descriptors[i] instanceof IndexedPropertyDescriptor) {
throw new TclException(interp,
"can't access indexed property \"" +
propName + "\": not implemented");
}
desc = descriptors[i];
break;
}
}
}
if (desc == null) {
throw new TclException(interp, "unknown property \"" + propName +
"\"");
}
PropertySig sig = new PropertySig(targetCls,
PkgInvoker.getPkgInvoker(targetCls), desc);
signature.setInternalRep(sig);
return sig;
}
} // end PropertySig