Package com.hp.gloze.www_w3_org_2001_XMLSchema

Source Code of com.hp.gloze.www_w3_org_2001_XMLSchema.attribute

/*
*  (c) Copyright Hewlett-Packard Company 2001 - 2009
*  All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
*    derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
*  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**
  * @author steven.a.battle@googlemail.com
  */

package com.hp.gloze.www_w3_org_2001_XMLSchema;

import java.beans.IntrospectionException;
import java.net.URI;
import java.util.HashSet;
import java.util.Set;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.hp.gloze.Content;
import com.hp.gloze.Context;
import com.hp.gloze.Gloze;
import com.hp.gloze.Restrictions;
import com.hp.gloze.XMLBean;
import com.hp.gloze.www_eclipse_org_emf_2002_Ecore.Ecore;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.impl.UnionClassImpl;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFList;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.XSD;

/*! \page attribute attribute
  Attributes map to RDF properties. An instance of an attribute maps to an RDF statement.
   A qualified attribute is defined in the target namespace of the schema. The target namespace is the
   namespace of the corresponding RDF property.
  
   e.g. The following schema declares a global and therefore qualified attribute 'foo'  defined in the
   target namespace.
  
   \include attribute1.xsd
  
   By default, we take the closure over global attributes, assuming that \em all uses of the property conform to
   this global declaration. This means that 'foo' globally ranges over rdfs:Literal (the datatype corresponding to xs:anySimpleType).
   If this assumption is false, attribute closure may be disabled (closed=false), and global ranges are not asserted.
  
   \include attribute1.owl
  
   Like elements, if the target namespace ends with an alpha-numeric a fragment separator '#' is introduced.
  
   Unqualified attributes are not defined in the target namespace. Unqualified attributes occur if no target namespace
   is defined, or where the attribute is defined locally and its form is unqualified.
   The example below defines the attribute 'foo' locally within an attributeGroup; it's form is unqualified by default.
  
   \include attribute2.xsd
  
   All we can say about the attribute is that it is a property, for the same name may be re-used where
   its range is a different datatype or even an object type. Closure doesn't apply to local attributes.
  
   The following OWL was produced with lang=N3. The unqualified attribute is defined in the user-supplied default namespace,
   with xmlns=http://example.org/def/ .
  
   \include attribute2.owl
  
   In xml schema, attributes have their own symbol space, distinct from other components such as elements and types.
   If there are overlaps between these symbol spaces, it is advisable to introduce a symbolic prefix to keep them distinct.
  
   e.g. the attribute named 'foo' and type named 'foo' in the target namespace http://example.org/ will clash.
   Introducing a symbolic prefix '@' (at the command line) for attributes resolves the clash giving us an RDF property name
   http://example.org/@foo.
  
   The OWL mapping below was generated from the first schema above, but with attribute=@
  
   \include attribute3.owl

  \section attributeChildren Child components
 
  - \ref simpleType
  - \ref annotation
    \page attributeAnySimpleType Example: xs:anySimpleType
 
   This example shows how an untyped attribute 'bar' has a default type of xs:anySimpleType. All simple types are
   derived from this, so it occupies a similar place to rdfs:Literal.

  \include attributeAnySimpleType.xsd
 
  An XMl instance of this schema is as follows:
  
   \include attributeAnySimpleType.xml
       
  The value 'foobar' is mapped to a literal of type rdfs:Literal.
 
  \include attributeAnySimpleType.n3
 
  \page attributeNotation Example: xs:NOTATION
 
  This example demonstrates the use of notations. These are essentially QNames which must be expanded to give them global scope.
  The only restriction is that any notation should be predefined in the schema. The example includes a base64Binary embedded image
  which is notated as belonging to a particular predefined mime type.
 
    \include attributeNOTATION.xml
   
    The xml schema defines the mime options is as follows.
  The only mime type options available are 'jpeg', 'gif' and 'png'.

    \include attributeNOTATION.xsd
   
    In the resulting RDF mapping, the xs:NOTATION datatype does not appear, but the expanded QName names the global mime type resource.
  
    \include attributeNOTATION.n3
   
    \section attributeChildren Child components

  - \ref annotation
  - \ref simpleType

- \ref simpleContent
*/

