/* * Copyright 2011 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.semantics.builder.model; import com.hp.hpl.jena.sparql.function.library.min; import org.drools.definition.type.Position; import org.drools.semantics.utils.NameUtils; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class PropertyRelation extends Relation implements Cloneable { @Position(3) protected String name; private Integer minCard = 0; private Integer maxCard = null; private Concept target = null; private Concept domain = null; private Concept addableTarget = null; private boolean restricted = false; private boolean inherited = false; private boolean simple = false; private PropertyRelation baseProperty; private List<PropertyRelation> restrictedProperties = new ArrayList<PropertyRelation>(); private Set<List<PropertyRelation>> chains = new HashSet<List<PropertyRelation>>(); private boolean inverse = false; public PropertyRelation( String subject, String property, String object, String name ) { this.subject = subject; this.property = property; this.object = object; this.name = name; baseProperty = this; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getMinCard() { int x = minCard; for ( List<PropertyRelation> chain : chains ) { int m = 1; for ( PropertyRelation rel : chain ) { m = m * rel.getMinCard(); } x = Math.max( x, m ); } return x; } public void setMinCard(Integer minCard) { this.minCard = minCard; } public Integer getMaxCard() { Integer x = maxCard; for ( List<PropertyRelation> chain : chains ) { Integer m = 1; for ( PropertyRelation rel : chain ) { if ( rel.getMaxCard() == null ) { m = null; break; } m = m * rel.getMaxCard(); } if ( m != null ) { x = (x == null) ? m : Math.min( x, m ); } } return x; } public void setMaxCard(Integer maxCard) { this.maxCard = maxCard; } public Concept getTarget() { return target; } public void setTarget(Concept target) { this.target = target; } public Concept getDomain() { return domain; } public void setDomain(Concept domain) { this.domain = domain; } public String toString() { return name; } public boolean isRestricted() { return restricted; } public void setRestricted(boolean restricted) { this.restricted = restricted; } public String getIri() { return property.replace( "<", "" ).replace( ">", "" ); } public PropertyRelation clone() { PropertyRelation rel = new PropertyRelation( this.subject, this.property, this.object, this.name ); rel.minCard = this.minCard; rel.maxCard = this.maxCard; rel.target = this.target; rel.domain = this.domain; rel.addableTarget = this.addableTarget; rel.restricted = this.restricted; rel.inherited = this.inherited; rel.simple = this.simple; rel.inverse = this.inverse; rel.baseProperty = this.baseProperty; rel.restrictedProperties = new ArrayList<PropertyRelation>( this.restrictedProperties ); rel.chains = new HashSet<List<PropertyRelation>>( this.chains ); return rel; } public PropertyRelation getBaseProperty() { if ( baseProperty == this ) { return this; } else { return baseProperty.getBaseProperty(); } } public PropertyRelation getImmediateBaseProperty() { return baseProperty; } public void setBaseProperty(PropertyRelation baseProperty) { this.baseProperty = baseProperty; baseProperty.addRestrictedChild( this ); } private void addRestrictedChild(PropertyRelation propertyRelation) { this.restrictedProperties.add( propertyRelation ); } public boolean isCollection() { return getMaxCard() == null || getMaxCard() > 1; } public boolean isSimpleBoolean() { return getTarget().getName().equals("xsd:boolean") && ! isCollection(); } public String getTypeName() { return NameUtils.map( getTarget().getName(), true ); } public String getGetter() { String prefix = ( isSimpleBoolean() && ! isCollection() ) ? "is" : "get"; return prefix + NameUtils.compactUpperCase( getName() ); } public String getSetter() { return "set" + NameUtils.compactUpperCase( getName() ); } public String toFullString() { return "Property{" + "subject='" + subject + '\'' + ", property='" + property + '\'' + ", object='" + object + '\'' + ", name='" + name + '\'' + "," + minCard +" .. " + maxCard + '}'; } public boolean mirrors( PropertyRelation that ) { if ( this == that) return true; if (name != null ? !name.equals(that.name) : that.name != null) return false; if (object != null ? !object.equals(that.object) : that.object != null) return false; if (property != null ? !property.equals(that.property) : that.property != null) return false; if (minCard != null ? !minCard.equals(that.minCard) : that.minCard != null) return false; if (maxCard != null ? !maxCard.equals(that.maxCard) : that.maxCard != null) return false; return true; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PropertyRelation that = (PropertyRelation) o; if (name != null ? !name.equals(that.name) : that.name != null) return false; if (object != null ? !object.equals(that.object) : that.object != null) return false; if (property != null ? !property.equals(that.property) : that.property != null) return false; if (subject != null ? !subject.equals(that.subject) : that.subject != null) return false; return true; } @Override public int hashCode() { int result = subject != null ? subject.hashCode() : 0; result = 31 * result + (property != null ? property.hashCode() : 0); result = 31 * result + (object != null ? object.hashCode() : 0); result = 31 * result + (name != null ? name.hashCode() : 0); return result; } public boolean isTransient() { return isChain() || isRestricted(); } public void addPropertyChain(List<PropertyRelation> chain) { chains.add( chain ); } public boolean isChain() { return chains.size() > 0; } public Set<List<PropertyRelation>> getChains() { return chains; } public boolean isReadOnly() { return isChain(); } public boolean isInheritedFor( Concept con ) { return con != null && ! con.getIri().equals( domain.getIri() ); } public boolean isInheritedFor( String conIri ) { return conIri != null && ! conIri.equals( domain.getIri() ); } public void restrictTargetTo( Concept target ) { setAddableTarget(target); setObject( target.getIri() ); for ( PropertyRelation sub : restrictedProperties ) { Concept restrTarget = sub.getTarget(); if ( ! restrTarget.equals( target ) ) { if ( ! restrTarget.getSuperConcepts().contains( target ) ) { sub.restrictTargetTo( target ); } } } } public List<PropertyRelation> getRestrictedProperties() { return restrictedProperties; } public Concept getAddableTarget() { return addableTarget == null ? target : addableTarget; } public void setAddableTarget(Concept addableTarget) { this.addableTarget = addableTarget; } public boolean isInverse() { return inverse; } public void setInverse(boolean inverse) { this.inverse = inverse; } public boolean isInherited() { return inherited; } public void setInherited(boolean inherited) { this.inherited = inherited; } public boolean isSimple() { return simple; } public void setSimple(boolean simple) { this.simple = simple; } }