Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 334642

Summary: [metatype] Parsing of metafile without default value fails
Product: [Eclipse Project] Equinox Reporter: janssk1
Component: CompendiumAssignee: John Ross <jwross>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: jgawor, jwross, tjwatson
Version: unspecified   
Target Milestone: 3.7 M7   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Bug Depends on:    
Bug Blocks: 337247    
Attachments:
Description Flags
Proposed Patch
tjwatson: iplog+
Reviewed patch none

Description janssk1 CLA 2011-01-18 08:51:14 EST
Build Identifier: 1.0.0.v20070827, but also on trunk 

For some reason, equinox decides that attribute with cardinality 0 *must* have metadata, although the schema files says it's optional. 
I don't find such a requirement in the osgi spec. 

The javadoc of AttributeDefinition.getDefaultValue says it should return a list of size one if cardinality is 0, but that does not imply that a default value must be provided in the xml representation, right ? IMHO, If no value is provided in xml, IgetDefaultValue should return an array containing a single null element. 

The code doing the (unwanted) check is in DataParser.java:

{code}
  // Not a problem, because DEFAULT is an optional attribute.
519	                                if (ad_cardinality_val == 0) {
520	                                        // But when it is not assigned, CARDINALITY cannot be '0'.
521	                                        _isParsedDataValid = false;
522	                                        logger.log(LogService.LOG_ERROR, "DataParser.init(String, Attributes, Vector) " + MetaTypeMsg.NULL_DEFAULTS); //$NON-NLS-1$
523	
524	                                        return;
525	                                }
{code}

Reproducible: Always

Steps to Reproduce:
1.Create a meta xml file with an attribute having cardinality 0 and no default value
Comment 1 John Ross CLA 2011-01-18 12:29:12 EST
This will require some investigation in order to provide a justification (if any) for the behavior.

In the meantime, if your primary issue is wanting to declare a required attribute holding only a single value without a specified default, using required=true (default) and cardinality=1 should work.
Comment 2 John Ross CLA 2011-01-18 14:30:24 EST
A cardinality of zero has special meaning. It says that an attribute must have one, and only one, value. Not to enforce this by requiring a specified default would seem to render it practically indistinguishable from a cardinality of one, which says an attribute may have zero or one values.

There is another ambiguity here, however. The spec allows getDefaultValue() to return null "if no default exists". What's the difference between returning an array of size 0 and a null array when cardinality != 0? Why not always do one or the other? Are we differentiating between an omitted default attribute and one with an empty string value?
Comment 3 janssk1 CLA 2011-01-18 15:01:50 EST
Cardinality 0 means indeed that the attribute has only one value, but that value can be null as well. It's easy to distinguish from cardinality 1, since cardinality 1 means the attribute is an array of maximally one element (so either an empty array or a single element array). 

After reading the getDefaultValue javadoc another time, it seems indeed better to return just 'null' in case no default value is specified for a cardinality 0 (for other cardinalities as well). If a default value is specified for a cardinality 0, it should be represented as a single value array. 


Anyway, my conclusion is the same: The dataparser should not force a default value.
Comment 4 John Ross CLA 2011-01-19 13:47:30 EST
I think the intent of the API was to ensure that getDefaultValue() would not return a value incompatible with validate(). Returning null is a special case indicating no default exists and does not apply.
 
Returning an array of size one containing a null value in the case of cardinality=0 would be incompatible with the spec.

I don't see a difference between returning null or an array of size zero when cardinality != 0. I presume implementations are free to do either.

I don't see that the conditional requirement imposed by the implementation between the cardinality (when zero) and default attributes is necessary or required by the spec.
Comment 5 John Ross CLA 2011-01-19 15:20:35 EST
I've requested a clarification in https://www.osgi.org/members/bugzilla/show_bug.cgi?id=1861.
Comment 6 John Ross CLA 2011-03-14 18:16:23 EDT
Created attachment 191174 [details]
Proposed Patch

This patch removes the conditional requirement imposed by the XML parser that a default value must be specified if cardinality is zero. This restriction is not required by the specification and would seem to place an unnecessary burden on users, particularly in light of the new PASSWORD attribute definition type. This type is tailor made for a zero cardinality (one and only one) but is unlikely to have an associated static default value.

The patch also includes a new compendium test which, incidentally, flushed out an additional bug where escape characters within a default value were not stripped out if only one value existed. That fix is also included.
Comment 7 Thomas Watson CLA 2011-03-15 08:28:37 EDT
Created attachment 191207 [details]
Reviewed patch

Patch looks good.  I removed the now unused nls message NULL_DEFAULTS.  I also integrated the new metatype tests into org.eclipse.equinox.metatype.tests.AllTests so they can be run when running the other tests automatically.
Comment 8 Thomas Watson CLA 2011-03-15 08:30:05 EDT
patch released.