public class attribute extends Content {

  private String _default, fixed, form, name, ref, type, use="optional";
  private simpleType simpleType;
  private String uri;
  private annotation annotation;
 
  // ecore attributes
  private Ecore ecore;
 
  public attribute() throws IntrospectionException {
  }
 
  public attribute(String uri) throws IntrospectionException {
    this.uri = uri;
  }
 
  /** create a URI for a reference to a global attribute **/

  public static String createURI(Attr attr, String tns, Context ctx) {
    if (attr.getNamespaceURI()!=null)
      return concatName(attr.getNamespaceURI(), ctx.getAttributeSymbol(), attr.getLocalName());
    else if (tns!=null)
      return concatName(tns,ctx.getAttributeSymbol(), attr.getNodeName());
    else
      return concatName(ctx.getDefaultNS(), ctx.getAttributeSymbol(),attr.getNodeName());
  }
 
  String createURI(Model model, Context ctx) {
    if (uri != null) return uri;
    schema xs = (schema) this.get_owner();
   
    if (isQualified() && getName()!=null)
      uri = xs.qualifiedName(getName(),ctx.getAttributeSymbol(),model);
   
    // unqualified definitions
    else if (getRef()==null)
      uri = xs.unqualifiedName(getName(),ctx.getAttributeSymbol(),model,ctx);

    // QName references use the xmlns (also see xmlns parameter) as the default
    else uri = expandQName(ctx.getDefaultNS(),ctx.getAttributeSymbol(),getRef(),get_node(),model);
   
    return uri;
  }

  public void resolve(Model model, Context ctx) {
    ctx.putType(this,get_type(ctx));
    super.resolve(model,ctx);
  }
 
  public void reportLocalAttributes(Model model,Set<String> report, Context ctx) {
    if (name!=null && !(get_parent() instanceof schema)) {
      String t = expandQName(ctx.getDefaultNS(),getType(),ctx.getModel());
      if (t!=null && t.equals(schema.XSD_URI+"#ID")) return;
      report.add(createURI(model,ctx));
    }
  }

  private XMLBean get_type(Context ctx) {
    if (simpleType != null) return simpleType;
    XMLBean b = ctx.getType(this);
    if (b!=null) return b;
    if (type!=null) {
      String uri = expandQName(ctx.getDefaultNS(),type,ctx.getModel());
      if (!uri.startsWith(schema.XSD_URI)) {
        b = ctx.getComplexType(uri);
        if (b==null) b = ctx.getSimpleType(uri);
        if (b!=null) ctx.putType(this,b);
        else Gloze.logger.warn("no such type: "+type);
      }
    }
    return b;
  }
 
  /*! \page attributeID Attribute Identity
  
   The following example demonstrates the use of xs:ID, xs:IDREF, and xs:IDREFS.
   The element 'foobar' includes an 'id' attribute that identifies it.
   The bar element references it via its 'href' or 'hrefs' attributes,
   of type xs:IDREF or xs:IDREFS, respectively.
  
   \include attributeID.xml
   \include attributeID.xsd
  
   Observe that no resources of types xs:ID, xs:IDREF, or xs:IDREFS appear in the mapped RDF.
   These are all translated into resource URIs, and in the case of xs:IDREFS to an RDF:List of URIs.
  
   \include attributeID.n3
  
   */
 
  /*! \page lang xml:lang
   The appearance of an xml:lang attribute states that the element content is
   expressed in the given language. The same lang value can be set on an RDF literal
   but not an RDF datatype. Language settings take precedence over datatyping.
  
   \include attributeLang.xml
  
   This conforms to the following schema. Note that xml:lang is defined in a standard schema
   obtainable from http://www.w3.org/XML/1998/namespace. The attribute group 'specialAttrs' includes
   xml:base, xml:lang and xml:space.
  
   \include attributeLang.xsd
  
   The resulting RDF below includes the literal 'language' in the english language.
  
   \include attributeLang.n3
  
   */
       
