thredds.catalog.InvDatasetImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netcdf Show documentation
Show all versions of netcdf Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package thredds.catalog;
import java.util.*;
import java.net.URI;
import ucar.nc2.constants.FeatureType;
import ucar.nc2.units.TimeDuration;
import ucar.nc2.units.DateRange;
import ucar.nc2.units.DateType;
import ucar.unidata.util.Format;
import ucar.unidata.util.StringUtil;
/**
* Concrete implementation of a thredds Dataset, for reading and writing from XML.
*
* @author john caron
* @see InvDataset
*/
/*
Notes on inheritence implementation.
Version 1.0
"Local metadata" is the metadata contained in the dataset node itself.
Inheritable metadata must be placed in an InvMetadata object with inherit = true;
"Inherited metadata" is not local, but comes from an ancestor node.
"Public metadata" is all the dataset's metadata, the local and the inherited.
When finish() is called, the public metadata is constructed.
If metadata cannot be inherited, it can be safely stored in the InvDataset objec. Otherwise, it must be kept in
local or inheritable ThreddsMetadata.
*/
public class InvDatasetImpl extends InvDataset {
private String urlPath;
private String alias;
private double size = 0.0;
private List accessLocal = new ArrayList();
private List servicesLocal = new ArrayList();
protected ThreddsMetadata tm = new ThreddsMetadata(false); // all local metadata kept here. This may include
// inheritable InvMetadata
protected ThreddsMetadata tmi = new ThreddsMetadata(true); // local inheritable metadata (canonicalization)
protected ThreddsMetadata tmi6 = new ThreddsMetadata(true); // local catalog 0.6 inheritable metadata
protected org.jdom.Element ncmlElement;
// validation
protected StringBuilder log = new StringBuilder();
// filter
protected boolean mark = false;
// debug lsls -
private boolean debugInherit = false, debugInherit2 = false;
/**
* Constructor from Catalog XML info. You must call finish() before this object
* is ready to be used. We had to do it this way so that nested service elements could be added
* through addService(), before we define on the default service.
*
* @param parent : parent dataset
* @param name : display name of dataset
* @param dataType : DataType name (may be null)
* @param serviceName : default service (may be null)
* @param urlPath : URL = server.getURLbase() + urlPath
*/
public InvDatasetImpl(InvDatasetImpl parent, String name, FeatureType dataType, String serviceName, String urlPath) {
super(parent, name);
tm.setDataType(dataType);
tm.setServiceName(serviceName);
this.urlPath = urlPath;
}
/**
* Finish constructing after all elements have been added.
* This does the inheritence thing
* This can be called again if new elements are added.
*
* @return true if successful.
*/
public boolean finish() {
boolean ok = true;
java.util.Iterator iter;
if (debugInherit) System.out.println("Now finish " + getName() + " id= " + getID());
authorityName = null;
dataType = null;
dataFormatType = null;
defaultService = null;
gc = null;
tc = null;
docs = new ArrayList();
metadata = new ArrayList();
properties = new ArrayList();
creators = new ArrayList();
contributors = new ArrayList();
dates = new ArrayList();
keywords = new ArrayList();
projects = new ArrayList();
publishers = new ArrayList();
variables = new ArrayList();
canonicalize(); // canonicalize thredds metadata
transfer2PublicMetadata(tm, true); // add local metadata
transfer2PublicMetadata(tmi, true); // add local inherited metadata
transfer2PublicMetadata(tmi6, true); // add local inherited metadata (cat 6 only)
transferInheritable2PublicMetadata((InvDatasetImpl) getParent()); // add inheritable metadata from parents
// build the expanded access list
access = new ArrayList();
// add access element if urlPath is specified
if ((urlPath != null) && (getServiceDefault() != null)) {
InvAccessImpl a = new InvAccessImpl(this, urlPath, getServiceDefault());
a.setSize(size);
a.finish();
addExpandedAccess(a);
}
// add local access elements
iter = accessLocal.iterator();
while (iter.hasNext()) {
InvAccessImpl a = (InvAccessImpl) iter.next();
a.finish();
addExpandedAccess(a);
}
// recurse into child datasets.
if (!(this instanceof InvCatalogRef)) {
for (InvDataset invDataset : this.getDatasets()) {
InvDatasetImpl curDs = (InvDatasetImpl) invDataset;
ok &= curDs.finish();
}
}
return ok;
}
/**
* Look for InvMetadata elements in the parent that need to be added to the public metadata of this dataset.
* Recurse up through all ancestors.
*
* @param parent transfer from here
*/
private void transferInheritable2PublicMetadata(InvDatasetImpl parent) {
if (parent == null) return;
if (debugInherit) System.out.println(" inheritFromParent= " + parent.getID());
transfer2PublicMetadata(parent.getLocalMetadataInheritable(), true);
//transfer2PublicMetadata(parent.getCat6Metadata(), true);
/* look through local metadata, find inherited InvMetadata elements
ThreddsMetadata tmd = parent.getLocalMetadata();
Iterator iter = tmd.getMetadata().iterator();
while (iter.hasNext()) {
InvMetadata meta = (InvMetadata) iter.next();
if (meta.isInherited()) {
if (!meta.isThreddsMetadata()) {
metadata.add(meta);
} else {
if (debugInherit) System.out.println(" inheritMetadata Element " + tmd.isInherited() + " " + meta.isInherited());
meta.finish(); // make sure XLink is read in.
transfer2PublicMetadata(meta.getThreddsMetadata(), false);
}
}
} */
// recurse
transferInheritable2PublicMetadata((InvDatasetImpl) parent.getParent());
}
/**
* take all elements from tmd and add to the public metadata of this dataset.
* for InvMetadata elements, only add if inheritAll || InvMetadata.isInherited().
*
* @param tmd tahe metadata from here
* @param inheritAll true if all should be inherited, else only those which are specifically mareked
*/
private void transfer2PublicMetadata(ThreddsMetadata tmd, boolean inheritAll) {
if (tmd == null) return;
if (debugInherit) System.out.println(" transferMetadata " + tmd);
if (authorityName == null)
authorityName = tmd.getAuthority();
if (dataType == null || (dataType == FeatureType.ANY) || (dataType == FeatureType.NONE))
dataType = tmd.getDataType();
if (dataFormatType == null || dataFormatType == DataFormatType.NONE)
dataFormatType = tmd.getDataFormatType();
if (defaultService == null)
defaultService = findService(tmd.getServiceName());
if (gc == null) {
ThreddsMetadata.GeospatialCoverage tgc = tmd.getGeospatialCoverage();
if ((tgc != null) && !tgc.isEmpty())
gc = tgc;
}
if (tc == null) {
DateRange ttc = tmd.getTimeCoverage();
if (ttc != null) {
// System.out.println(" tc assigned = "+ttc);
tc = ttc;
}
}
if (tc == null)
tc = tmd.getTimeCoverage();
for (InvProperty item : tmd.getProperties()) {
if (!properties.contains(item)) { // dont add properties with same name
if (debugInherit) System.out.println(" add Property " + item + " to " + getID());
properties.add(item);
}
}
creators.addAll(tmd.getCreators());
contributors.addAll(tmd.getContributors());
dates.addAll(tmd.getDates());
docs.addAll(tmd.getDocumentation());
keywords.addAll(tmd.getKeywords());
projects.addAll(tmd.getProjects());
publishers.addAll(tmd.getPublishers());
variables.addAll(tmd.getVariables());
for (InvMetadata meta : tmd.getMetadata()) {
if (meta.isInherited() || inheritAll) {
if (!meta.isThreddsMetadata()) {
metadata.add(meta);
} else {
if (debugInherit) System.out.println(" add metadata Element " + tmd.isInherited() + " " + meta);
meta.finish(); // make sure XLink is read in.
transfer2PublicMetadata(meta.getThreddsMetadata(), inheritAll);
metadata.add(meta);
}
}
}
}
/**
* Transfer all inheritable metadata from fromDs to the local metadata of this dataset.
* Called by InvDatasetScan to transfer inheritable metaddata to the nested catalogRef
*
* @param fromDs transfer from here
*/
public void transferMetadata(InvDatasetImpl fromDs, boolean copyInheritedMetadataFromParents) {
if (debugInherit2) System.out.println(" transferMetadata= " + fromDs.getName());
if (this != fromDs)
getLocalMetadata().add(fromDs.getLocalMetadata(), false);
transferInheritableMetadata(fromDs, getLocalMetadataInheritable(), copyInheritedMetadataFromParents);
setResourceControl(fromDs.getRestrictAccess());
}
/**
* transfer inherited metadata, consolidating it into target
* @param fromDs transfer from here, plus its parents
* @param target transfer to here
*/
private void transferInheritableMetadata(InvDatasetImpl fromDs, ThreddsMetadata target,
boolean copyInheritedMetadataFromParents)
{
if (fromDs == null) return;
if (debugInherit2) System.out.println(" transferInheritedMetadata= " + fromDs.getName());
target.add(fromDs.getLocalMetadataInheritable(), true);
/* look through local metadata, find inherited InvMetadata elements
ThreddsMetadata tmd = fromDs.getLocalMetadata();
Iterator iter = tmd.getMetadata().iterator();
while (iter.hasNext()) {
InvMetadata meta = (InvMetadata) iter.next();
if (meta.isInherited()) {
if (!meta.isThreddsMetadata()) {
tmc.addMetadata( meta);
} else {
if (debugInherit2) System.out.println(" transferInheritedMetadata "+meta.hashCode()+" = "+meta);
meta.finish(); // LOOK ?? make sure XLink is read in.
tmc.add( meta.getThreddsMetadata(), true);
}
}
} */
// now do the same for the parents
if ( copyInheritedMetadataFromParents)
transferInheritableMetadata((InvDatasetImpl) fromDs.getParent(), target, true);
}
private void addExpandedAccess(InvAccessImpl a) {
InvService service = a.getService();
if (null == service) {
a.check(log, false); // illegal; get error message
return;
}
if (service.getServiceType() == ServiceType.COMPOUND) {
// if its a compound service, expand it
for (InvService nestedService : service.getServices()) {
InvAccessImpl nestedAccess = new InvAccessImpl(this, a.getUrlPath(), nestedService);
addExpandedAccess(nestedAccess); // i guess it could recurse
}
} else {
access.add(a);
}
}
/**
* Put metadata into canonical form.
* All non-inherited thredds metadata put into dataset.
* All inherited thredds metaddata put into single metadata element, pointed to by getLocalMetadataInherited.
* This is needed to do reliable editing.
*/
protected void canonicalize() {
// transfer all non-inherited thredds metadata to tm
Iterator iter = tm.metadata.iterator();
while (iter.hasNext()) {
InvMetadata m = (InvMetadata) iter.next();
if (m.isThreddsMetadata() && !m.isInherited() && !m.hasXlink()) {
ThreddsMetadata nested = m.getThreddsMetadata();
tm.add(nested, false);
iter.remove();
}
}
// transfer all inherited thredds metadata to tmi
iter = tm.metadata.iterator();
while (iter.hasNext()) {
InvMetadata m = (InvMetadata) iter.next();
if (m.isThreddsMetadata() && m.isInherited() && !m.hasXlink()) {
ThreddsMetadata nested = m.getThreddsMetadata();
tmi.add(nested, true);
iter.remove();
}
}
}
/**
* Construct an InvDatasetImpl which refers to a urlPath.
* This is used to create a standalone InvDatasetImpl, outside of an InvCatalog.
* An "anonymous" InvServerImpl is created and attached to the InvDataset.
*
* @param urlPath : construct URL from this path
* @param dataType : data type
* @param stype : ServiceType
*/
public InvDatasetImpl(String urlPath, FeatureType dataType, ServiceType stype) {
super(null, "local file");
tm.setDataType(dataType);
tm.setServiceName("anon");
this.urlPath = urlPath;
// create anonomous service
addService(new InvService(tm.getServiceName(), stype.toString(), "", "", null));
finish();
}
public InvDatasetImpl(InvDataset parent, String name) {
super(parent, name);
}
/**
* copy constructor
* @param from copy from here
*/
public InvDatasetImpl(InvDatasetImpl from) {
super(from.getParent(), from.getName());
// steal everything
this.tm = new ThreddsMetadata(from.getLocalMetadata());
this.tmi = new ThreddsMetadata(from.getLocalMetadataInheritable());
this.accessLocal = new ArrayList(from.getAccessLocal());
this.servicesLocal = new ArrayList(from.getServicesLocal());
this.harvest = from.harvest;
this.collectionType = from.collectionType;
}
////////////////////////////////////////////////////////
// get/set local properties
/**
* @return alias for this Dataset, if there is one
*/
public String getAlias() {
return alias;
}
/**
* Set alias for this Dataset
* @param alias ID of another Dataset
*/
public void setAlias(String alias) {
this.alias = alias;
hashCode = 0;
}
/**
* Set the containing catalog; use only for top level dataset.
* @param catalog the containing catalog for the top level dataset.
*/
public void setCatalog(InvCatalog catalog) {
this.catalog = catalog;
hashCode = 0;
}
/**
* Get real parent dataset, no proxies
*
* @return parent dataset. If top dataset, return null.
*/
public InvDataset getParentReal() {
return parent;
}
/**
* Get urlPath for this Dataset
* @return urlPath for this Dataset
*/
public String getUrlPath() {
return urlPath;
}
/**
* Set the urlPath for this InvDatasetImpl
* @param urlPath the urlPath for this InvDatasetImpl
*/
public void setUrlPath(String urlPath) {
this.urlPath = urlPath;
hashCode = 0;
}
/**
* Set authorityName for this Dataset
* @param authorityName for this Dataset
*/
public void setAuthority(String authorityName) {
tm.setAuthority(authorityName);
hashCode = 0;
}
////////////////////////////////////////////////////////
// setters for public properties (in InvDataset)
/**
* Set collectionType
* @param collectionType the collection type
*/
public void setCollectionType(CollectionType collectionType) {
this.collectionType = collectionType;
hashCode = 0;
}
/**
* Set harvest
* @param harvest true if this dataset should be harvested for Digital Libraries
*/
public void setHarvest(boolean harvest) {
this.harvest = harvest;
hashCode = 0;
}
/**
* Set the ID for this Dataset
* @param id unique ID
*/
public void setID(String id) {
this.id = id;
hashCode = 0;
}
/**
* Set name of this Dataset.
* @param name of the dataset
*/
public void setName(String name) {
this.name = name;
hashCode = 0;
}
/**
* Set the parent dataset.
* @param parent parent dataset
*/
public void setParent(InvDatasetImpl parent) {
this.parent = parent;
hashCode = 0;
}
////////////////////////////////////////////////////////
// setters for public properties - these go into the local metadata object
// these are not inherited, only InvMetadata objects are inheritable.
// LOOK these are probably wrong
public void setGeospatialCoverage(ThreddsMetadata.GeospatialCoverage gc) {
tm.setGeospatialCoverage(gc);
hashCode = 0;
}
public void setTimeCoverage(DateRange tc) {
tm.setTimeCoverage(tc);
hashCode = 0;
}
public void setDataFormatType(DataFormatType dataFormatType) {
tm.setDataFormatType(dataFormatType);
hashCode = 0;
}
public void setDataType(FeatureType dataType) {
tm.setDataType(dataType);
hashCode = 0;
}
public double getDataSize() {
return tm.getDataSize();
}
public void setDataSize(double dataSize) {
tm.setDataSize(dataSize);
hashCode = 0;
}
public DateType getLastModifiedDate() {
// Look for a last modified date.
for (DateType dateType : tm.getDates()) {
if ((dateType.getType() != null) && dateType.getType().equals("modified")) {
return dateType;
}
}
return null;
}
public void setLastModifiedDate(DateType lastModDate) {
if (lastModDate == null)
throw new IllegalArgumentException("Last modified date can't be null.");
if (lastModDate.getType() == null || !lastModDate.getType().equals("modified")) {
throw new IllegalArgumentException("Date type must be \"modified\" (was \"" + lastModDate.getType() + "\").");
}
// Check for existing last modified date and remove if one exists.
DateType curLastModDateType = this.getLastModifiedDate();
if (curLastModDateType != null) {
tm.getDates().remove(curLastModDateType);
}
// Set the last modified date with the given DateType.
tm.addDate(lastModDate);
hashCode = 0;
}
public void setLastModifiedDate(Date lastModDate) {
if (lastModDate == null)
throw new IllegalArgumentException("Last modified date can't be null.");
// Set the last modified date with the given Date.
DateType lastModDateType = new DateType(false, lastModDate);
lastModDateType.setType("modified");
setLastModifiedDate(lastModDateType);
}
public void setServiceName(String serviceName) {
tm.setServiceName(serviceName);
hashCode = 0;
}
// LOOK these are wrong
public void setContributors(List a) {
List dest = tm.getContributors();
for (ThreddsMetadata.Contributor item : a) {
if (!dest.contains(item))
dest.add(item);
}
hashCode = 0;
}
public void setKeywords(List a) {
List dest = tm.getKeywords();
for (ThreddsMetadata.Vocab item : a) {
if (!dest.contains(item))
dest.add(item);
}
hashCode = 0;
}
public void setProjects(List a) {
List dest = tm.getProjects();
for (ThreddsMetadata.Vocab item : a) {
if (!dest.contains(item))
dest.add(item);
}
hashCode = 0;
}
public void setPublishers(List a) {
List dest = tm.getPublishers();
for (ThreddsMetadata.Source item : a) {
if (!dest.contains(item))
dest.add(item);
}
hashCode = 0;
}
public void setResourceControl(String restrictAccess) {
this.restrictAccess = restrictAccess;
}
//////////////////////////////////////////////////////////////////////////////
// add/remove/get/find local elements
/**
* Add InvAccess element to this dataset.
* @param a add dthis
*/
public void addAccess(InvAccess a) {
accessLocal.add(a);
hashCode = 0;
}
/**
* Add a list of InvAccess elements to this dataset.
* @param a add all of these
*/
public void addAccess(List a) {
accessLocal.addAll(a);
hashCode = 0;
}
/**
* @return the local access (non-expanded) elements.
*/
public java.util.List getAccessLocal() {
return accessLocal;
}
/**
* @return the ncml element if it exists, else return null.
*/
public org.jdom.Element getNcmlElement() {
return ncmlElement;
}
public void setNcmlElement(org.jdom.Element ncmlElement) {
this.ncmlElement = ncmlElement;
}
/**
* Add a nested dataset.
* @param ds add this
*/
public void addDataset(InvDatasetImpl ds) {
if (ds == null) return;
ds.setParent(this);
datasets.add(ds);
hashCode = 0;
}
/**
* Add a nested dataset at the location indicated by index.
* @param index add at this position
* @param ds add this
*/
public void addDataset(int index, InvDatasetImpl ds) {
if (ds == null) return;
ds.setParent(this);
datasets.add(index, ds);
hashCode = 0;
}
/**
* Remove the given dataset element from this dataset if it is in the dataset.
*
* @param ds - the dataset element to be removed
* @return true if this dataset contained the given dataset element.
*/
public boolean removeDataset(InvDatasetImpl ds) {
if (this.datasets.remove(ds)) {
ds.setParent(null);
InvCatalogImpl cat = (InvCatalogImpl) getParentCatalog();
if (cat != null)
cat.removeDatasetByID(ds);
return (true);
}
return (false);
}
/**
* Replace the given dataset if it is a nesetd dataset.
*
* @param remove - the dataset element to be removed
* @param add - the dataset element to be added
* @return true on success
*/
public boolean replaceDataset(InvDatasetImpl remove, InvDatasetImpl add) {
for (int i = 0; i < datasets.size(); i++) {
InvDataset dataset = datasets.get(i);
if (dataset.equals(remove)) {
datasets.set(i, add);
InvCatalogImpl cat = (InvCatalogImpl) getParentCatalog();
if (cat != null) {
cat.removeDatasetByID(remove);
cat.addDatasetByID(add);
}
return true;
}
}
return false;
}
/**
* Add documentation element to this dataset.
* @param doc add this
*/
public void addDocumentation(InvDocumentation doc) {
tm.addDocumentation(doc);
hashCode = 0;
}
/**
* Add a property to this dataset
* @param p add this
*/
public void addProperty(InvProperty p) {
tm.addProperty(p);
hashCode = 0;
}
/**
* Add a service to this dataset.
* @param service add this
*
* @deprecated put services in catalog
*/
public void addService(InvService service) {
// System.out.println("--add dataset service= "+service.getName());
servicesLocal.add(service);
services.add(service);
// add nested servers
for (InvService nested : service.getServices()) {
services.add(nested);
// System.out.println("--add expanded service= "+nested.getName());
}
hashCode = 0;
}
/**
* Remove a service from this dataset.
*
* @deprecated put services in catalog
* @param service remove this
*/
public void removeService(InvService service) {
servicesLocal.remove(service);
services.remove(service);
// remove nested servers
for (InvService nested : service.getServices()) {
services.remove(nested);
}
}
/**
* Get services attached specifically to this dataset.
*
* @return List of type InvService. May be empty, but not null.
*/
public java.util.List getServicesLocal() {
return servicesLocal;
}
/**
* Set the list of services attached specifically to this dataset.
* Discard any previous servies.
*
* @param s list of services.
*/
public void setServicesLocal(java.util.List s) {
this.services = new ArrayList();
this.servicesLocal = new ArrayList();
for (InvService elem : s) {
addService(elem);
}
hashCode = 0;
}
/**
* Get the metadata stored in this dataset element.
* Inherited metadata only in an InvMetadata object.
* @return the metadata stored in this dataset element.
*/
public ThreddsMetadata getLocalMetadata() {
return tm;
}
public void setLocalMetadata(ThreddsMetadata tm) {
// look this is wrong.
// need to copy fields into it !!
// possible only the one that are different from default !!!
// like stored defaults !! ha ha !
this.tm = tm;
hashCode = 0;
}
/**
* local metadata that should be inherited by this dataset's children.
* @return local metadata that should be inherited by this dataset's children.
*/
public ThreddsMetadata getLocalMetadataInheritable() {
return tmi;
}
/*
* local metadata that should be inherited by this dataset's children.
*
public ThreddsMetadata getCat6Metadata() {
return tmi6;
} */
/**
* Remove the given InvMetadata from the set of metadata local to this dataset.
*
* @param metadata remove this
* @return true if an InvMetadata is removed, false otherwise.
*/
public boolean removeLocalMetadata(InvMetadata metadata) {
InvDatasetImpl parentDataset = ((InvDatasetImpl) metadata.getParentDataset());
List localMdata = parentDataset.getLocalMetadata().getMetadata();
if (localMdata.contains(metadata)) {
if (localMdata.remove(metadata)) {
hashCode = 0; // Need to recalculate the hash code.
return (true);
}
}
return (false);
}
public String getServiceName() {
if (defaultService != null)
return defaultService.getName();
return null;
}
/*
* get Documentation that are xlinks
*
public List getDocumentationLinks() {
ArrayList result = new ArrayList();
java.util.List docs = getDocumentation();
for (int i = 0; i < docs.size(); i++) {
InvDocumentation doc = (InvDocumentation) docs.get(i);
if (doc.hasXlink())
result.add(doc);
}
return result;
} */
/**
* Filtering
* @return true if this is "marked"
*/
protected boolean getMark() {
return mark;
}
protected void setMark(boolean mark) {
this.mark = mark;
}
/**
* Look up the User property having the given key
* @param key property key
* @return User property having the given key, or null
*/
public Object getUserProperty(Object key) {
if (userMap == null) return null;
return userMap.get(key);
}
public void setUserProperty(Object key, Object value) {
if (userMap == null) userMap = new HashMap