Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Sapphire » XML schema data types like xs:Name
XML schema data types like xs:Name [message #1062215] Thu, 06 June 2013 14:24 Go to next message
kon f is currently offline kon fFriend
Messages: 112
Registered: March 2012
Senior Member
Hey,

was wondering if sapphire supports certain schema types like xs:ID, xs:Name and xs:NCName. One element in my schema uses the xs:Name type. Currently, I can fill the text field for the element in the Design View with any string, also with 1myName and no error is shown. If I switch to the source view, the xml editor creates an error marker and that 1Name does not conform the xs:Name type (must not start with with a number).

Thank you.

Kon
Re: XML schema data types like xs:Name [message #1062279 is a reply to message #1062215] Thu, 06 June 2013 23:34 Go to previous messageGo to next message
Konstantin Komissarchik is currently offline Konstantin KomissarchikFriend
Messages: 950
Registered: July 2009
Senior Member
Sapphire does not validation per XML Schema, but you can certainly specify validation rules to cover what the schema requires and much more. A number of annotations such as @Required, @PossibleValues, @NumericRange, etc. result in validation. For maximum flexibility, you can implement a custom ValidationService and attach it to a property using @Service annotation. Examples in the samples project.

In Sapphire 0.7, there is also an @Validation annotation that allows custom validation rules to be specified using EL. For instance:

@Validation
(
    rule = "${ Scale( Discount, 2 ) <= Scale( Subtotal, 2 ) + Scale( Delivery, 2 ) }",
    message = "Discount must not exceed subtotal plus delivery charge."
)


There isn't a regex function in EL, but we can add one if that would be useful.
Re: XML schema data types like xs:Name [message #1062369 is a reply to message #1062279] Fri, 07 June 2013 12:35 Go to previous messageGo to next message
kon f is currently offline kon fFriend
Messages: 112
Registered: March 2012
Senior Member
Hey Konstantin,

thank you for the information. Since it is possible to use regex with a schema, it would be nice to have this feature. I also think that it would help save boilerplate code for checking common xml schema type like xs:ID, xs:Name and xs:NCName.

As suggested, I implemented a custom validation service that checks for schema type xs:Name.

public class NameValidationService extends ValidationService {
    @Override
    public Status validate() {
        final Value<?> value = context(IModelElement.class).read(context(ValueProperty.class));
        final String name = value.getText();
        if (XMLChar.isValidName(name)) {
            return Status.createOkStatus();
        }
        String message = String.format("%s is not a valid value for the type \"Name\".", name);
        return Status.createErrorStatus(message);
    }
}


While debugging some simple JAXB project, I found the com.sun.org.apache.xerces.internal.util.XMLChar type. The xs:ID type inherits from xs:NCName that can be checked with XMLChar.isValidNCName(...).

Thank you!

Kon

[Updated on: Fri, 07 June 2013 12:44]

Report message to a moderator

Re: XML schema data types like xs:Name [message #1062456 is a reply to message #1062369] Fri, 07 June 2013 20:21 Go to previous messageGo to next message
Konstantin Komissarchik is currently offline Konstantin KomissarchikFriend
Messages: 950
Registered: July 2009
Senior Member
I added a Matches function for the 0.7 release.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=410202
Re: XML schema data types like xs:Name [message #1065768 is a reply to message #1062456] Thu, 27 June 2013 12:43 Go to previous messageGo to next message
kon f is currently offline kon fFriend
Messages: 112
Registered: March 2012
Senior Member
I just noticed that xs:ID has to be unique for the entire document. I found the @NoDuplicates annotation in the examples. I extracted the following snippet from the Contact Example:

// *** Name ***
    
@Label( standard = "name" )
@Required
@NoDuplicates
@XmlBinding( path = "@name" )

ValueProperty PROP_NAME = new ValueProperty( TYPE, "Name" );

Value<String> getName();
void setName( String name );


This does not work out for my requirement since the xs:ID type is spread over several properties. Is there a straightforward solution for this? Or do I have to provide some custom validation service that caches all ID values and assures uniqueness? Thank you.

Kon
Re: XML schema data types like xs:Name [message #1065800 is a reply to message #1065768] Thu, 27 June 2013 14:12 Go to previous messageGo to next message
Konstantin Komissarchik is currently offline Konstantin KomissarchikFriend
Messages: 950
Registered: July 2009
Senior Member
There is no existing facility to do the type of validation that you are looking for, so you will need to write a custom validation service.
Re: XML schema data types like xs:Name [message #1066636 is a reply to message #1065800] Wed, 03 July 2013 14:07 Go to previous messageGo to next message
kon f is currently offline kon fFriend
Messages: 112
Registered: March 2012
Senior Member
Hey Konstantin,

I'm trying to implement some custom custom validation service but having difficulties to access all Value<T>s, storing the the id. I'm just able to get a collection of strings.

My model has following structure:

- ElementA [1-1]
  \- Id
  \- ElementB [0-*]
     \- Id
     \- ElementC [0-*]
        \- Id


Every Id is tagged with following annotations:

@Required
@DependsOn({ "/Id", "/ElementB/Id", "/ElementB/ElementC/Id" })
@Service(impl = IDValidationService.class)
ValueProperty PROP_ID = new ValueProperty(TYPE, "Id");
Value<String> getId();
void setId(String value);


I use absolute paths being able to compare the changed id against every other id that occurs in my file.

My validation method of my custom validation service:

@Override
public Status isValid(String name) {

    if (!isValidContent(name)) {
        return Status.createErrorStatus(getErrorMessage(name));
    }
    
    // here the actual interesting part
    Value<?> value = context(IModelElement.class).read(context(ValueProperty.class));
    List<DependenciesService> services = context(IModelElement.class).services(context(ModelProperty.class), DependenciesService.class);
    for (DependenciesService dependenciesService : services) {
        Set<ModelPath> dependencies = dependenciesService.dependencies();
        for (ModelPath path : dependencies) {
            SortedSet<String> read = ((IModelElement) context(IModelElement.class).root()).read(path);
            System.out.println(String.format("%s %s", path, read));

            // ... perform validation value against the collections content
        }
    }

    return Status.createOkStatus();
}


Unfortunately, the method call read(ModelPath) returns a list of strings. I would need the actual values being able to exclude value from the comparison. In addition, ids with the same string content are aggregated to one due to the SortedSet implementation.

Thank you.

Kon

Re: XML schema data types like xs:Name [message #1067612 is a reply to message #1066636] Tue, 09 July 2013 14:52 Go to previous messageGo to next message
kon f is currently offline kon fFriend
Messages: 112
Registered: March 2012
Senior Member
I've seen some a commit on this for 0.7. Does it work for 0.6?

Thank you!

Kon
Re: XML schema data types like xs:Name [message #1067864 is a reply to message #1067612] Thu, 11 July 2013 00:18 Go to previous messageGo to next message
Konstantin Komissarchik is currently offline Konstantin KomissarchikFriend
Messages: 950
Registered: July 2009
Senior Member
In 0.6.x, the read(ModelPath) API is very limited in scope as you found. In 0.7, the comparable API returns property instances rather than their content, but if you must continue using 0.6.x, you will need to write your own harvester to traverse the model.
Re: XML schema data types like xs:Name [message #1074216 is a reply to message #1067864] Fri, 26 July 2013 09:47 Go to previous message
kon f is currently offline kon fFriend
Messages: 112
Registered: March 2012
Senior Member
Hey,

I updated to 0.7 and could make the xs:ID type validation work. xs:ID extends xs:NCName and it's value is unique for the whole document. I implemented the following validation service:

import java.util.List;

import org.eclipse.sapphire.Element;
import org.eclipse.sapphire.Property;
import org.eclipse.sapphire.Value;
import org.eclipse.sapphire.ValueProperty;
import org.eclipse.sapphire.modeling.ModelPath;
import org.eclipse.sapphire.services.DependenciesService;

public class IDValidationService extends NCNameValidationService {

    @Override
    public boolean isValidContent(String name) {
        if (!org.apache.xerces.util.XMLChar.isValidNCName(name)) {
            return false;
        }

        Value<?> value = context(Element.class).property(context(ValueProperty.class));
        List<DependenciesService> services = value.services(DependenciesService.class);

        for (DependenciesService dependenciesService : services) {
            for (ModelPath path : dependenciesService.dependencies()) {
                for (Property property : value.root().properties(path)) {
                    if (!(property instanceof Value<?>)) {
                        continue;
                    }

                    Value<?> otherValue = (Value<?>) property;
                    if (otherValue.equals(value)) {
                        continue;
                    }
                    if (otherValue.text().equals(value.text())) {
                        return false;
                    }
                }
            }
        }

        return true;
    }
}


And here the annotation for the id property:

@DependsOn({ "/Id", "/a/Id", "/a/b/Id" }) 
@Service(impl = IDValidationService.class)
ValueProperty PROP_ID = new ValueProperty(TYPE, "Id");


You need to specify all xs:ID appearances in your model with a absolute path. If the property is modified, it will be compared against every other xs:ID in the model.

Kon
Previous Topic:Not transform property label to upper case
Next Topic:Customized properties displayed in ListProperty
Goto Forum:
  


Current Time: Sun Nov 23 02:30:14 GMT 2014

Powered by FUDForum. Page generated in 0.01887 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software