  public void toRDF(Resource subject, Attr attribute, Context ctx)
    throws Exception {
    Model model = ctx.getModel();
    schema xs = (schema) this.get_owner();
    if (attribute==null && getFixed()==null) return;
   
    String value = attribute!=null?attribute.getValue():getFixed();
    if (value.equals("") && _default!=null) value = _default;
    Property prop = model.createProperty(createURI(model,ctx));
   
    // avoid adding xml namespace attributes
    if (attribute!=null &&
        attribute.getNamespaceURI()!=null &&
        attribute.getNamespaceURI().equals(XML)) return;
   
    // the attribute may have been added already in a restriction
    if (subject.hasProperty(prop)) return;

    // the attribute may be defined locally or globally by ref
    attribute def = getDefinition(model,ctx);
    if (def==null) return; // may be eg. xml:lang
   
    String t = expandQName(ctx.getDefaultNS(),def.getType(),ctx.getModel());
    if (t==null && simpleType==null) t = schema.XSD_URI+"#anySimpleType";
    if (t!=null && t.startsWith(schema.XSD_URI)) {
      // ID is used to name the owning element - don't generate RDF property
      if (t.endsWith("#ID")) return;
      // IDREF to globally named element
      else if (t.endsWith("#IDREF")) {
        Resource rez = model.createResource(addFragment(ctx.getBaseMap(), value).toString());
        subject.addProperty(prop, rez);
      }
      // IDREFS to global entities
      else if (t.endsWith("#IDREFS"))
        subject.addProperty(prop, schema.toRDFList(attribute,value,XSD.IDREF.getURI(),null,ctx));
      else {
        value = schema.processWhitespace(attribute,value,t,ctx);
        xs.toRDF(attribute, subject, prop, value, t, null, null, ctx);
      }
      return;
    }
    else {
      XMLBean type = def.get_type(ctx);
      // simple type?
      if (type instanceof simpleType)
        ((simpleType) type).toRDF(subject, prop, attribute, value, null, null, ctx);
      // else add plain literal
      else subject.addProperty(prop, model.createLiteral(schema.processWhitespace(attribute,value,null,ctx)));
    }
  }
 
  /* preliminaries before matching on property name */

  public void toXML(Element e, Resource subject, Set<Statement> pending, Context ctx) {
    String uri = createURI(ctx.getModel(),ctx);
    try {
      // the attribute may be defined locally or globally by ref
      attribute def = getDefinition(ctx.getModel(),ctx);
     
      if (!ctx.isFixed() && getFixed()!=null) return;
     
      String type = def!=null?expandQName(ctx.getDefaultNS(),def.getType(),ctx.getModel()):null;
     
      if (type==null && simpleType==null) type = schema.XSD_URI+"#anySimpleType";
     
      if (ref!=null && ref.equals("xml:lang")) {
        String l = subject.getProperty(RDF.value).getLiteral().getLanguage();
        if (l!=null && !l.equals("")) e.setAttribute("xml:lang", l);       
      }
      if (ref!=null && ref.equals("xml:id")) {
        if (!subject.isAnon())
          e.setAttribute("xml:id", subject.getLocalName());       
      }
      else if (type!=null && type.startsWith(schema.XSD_URI)) {
        if (type.endsWith("#ID")) {
          if (!subject.isAnon() && !getUse().equals("prohibited")) {
            // derive attribute from resource URI
            e.setAttribute(def.getName(), new URI(subject.getURI()).getFragment());
          }
          else if (getUse().equals("required"))
            Gloze.logger.warn("missing required ID "+getName());
          return;
        }
      }
 
      // look for attributes that correspond to RDF properties
      Set<Statement> done = new HashSet<Statement>();
      for (Statement stmt: pending) {
        Property p = stmt.getPredicate();
        if (uri.equals(p.getURI())) { // && !done.contains(s)) {
          toXML(e, ctx, def, type, stmt.getObject());
          done.add(stmt);
        }
      }
      pending.removeAll(done);
    } catch (Exception x) {}
  }
 
  public void toXML(Element elem, RDFNode object, Context ctx) {
    try {
      attribute def = getDefinition(ctx.getModel(),ctx);
      String type = def!=null?expandQName(ctx.getDefaultNS(),def.getType(),ctx.getModel()):null;
      toXML(elem, ctx, def, type, object)
    } catch (Exception e) {
    }
  }

  private void toXML(Element e, Context ctx, attribute def, String type, RDFNode object)
    throws Exception {
      Document doc = e.getOwnerDocument();
      schema xs = (schema) this.get_owner();
      Attr a;
      if (isQualified()) {
        String ns = xs.getTargetNamespace();
        a = doc.createAttributeNS(ns, def.getName());
        //if (Character.isLetterOrDigit(ns.charAt(ns.length()-1))) ns += "#";
        a.setPrefix(ctx.getModel().getNsURIPrefix(ns));
        e.setAttributeNodeNS(a);
      }
      else e.setAttributeNode(a = doc.createAttribute(def.getName()));

      XMLBean t = get_type(ctx);
      if (t instanceof simpleType) ((simpleType) t).toXML(a,object,ctx);
      else if (type != null && type.endsWith("IDREFS"))
        xs.listToXML(a,(RDFList) object.as(RDFList.class),XSD.IDREF.getURI(),ctx);
      else a.setValue(xs.toXMLValue(e,object,type,ctx));
    }

  /** check validity of simple content */
 
  public boolean isValid(Resource resource, Context ctx) {
    Model model = ctx.getModel();
    Property prop = model.createProperty(createURI(model,ctx));
    Statement stmt = resource.getProperty(prop);
    String value = stmt!=null?stmt.getString():null;
    attribute def = getDefinition(model,ctx);
    XMLBean t = def.get_type(ctx);
    if (t instanceof simpleType) return ((simpleType)t).isValid(value, ctx);
    return true;
  }

  public String getID(Attr a, Context ctx) {
    if (a==null) return null;
    // the attribute may be defined locally or globally by ref
    attribute def = getDefinition(ctx.getModel(),ctx);
    String t = expandQName(ctx.getDefaultNS(),def.getType(),ctx.getModel());
    // schema ID?
    if (t != null && t.startsWith(schema.XSD_URI) && t.endsWith("ID"))
      return a.getValue();
    return null;
  }

  /** return the attribute definition **/

  attribute getDefinition(Model model, Context ctx) {
    // The attribute may refer to its definition
    if (ref != null) return ctx.getAttribute(createURI(model,ctx));
    else return this;
  }
 
  public void toOWL(Restrictions rest, Context ctx) {
   
    // Restrictions are only used in the context of class definitions.
    // They need to be cleaned up, for example, when creating global attribute definitions
    boolean noRest = rest==null;
   
    schema xs = (schema) this.get_owner();
    String uri = createURI(xs.ont,ctx);   
    attribute def = getDefinition(xs.ont,ctx);
    if (def==null) return;
    if (rest==null) rest = new Restrictions();
    String type = expandQName(ctx.getDefaultNS(),def.getType(),xs.ont);
   
    // add cardinality restrictions
    // simple types (including QNames, IDREFs) have minCard of at most 1 because of possible duplication */
    boolean simple = type==null || (type.startsWith(schema.XSD_URI) && !type.endsWith("#anyType")) ;
    if (type==null || !type.equals(schema.ID)) {
      rest.addMin(uri, use.equals("required")?1:0,simple,def.getModel());
      rest.addMax(uri, use.equals("prohibited")?0:1,def.getModel());
    }
   
    // include no more than cardinality restrictions for referenced attributes
    if (!this.equals(def)) return;

    OntProperty property = xs.ont.createOntProperty(uri);

    Resource range = null;
    simpleType s = def.simpleType;
    if (s==null) s = ctx.getSimpleType(type);
    if (s!=null) {
      s.defineType(property,ctx);
      range = s.toOWL(ctx);
    }
    else {
      // default attribute type
      if (type==null) type = schema.anySimpleType;
      schema.defineType(property,type);
      range = schema.toOWL(xs.ont,type);
     
      // ecore extensions
      if (ecore!=null) ecore.toOWL(getModel(), uri, rest, get_node(), type, ctx);
    }
   
    // remove all evidence of an ID attribute
    if (range!=null && schema.isID(range)) property.remove();
   
    // Don't bother to add a range restriction only for it to be cleaned up afterwards (noRest)
    if (range!=null && rest!=null && !noRest && !schema.isID(range))
      rest.addRange(uri, range);
   
    // global attribute closure
    if (property.getRange()==null && ctx.isGlobalAttribute(def)
        && ctx.isClosed() && range!=null && !schema.ID.equals(range.getURI())) {
      property.setRange(range);
    }
   
    if (noRest) rest.cleanup(xs.ont,uri);
   
    // add comments
    if (annotation!=null) annotation.toOWL(property,ctx)
  }
   
  private OntModel getModel() {
    return ((schema) this.get_owner()).ont;
  }

  /**
   * Returns the name.
   * @return String
   */
  public String getName() {
    return name;
  }

  /**
   * Returns the type.
   * @return String
   */
  public String getType() {
    return type;
  }

  /**
   * Sets the name.
   * @param name The name to set
   */
  public void setName(String name) {
    this.name = name;
  }

  /**
   * Sets the type.
   * @param type The type to set
   */
  public void setType(String type) {
    this.type = type;
  }

  /**
   * Returns fixed.
   * @return String
   */
  public String getFixed() {
    return fixed;
  }

  /**
   * Sets fixed.
   * @param fixed The fixed to set
   */
  public void setFixed(String fixed) {
    this.fixed = fixed;
  }

  /**
   * Returns use.
   * @return String
   */
  public String getUse() {
    return use;
  }

  /**
   * Sets use.
   * @param use The use to set
   */
  public void setUse(String use) {
    this.use = use;
  }

  /**
   * @return global defininition for this attribute
   */
  public String getRef() {
    return ref;
  }

  /**
   * set ref to global definition for this attribute
   * @param string
   */
  public void setRef(String string) {
    ref = string;
  }

  /**
   * @return inline simple type definition
   */
  public simpleType getSimpleType() {
    return simpleType;
  }

  public void setSimpleType(simpleType type) {
    simpleType = type;
  }

  public String get_default() {
    return _default;
  }

  public void set_default(String string) {
    _default = string;
  }

  public String getForm() {
    return form;
  }
 
  public boolean isQualified() {
    schema xs = (schema) get_owner();
    // if no TNS is defined, all attributes are unqualified
    if (xs.getTargetNamespace()==null) return false;
    // explicitly qualified attribute
    if (form!=null && form.equals("qualified")) return true;
    // global attributes (or references to them) are qualified
    else if (get_parent() instanceof schema || ref!=null) return true;
    else return xs.getAttributeFormDefault().equals("qualified");
  }

  public void setForm(String string) {
    form = string;
  }

  public String getRefName() {
    String n = getName();
    if (n!=null) return n;
    else return getRef();
  }

  public annotation getAnnotation() {
    return annotation;
  }

  public void setAnnotation(annotation annotation) {
    this.annotation = annotation;
  }

  /* ecore attributes */

  public String getReference() {
    if (ecore==null) return null;
    return ecore.getReference();
  }

  public void setReference(String reference) {
    if (ecore==null) ecore = new Ecore();
    ecore.setReference(reference);
  }

}
TOP

Related Classes of com.hp.gloze.www_w3_org_2001_XMLSchema.attribute

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.