diff --git a/src/fr/inrialpes/exmo/align/gen/Alterator.java b/src/fr/inrialpes/exmo/align/gen/Alterator.java new file mode 100644 index 0000000000000000000000000000000000000000..b9b3d9762ddf04ec0fbbcf720041e693a48efccd --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/Alterator.java @@ -0,0 +1,85 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen; + +import java.util.Properties; + +import org.semanticweb.owl.align.Alignment; + +import com.hp.hpl.jena.ontology.OntModel; + +/** + * An abstract test generator which takes as input an ontology and an + * alignment between this ontology and another one and transform the + * ontology and the alignment accordingly to a type of alteration. + * + * It follows a particular lifecycle + */ +public interface Alterator { + + /** + * It is created either: + * - from a seed ontology and generate the alignment between this + * ontology itself + * - from a previous alterator from which it will take the output + * ontology and alignment as input. + */ + //public Alterator( Alterator om ); + + /** + * the namespace of the input ontology + */ + public String getNamespace(); + /** + * the namespace of the source ontology in the input alignment + */ + public String getBase(); + + /** + * modify applies the alteration to the input (the results are kept in + * internal structures. + */ + public Alterator modify( Properties params ); + + // Temporary + /** + * getProtoAlignment, getProtoOntology, getHierarchy + * are used for accessing these internal structure at creation time. + */ + public Properties getProtoAlignment(); + public OntModel getProtoOntology(); + public ClassHierarchy getHierarchy(); + + /** + * Modifies the namespaces of source and target ontologies + * (for the main purpose of outputing them) + */ + public void relocateTest( String namespace1, String namespace2 ); + public void relocateTest( String namespace2 ); + + /** + * Returns the altered Alignment and Ontology in output form + */ + public Alignment getAlignment(); + public OntModel getModifiedOntology(); + +} diff --git a/src/fr/inrialpes/exmo/align/gen/AlteratorFactory.java b/src/fr/inrialpes/exmo/align/gen/AlteratorFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..1ee58eae25f7486c5d86a087ae229e69939131ba --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/AlteratorFactory.java @@ -0,0 +1,159 @@ +/** + * $Id$ + * + * Copyright (C) INRIA, 2011 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +package fr.inrialpes.exmo.align.gen; + +import java.util.Map; +import java.util.HashMap; +import java.util.Properties; + +import java.lang.reflect.InvocationTargetException; + +public class AlteratorFactory { + + // The parameter Ids should be here + //public static final int ANY = 0; + + // This should be largely improved with precedence + private static Map<String,String> alterators = null; + + public static Alterator newInstance( String id, Alterator om ) { + if ( alterators == null ) init(); + String classname = alterators.get( id ); + Alterator alt = null; + if ( classname != null ) { + try { + // This should also be a static getInstance! + Class<?> altClass = Class.forName(classname); + Class[] cparams = {Class.forName("fr.inrialpes.exmo.align.gen.Alterator")}; + java.lang.reflect.Constructor altConstructor = altClass.getConstructor(cparams); + Object[] mparams = { om }; + alt = (Alterator)altConstructor.newInstance(mparams); + } catch (ClassNotFoundException cnfex ) { + cnfex.printStackTrace(); // better raise errors + } catch (NoSuchMethodException nsmex) { + nsmex.printStackTrace(); + } catch (InstantiationException ieex) { + ieex.printStackTrace(); + } catch (IllegalAccessException iaex) { + iaex.printStackTrace(); + } catch (InvocationTargetException itex) { + itex.printStackTrace(); + } + } + return alt; + } + + public static void init() { + alterators = new HashMap<String, String>(); + alterators.put( ParametersIds.REMOVE_CLASSES, "fr.inrialpes.exmo.align.gen.alt.RemoveClasses" ); + alterators.put( ParametersIds.REMOVE_PROPERTIES, "fr.inrialpes.exmo.align.gen.alt.RemoveProperties" ); + alterators.put( ParametersIds.REMOVE_RESTRICTIONS, "fr.inrialpes.exmo.align.gen.alt.RemoveRestrictions" ); + alterators.put( ParametersIds.REMOVE_COMMENTS, "fr.inrialpes.exmo.align.gen.alt.RemoveComments" ); + alterators.put( ParametersIds.RENAME_CLASSES, "fr.inrialpes.exmo.align.gen.alt.RenameClasses" ); + alterators.put( ParametersIds.RENAME_PROPERTIES, "fr.inrialpes.exmo.align.gen.alt.RenameProperties" ); + alterators.put( ParametersIds.REMOVE_INDIVIDUALS, "fr.inrialpes.exmo.align.gen.alt.RemoveIndividuals" ); + alterators.put( ParametersIds.REMOVE_CLASSESLEVEL, "fr.inrialpes.exmo.align.gen.alt.RemoveClassLevel" ); + alterators.put( ParametersIds.LEVEL_FLATTENED, "fr.inrialpes.exmo.align.gen.alt.FlattenLevel" ); + alterators.put( ParametersIds.ADD_CLASSES, "fr.inrialpes.exmo.align.gen.alt.AddClasses" ); + alterators.put( ParametersIds.ADD_PROPERTIES, "fr.inrialpes.exmo.align.gen.alt.AddProperties" ); + alterators.put( ParametersIds.ADD_CLASSESLEVEL, "fr.inrialpes.exmo.align.gen.alt.AddClassLevel" ); + alterators.put( ParametersIds.NO_HIERARCHY, "fr.inrialpes.exmo.align.gen.alt.SuppressHierarchy" ); + //alterators.put( , "fr.inrialpes.exmo.align.gen.alt." ); + //alterators.put( , "fr.inrialpes.exmo.align.gen.alt." ); + //alterators.put( , "fr.inrialpes.exmo.align.gen.alt." ); + } + + public static void declareAlterator( String id, String classname ) { + if ( alterators == null ) init(); + alterators.put( id, classname ); + } + + // I should add a run primitive + // which executes all the parameters in the given order + public static Alterator cascadeAlterators( Alterator init, Properties params ) { + Alterator modifier = init; + // JE: Of course, this could be improved (at least be rendered generic) + if ( params.getProperty( ParametersIds.REMOVE_CLASSES ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.REMOVE_CLASSES, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.REMOVE_PROPERTIES ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.REMOVE_PROPERTIES, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.REMOVE_RESTRICTIONS ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.REMOVE_RESTRICTIONS, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.REMOVE_COMMENTS ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.REMOVE_COMMENTS, modifier ); + modifier.modify( params ); + } + + if ( params.getProperty( ParametersIds.RENAME_CLASSES ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.RENAME_CLASSES, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.RENAME_PROPERTIES ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.RENAME_PROPERTIES, modifier ); + modifier.modify( params ); + } + // UNTIL HERE, WE USE THE DOCUMENTED ORDER + + if ( params.getProperty( ParametersIds.REMOVE_INDIVIDUALS ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.REMOVE_INDIVIDUALS, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.REMOVE_CLASSESLEVEL ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.REMOVE_CLASSESLEVEL, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.LEVEL_FLATTENED ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.LEVEL_FLATTENED, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.ADD_CLASSES ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.ADD_CLASSES, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.ADD_PROPERTIES ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.ADD_PROPERTIES, modifier ); + modifier.modify( params ); + } + + if ( params.getProperty( ParametersIds.ADD_CLASSESLEVEL ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.ADD_CLASSESLEVEL, modifier ); + modifier.modify( params ); + } + if ( params.getProperty( ParametersIds.NO_HIERARCHY ) != null ) { + modifier = AlteratorFactory.newInstance( ParametersIds.NO_HIERARCHY, modifier ); + modifier.modify( params ); + } + /* + for( String key : params.stringPropertyNames() ) { + String value = params.getProperty(key); + //if ( debug ) System.out.println( "[" +key + "] => [" + value + "]"); + modifier.modifyOntology( key, value ); //modify the ontology according to it + } + */ + return modifier; + } +} diff --git a/src/fr/inrialpes/exmo/align/gen/BenchmarkGenerator.java b/src/fr/inrialpes/exmo/align/gen/BenchmarkGenerator.java index 264bcdf77d95006f54a29429d924e5fa07545406..f35d59358870b9cda20361b9f72123cd00b04751 100644 --- a/src/fr/inrialpes/exmo/align/gen/BenchmarkGenerator.java +++ b/src/fr/inrialpes/exmo/align/gen/BenchmarkGenerator.java @@ -105,14 +105,16 @@ public class BenchmarkGenerator extends TestSet { addTestChild( "250"+SUFFIX, "261"+SUFFIX, newProperties( ParametersIds.ADD_CLASSES, FULL ) ); /* 266-x *** no names + no comments + no property + expand + no instance */ - addTestChild( "261"+SUFFIX, "266"+SUFFIX, - newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); + // This would generate graded 266 (which is nice, but not in bench) + //addTestChild( "261"+SUFFIX, "266"+SUFFIX, + // newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); /* 260-x *** no names + no comments + no property + flatten */ addTestChild( "250"+SUFFIX, "260"+SUFFIX, newProperties( ParametersIds.LEVEL_FLATTENED, "2" ) ); /* 265-x *** no names + no comments + no property + flatten + no instance */ - addTestChild( "260"+SUFFIX, "265"+SUFFIX, - newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); + // This would generate graded 266 (which is nice, but not in bench) + //addTestChild( "260"+SUFFIX, "265"+SUFFIX, + // newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); /* 251-x *** no names + no comments + flatten */ addTestChild( "202"+SUFFIX, "251"+SUFFIX, newProperties( ParametersIds.LEVEL_FLATTENED, "2" ) ); @@ -126,9 +128,22 @@ public class BenchmarkGenerator extends TestSet { addTestChild( "252"+SUFFIX, "259"+SUFFIX, newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); } + /* 203 *** no comments */ + //Too easy + //addTestChild( "101", "203", + // newProperties( ParametersIds.REMOVE_COMMENTS, FULL ) ); + /* 204 *** naming convention */ + /* 205 *** synonyms */ + /* 207 *** translation (classes) */ + /* 206 *** translation (classes and properties) */ + /* 208 *** naming convention + no comments */ + /* 209 *** synonyms + no comments */ + /* 210 *** translation + no comments */ /* 221 *** no hierarchy */ addTestChild( "101", "221", newProperties( ParametersIds.NO_HIERARCHY, ParametersIds.NO_HIERARCHY ) ); + /* 230 *** flattened classes */ + /* 231 *** expanded classes */ /* 232 *** no hierarchy + no instance */ addTestChild( "221", "232", newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); @@ -174,6 +189,13 @@ public class BenchmarkGenerator extends TestSet { /* 246 *** no property + flatten + no instance */ addTestChild( "239", "246", newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); + /* 265-x *** no names + no comments + no property + flatten + no instance */ + // Warning: For this to work, the suffix should be the more difficult test + addTestChild( "260"+SUFFIX, "265", + newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); + /* 266-x *** no names + no comments + no property + expand + no instance */ + addTestChild( "261"+SUFFIX, "266", + newProperties( ParametersIds.REMOVE_INDIVIDUALS, FULL ) ); } /* diff --git a/src/fr/inrialpes/exmo/align/gen/OntologyModifier.java b/src/fr/inrialpes/exmo/align/gen/OntologyModifier.java deleted file mode 100644 index e74514dcefd3cdfa7281d3262d130e99a2b94d07..0000000000000000000000000000000000000000 --- a/src/fr/inrialpes/exmo/align/gen/OntologyModifier.java +++ /dev/null @@ -1,1615 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2011, INRIA - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - */ - -/* This program receives as input two ontologies (the original ontology, the ontology that must be modified), - an alignment and a parameter with the modification that must be applied to the input ontology. - After the modification of the initial ontology the alignment must be computed - The file in which we store the alignment is "referenceAlignment.rdf" -*/ - -/* This program receives as input two ontologies (the original ontology, the ontology that must be modified), - an alignment and a parameter with the modification that must be applied to the input ontology. - After the modification of the initial ontology the alignment must be computed - The file in which we store the alignment is "referenceAlignment.rdf" -*/ - -package fr.inrialpes.exmo.align.gen; - -//Java classes -import java.net.URI; -import java.util.HashMap; -import java.util.Iterator; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.Random; - -//Alignment API classes -import org.semanticweb.owl.align.Alignment; -import org.semanticweb.owl.align.AlignmentException; - -//Google API classes -import com.google.api.GoogleAPI; -import com.google.api.translate.Language; -import com.google.api.translate.Translate; - -//JENA classes -import com.hp.hpl.jena.ontology.AllValuesFromRestriction; -import com.hp.hpl.jena.ontology.DatatypeProperty; -import com.hp.hpl.jena.ontology.Individual; -import com.hp.hpl.jena.ontology.ObjectProperty; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntClass; -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.ontology.OntProperty; -import com.hp.hpl.jena.ontology.OntResource; -import com.hp.hpl.jena.ontology.Ontology; -import com.hp.hpl.jena.ontology.Restriction; -import com.hp.hpl.jena.ontology.SomeValuesFromRestriction; -import com.hp.hpl.jena.ontology.UnionClass; -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.Property; -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.util.ResourceUtils; -import com.hp.hpl.jena.vocabulary.OWL; -import com.hp.hpl.jena.vocabulary.RDFS; -import com.hp.hpl.jena.vocabulary.XSD; -import fr.inrialpes.exmo.align.impl.URIAlignment; -import java.util.Enumeration; -/* -//WordNet API classes -import edu.smu.tspell.wordnet.Synset; -import edu.smu.tspell.wordnet.WordNetDatabase; -*/ - -//activeRandomString is true -> we replace the label with a random string -//activeTranslateString is true -> we translate the label - -public class OntologyModifier { - private boolean debug = false; - - private ClassHierarchy classHierarchy; //the class hierarchy - private OntModel modifiedModel; //the modified Ontology - private Properties alignment; //the alignment - - private String namespace; //the Namespace - private String namespaceNew; - - private boolean isBuild = false; //keep track if the class hierarchy is build - private boolean isAlign = false; //keep track if the initial alignment has already been computed - private boolean isChanged = false; //keep track if the namespace of the new ontology is changed - private String base; // - - // ------------------------- - // Constructors - //Ontology init, Ontology modified, Alignment align - // JE: Here the alignment is useless... it is used only if nothing is computed! - public OntologyModifier ( OntModel model, Alignment al ) { - modifiedModel = model; - // get the default namespace of the model - namespace = model.getNsPrefixURI(""); - alignment = new Properties(); - } - - // ------------------------- - // Accessors - - public void setDebug( boolean d ) { - debug = d; - } - - public void setNewNamespace( String newNamespace ) { - namespaceNew = newNamespace; - //if ( debug ) System.err.println("New namespace [" + this.namespaceNew + "]"); - } - - //returns the modified ontology after changing the namespace - public OntModel getModifiedOntology () { - //if ( debug ) System.err.println( "->change namespace" ); - modifiedModel = changeNamespace(); //change the namespace of the modified ontology - //if ( debug ) System.err.println( "->namespace changed" ); - return modifiedModel; - } - - public void setModifiedModel(OntModel model) { - modifiedModel = model; - } - - public OntModel getModifiedModel() { - return modifiedModel; - } - - //get properties - public Properties getProperties() { - return alignment; - } - - // ------------------------- - // Utility (string) functions - - //generates a random string with the length "length" - public String getRandomString() { - Random generator = new Random(); - String characters = "abcdefghijklmnopqrstuvwxyz"; - int length = characters.length(); - char[] text = new char[length]; - for (int i = 0; i < length; i++) { - text[i] = characters.charAt( generator.nextInt(length) ); - } - return new String(text); // JE suppressed toUpperCase() - } - - //removes spaces from a string - public String removeSpaces ( String str ) { - //return str.replaceAll("\\s+", ""); - if ( !str.contains( " " ) ) - return str; - else { - String aux = "", aux1=""; - int index; - - if ( str.contains( " " ) ) { - while ( str.indexOf( " " ) != -1 ) { - index = str.indexOf( " " ); - aux += str.substring( 0, index ); - aux1 = str.substring(index+2); - str = str.substring(index+1, index+2).toUpperCase().concat( aux1 ); - } - aux += str; - return aux; - } - } - return str; - } - - //translates the string from English to French - public String translateString( String source ) { - String translatedText = ""; - GoogleAPI.setHttpReferrer("http://code.google.com/p/google-api-translate-java/"); - //Translate.setHttpReferrer("http://code.google.com/p/google-api-translate-java/"); - try { - translatedText = Translate.execute(source, Language.ENGLISH, Language.FRENCH); - } catch (Exception e) { - System.err.println( "Exception " + e.getMessage() ); - } - return removeSpaces ( translatedText ); - } - - //string to upperCase - public String toUpperCase ( String source ) { - return source.toUpperCase(); - } - - //string to lowerCase - public String toLowerCase ( String source ) { - return source.toLowerCase(); - } - - public String getSynonym( String source ) { - return source; - } - /* - //synonym of the word - public String getSynonym ( String source ) { - String synonym = ""; - //set this variable according to your WordNet installation folder - //see : http://lyle.smu.edu/~tspell/jaws/index.html - System.setProperty("wordnet.database.dir", "/usr/Wordnet/WordNet-3.0/dict"); - WordNetDatabase database = WordNetDatabase.getFileInstance(); - Synset[] synsets = database.getSynsets( source ); - if (synsets.length > 0) { - for (int i = 0; i < synsets.length; i++) { - String[] wordForms = synsets[i].getWordForms(); - for (int j = 0; j < wordForms.length; j++) { - if ( !wordForms[j].equals( source ) ) { - synonym = removeSpaces ( wordForms[j] ); - return synonym; - } - } - } - } - else - return source; - return source; - } - */ - - public String parseString (String str, boolean activeTranslateString, boolean activeSynonym) { - // if ( debug ) System.err.println ( "str = [" + str + "]" ); - char [] parsed = str.toCharArray(); - String newString = ""; - - for ( int i=1; i<parsed.length; i++ ) { - if( Character.isUpperCase( parsed[i] ) ) { - String aux = str.substring(0, i); - - if ( activeTranslateString ) - newString = newString.concat( translateString( str.substring(0, i) ) ); - if ( activeSynonym ) - newString = newString.concat( getSynonym( str.substring(0, i) ) ); - - str = str.substring(i); - } - } - - if ( activeTranslateString ) - newString = newString.concat( translateString(str.substring(0)) ); - if ( activeSynonym ) - newString = newString.concat( getSynonym(str.substring(0)) ); - return newString; - } - - // ------------------------- - // Utility (randomizing) functions - - //count - the number of elements from the vector - //the random numElems that must be selected - //uses the Fisher and Yates method to shuffle integers from an array - public int [] randNumbers (int count, int numElems) { - int [] vect = new int[count]; - int [] n = new int[numElems]; - int aux, rand; - Random generator = new Random(); - - for ( int i=0; i<count; i++ ) //fill the array with sorted elements - vect[i] = i; - for ( int j=0; j<numElems; j++ ) { - rand = generator.nextInt( count-j ); //choose a random number from the interval - n[j] = vect[rand]; //build the new vector - aux = vect[rand]; //swap - vect[rand] = vect[count-j-1]; - vect[count-j-1] = aux; - } - return n; - } - - // ------------------------- - // Label replacement - - //replaces the label of the property - public void replacePropertyLabel( String uri, String newLabel, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation ) { - OntProperty prop = modifiedModel.getOntProperty( uri ); - if ( prop.getLabel( "en" ) != null ) { - if ( activeTranslateString ) { - prop.setLabel( newLabel, "fr" ); - } else { - prop.setLabel( newLabel, "en" ); - } - } - } - - //gets the URIs of the properties and their translation - public HashMap<String, String> getPropertiesIdentifiers( float percentage, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation) { - HashMap<String, String> propertiesIdentifiers = new HashMap<String, String>(); //the HashMap of the properties identifiers - List<String> propertiesName = new ArrayList<String>(); //the properties identifiers - - List<OntProperty> propertiesTo = new ArrayList<OntProperty>(); //the list of properties to be renamed - List<OntProperty> notRenamedProperties = new ArrayList<OntProperty>(); //the list of not renamed properties - List<OntProperty> properties = getOntologyProperties(); //the list of all the properties - - int nbProperties, toBeRenamed, renamedProperties; - - //builds the list of all unrenamed properties from the model - for ( OntProperty p : properties ) { - String uri = base + p.getLocalName(); - // JE: I am affraid that alignment is a terible thing here - if ( alignment.containsKey( uri ) ) { - String key = uri; - String value = alignment.getProperty( key ); - if ( key.equals( value ) ) - notRenamedProperties.add( p ); //add the property to not renamed properties - } - } - - - nbProperties = properties.size(); //the number of renamed properties - renamedProperties = nbProperties - notRenamedProperties.size(); - toBeRenamed = (int)(percentage*nbProperties) - renamedProperties; // -renamedProperties -> for Benchmark - - // JE: same thing as for classes... but strange - // JE: should be the symptom of a bug - if ( toBeRenamed < 0 ) toBeRenamed = 0; - //builds the list of properties to be renamed - int [] n = randNumbers(notRenamedProperties.size(), toBeRenamed); - for ( int i=0; i<toBeRenamed; i++ ) { - OntProperty p = notRenamedProperties.get(n[i]); - propertiesTo.add(p); - if ( p.getNameSpace().equals( namespace ) ) - propertiesName.add( p.getLocalName() ); - } - - for ( OntProperty prop : propertiesTo ) { - String nameSpace = prop.getNameSpace(); - String localName = prop.getLocalName(); - //has the same Namespace as the Ontology Namespace - if ( nameSpace.equals( namespace ) ) { - if ( !propertiesIdentifiers.containsKey( localName ) ) { - if ( activeTranslateString ) { //replace the URI with the translated one - String translateStrg = parseString ( localName, true, false); - propertiesIdentifiers.put( localName , translateStrg ); - replacePropertyLabel( prop.getURI(), translateStrg, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - - if ( alignment.containsKey( base + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); - alignment.put( base + prop.getLocalName() , base + translateStrg );//the reference alignment - } - } - else if ( activeRandomString ) { //replace the URI with a random string - String newStrg = getRandomString(); - propertiesIdentifiers.put( localName , newStrg ); - replacePropertyLabel( prop.getURI(), newStrg, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( base + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); - alignment.put( base + prop.getLocalName() , base + newStrg);//the reference alignment - } - } - else if ( activeSynonym ) { - String synonym = parseString (localName, false, true); - if ( propertiesName.contains( synonym ) ) - propertiesIdentifiers.put( localName, localName ); - else { - propertiesIdentifiers.put( localName, synonym ); - replacePropertyLabel( prop.getURI(), synonym, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); - alignment.put( this.base + prop.getLocalName() , this.base + synonym ); //the reference alignment - } - } - } - else if ( activeStringOperation == 1 ) { //replace the URI with the UpperCase URI - propertiesIdentifiers.put( localName , toUpperCase( localName ) ); - replacePropertyLabel( prop.getURI(), toUpperCase( localName ), activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); - alignment.put( this.base + prop.getLocalName() , this.base + toUpperCase( localName ) ); //the reference alignment - } - } - else if ( activeStringOperation == 2 ) { - propertiesIdentifiers.put( localName , toLowerCase( localName ) ); - replacePropertyLabel( prop.getURI(), toLowerCase( localName ), activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + prop.getLocalName() ) ) { // alignment.remove( prop.getURI() ); - alignment.put( this.base + prop.getLocalName() , this.base + toLowerCase( localName ) ); //the reference alignment - } - } - else { - propertiesIdentifiers.put( localName, localName + "PROPERTY" ); - replacePropertyLabel( prop.getURI(), localName + "PROPERTY", activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); - alignment.put( this.base + prop.getLocalName() , this.base + localName + "PROPERTY" ); - } - } - } - } - } - return propertiesIdentifiers; - } - - //replaces the label of the class - public void replaceClassLabel( String uri, String newLabel, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation ) { - OntClass c = modifiedModel.getOntClass( uri ); - - if ( c.getLabel( "en" ) != null ) { - if ( activeTranslateString ) { - c.setLabel( newLabel, "fr" ); - } else - c.setLabel( newLabel, "en" ); - } - } - - //gets the URIs of the classes and their translation - public HashMap<String, String> getClassesIdentifiers ( float percentage, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation ) { - HashMap<String, String> classesIdentifiers = new HashMap<String, String>(); //the HashMap of classes identifiers - - int nbClasses, toBeRenamed, renamedClasses; - - List<OntClass> notRenamedClasses = new ArrayList<OntClass>(); //the list of not renamed classes - List<OntClass> classes = getOntologyClasses(); //the list of ontology classes - List<OntClass> classesTo = new ArrayList<OntClass>(); //the list of classes to be renamed - - // alignment contains those classes which have already been renamed - //builds the list of all unrenamed classes from the model - for ( OntClass c : classes ) { - String uri = base + c.getLocalName(); - //gets the pair <key, value> - if ( alignment.containsKey( uri ) ) { - String key = uri; - String value = alignment.getProperty( uri ); - //they didnt change - if ( key.equals( value ) ) - notRenamedClasses.add( c ); //add the class to not renamed classes - } - } - - nbClasses = classes.size(); - renamedClasses = nbClasses - notRenamedClasses.size(); //the number of renamed classes - toBeRenamed = (int)(percentage*nbClasses) - renamedClasses; // -renamedClasses -> for Benchmark - // JE: toBeRenamed is negative when classes have been added to the model! - // JE TOCHECK IF THIS IS STILL CORRECT - if ( toBeRenamed < 0 ) toBeRenamed = 0; - //build the list of classes to be renamed - int[] n = randNumbers( notRenamedClasses.size(), toBeRenamed ); - for ( int i=0; i<toBeRenamed; i++ ) { - OntClass cls = notRenamedClasses.get(n[i]); - classesTo.add(cls); - } - - for ( OntClass cls : classesTo ) { - if ( !cls.isRestriction() ) { - if ( !cls.isAnon() ) { - String nameSpace = cls.getNameSpace(); - String localName = cls.getLocalName(); - - //has the same Namespace as the Ontology Namespace - if ( nameSpace.equals( namespace ) ) { - if ( !classesIdentifiers.containsKey( localName ) ) { - if ( activeTranslateString ) { //replace the URI with the translated one - String translateStrg = parseString (localName, true, false); - classesIdentifiers.put( localName , translateStrg ); - replaceClassLabel( cls.getURI(), translateStrg, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); - alignment.put( this.base + cls.getLocalName() , this.base + translateStrg); //the reference alignment - } - } - else if ( activeRandomString ) { //replace the URI with a random string - String newStrg = getRandomString(); - classesIdentifiers.put( localName , newStrg ); - replaceClassLabel( cls.getURI(), newStrg, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); - alignment.put( this.base + cls.getLocalName() , this.base + newStrg ); //the reference alignment - } - } - else if ( activeSynonym ) { //replace the URI with a synonym - String synonym = parseString (localName, false, true); - classesIdentifiers.put( localName, synonym ); - replaceClassLabel( cls.getURI(), synonym, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); - alignment.put( this.base + cls.getLocalName() , this.base + synonym );//the reference alignment - } - } - else if ( activeStringOperation == 1 ){ //replace the URI with the UpperCase URI - classesIdentifiers.put( localName , toUpperCase( localName ) ); - replaceClassLabel( cls.getURI(), toUpperCase(localName), activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); - alignment.put( this.base + cls.getLocalName() , this.base + toUpperCase( localName ) ); //the reference alignment - } - } - else if ( activeStringOperation == 2 ){ //replace the URI with the LowerCase URI - classesIdentifiers.put( localName , toLowerCase( localName ) ); - replaceClassLabel( cls.getURI(), toLowerCase(localName), activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); - alignment.put( this.base + cls.getLocalName() , this.base + toLowerCase( localName ) ); //the reference alignment - } - } - else { - classesIdentifiers.put( localName, localName + "CLASS" ); - replaceClassLabel( cls.getURI(), localName + "CLASS", activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - if ( alignment.containsKey( this.base + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); - alignment.put( this.base + cls.getLocalName() , this.base + localName + "CLASS" ); - } - } - } - } - } - } - } - return classesIdentifiers; - } - - //renames percentage properties and classes - //activeProperties -> if true, then rename properties - //activeClasses -> if true, then rename classes - public OntModel renameResource ( boolean activeProperties, boolean activeClasses, float percentage, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation) { - List<Statement> statements = null; //the list of all statements - HashMap<String, String> propertiesIdentifiers = null; //the HashMap of the properties identifiers - HashMap<String, String> classesIdentifiers = null; //the HashMap of the classes identifiers - - OntModel newModel = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );//create new Model - //get properties and classes identifiers - if ( activeProperties ) - propertiesIdentifiers = getPropertiesIdentifiers( percentage, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation); - if ( activeClasses ) - classesIdentifiers = getClassesIdentifiers( percentage, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); - - //iterate and modify the identifiers - for ( Statement stm : modifiedModel.listStatements().toList() ) { - - Resource subject = stm.getSubject(); //the subject - Property predicate = stm.getPredicate(); //the predicate - RDFNode object = stm.getObject(); //the object - - String subjectLocalName, subjectNameSpace; - String predicateLocalName, predicateNameSpace; - String objectLocalName, objectNameSpace; - - boolean isPred, isSubj, isObj; - - Resource subj = null; - Property pred = null; - Resource obj = null; - isPred = isSubj = isObj = false; - - //if it is the subject of the statement - if ( subject.getLocalName() != null ) { - if ( activeProperties ) { - if ( propertiesIdentifiers.containsKey( subject.getLocalName() ) ) { - //if the namespace of the subject is the same as the namespace of the property identifier - if ( subject.getNameSpace().equals( namespace ) ) {//that we want to remove - isSubj = true; - subjectNameSpace = subject.getNameSpace(); - subjectLocalName = subject.getLocalName(); - subj = newModel.createResource( subjectNameSpace + propertiesIdentifiers.get( subjectLocalName ) ); - } - } - } - - if ( activeClasses ) { - if ( classesIdentifiers.containsKey( subject.getLocalName() ) ) { - //if the namespace of the subject is the same as the namespace of the property identifier - //that we want to remove - if (subject.getNameSpace().equals( namespace ) ) { - isSubj = true; - subjectNameSpace = subject.getNameSpace(); - subjectLocalName = subject.getLocalName(); - subj = newModel.createResource( subjectNameSpace + classesIdentifiers.get( subjectLocalName ) ); - } - } - } - } - - //if it is the predicate of the statement - if ( activeProperties ) { - if ( propertiesIdentifiers.containsKey( predicate.getLocalName() ) ) { - //if the namespace of the predicate is the same as the namespace of the property identifier - //that we want to remove - if ( predicate.getNameSpace().equals( this.namespace ) ) { - isPred = true; - predicateNameSpace = predicate.getNameSpace(); - predicateLocalName = predicate.getLocalName(); - pred = newModel.createProperty(predicateNameSpace, propertiesIdentifiers.get( predicateLocalName ) ); - } - } - } - - if ( activeClasses ) { - if ( classesIdentifiers.containsKey( predicate.getLocalName() ) ) { - //if the namespace of the predicate is the same as the namespace of the property identifier - //that we want to remove - if ( predicate.getNameSpace().equals( this.namespace ) ) { - isPred = true; - predicateNameSpace = predicate.getNameSpace(); - predicateLocalName = predicate.getLocalName(); - pred = newModel.createProperty(predicateNameSpace, classesIdentifiers.get( predicateLocalName ) ); - } - } - } - - //if it is the object of the statement - if ( object.canAs( Resource.class ) ) - if ( object.isURIResource() ) { - if ( activeProperties ) { - if ( propertiesIdentifiers.containsKey( object.asResource().getLocalName() ) ) { - //if the namespace of the object is the same as the namespace of the property identifier - //that we want to remove - if ( object.asResource().getNameSpace().equals( this.namespace ) ) { - isObj = true; - objectNameSpace = object.asResource().getNameSpace(); - objectLocalName = object.asResource().getLocalName(); - obj = newModel.createResource(objectNameSpace + propertiesIdentifiers.get( objectLocalName ) ); - } - } - } - - if ( activeClasses ) { - if ( classesIdentifiers.containsKey( object.asResource().getLocalName() ) ) { - //if the namespace of the object is the same as the namespace of the property identifier that we want to remove - if ( object.asResource().getNameSpace().equals( this.namespace ) ) { - isObj = true; - objectNameSpace = object.asResource().getNameSpace(); - objectLocalName = object.asResource().getLocalName(); - obj = newModel.createResource(objectNameSpace + classesIdentifiers.get( objectLocalName ) ); - } - } - } - } - - if ( isSubj ) { - if ( isPred ) { - if ( isObj ) - newModel.add( subj, pred, obj ); - else - newModel.add( subj, pred, object ); - } - else { - if ( isObj ) - newModel.add( subj, predicate, obj ); - else - newModel.add( subj, predicate, object ); - } - } else { - if ( isPred ) { - if ( isObj ) - newModel.add( subject, pred, obj ); - else - newModel.add( subject, pred, object ); - } - else { - if ( isObj ) - newModel.add( subject, predicate, obj ); - else - newModel.add( subject, predicate, object ); - } - } - } - if ( activeClasses ) { - checkClassHierarchy(); - //we update the class hierarchy according to the new modifications - this.classHierarchy.updateClassHierarchy( alignment ); //this.classHierarchy.printClassHierarchy(); - } - return newModel; - } - - // ------------------------- - // Class hierarchy utilities - - //must have the max level of the class hierarchy - public int getMaxLevel() { - checkClassHierarchy(); //check if the class hierarchy is built - return this.classHierarchy.getMaxLevel(); - } - - //if we add / remove a class we need to keep track of the class hierarchy - public void buildClassHierarchy () { - classHierarchy = new ClassHierarchy(); - classHierarchy.buildClassHierarchy( modifiedModel ); - //classHierarchy.printClassHierarchy(); - } - - //check if the class hierarchy is build - public void checkClassHierarchy() { - if ( !this.isBuild ) { - buildClassHierarchy(); - this.isBuild = true; - } - } - - //gets the Ontology classes - @SuppressWarnings("unchecked") - public List<OntClass> getOntologyClasses () { - List<OntClass> classes = new ArrayList<OntClass>(); - for ( Iterator it = modifiedModel.listNamedClasses(); it.hasNext(); ) { - OntClass aux = (OntClass)it.next(); - if ( ( aux ).getNameSpace().equals( this.namespace ) ) { - classes.add( aux ); - } - } - return classes; - } - - //gets the Ontology properties - @SuppressWarnings("unchecked") - public List<OntProperty> getOntologyProperties () { - List<OntProperty> properties = new ArrayList<OntProperty>(); - for ( Iterator it = modifiedModel.listAllOntProperties(); it.hasNext(); ) { - OntProperty prop = (OntProperty)it.next(); - if ( prop.getNameSpace().equals( this.namespace ) ) - properties.add( prop ); - } - return properties; - } - - //adds a class with a random URI to the parent class parentURI - public OntClass addClass ( OntClass parentClass, String name ) { - String childURI = namespace+name; - OntClass childClass = modifiedModel.createClass( childURI );//create a new class to the model - - classHierarchy.addClass( childURI, parentClass.getURI() );//add the node in the hierarchy of classes - parentClass.addSubClass( childClass ); //add the childClass as subclass of parentClass - modifiedModel.add( childClass, RDFS.subClassOf, parentClass ); //add the class to the model - return childClass; - } - - //add the percentage of the specified subclasses - public void addSubClasses ( float percentage ) { - List<OntClass> classes = getOntologyClasses(); //get the list of classes from the Ontology - int nbClasses = classes.size(); //number of classes from the Ontology - int toAdd = (int)(percentage*nbClasses); - - checkClassHierarchy(); //check if the classHierarchy is built - //build the list of properties to be renamed - int[] n = this.randNumbers( nbClasses, toAdd ); - for ( int i=0; i<toAdd; i++ ) { - addClass( classes.get(n[i]), getRandomString() ); //give a random URI to the new class - } - } - - //add nbClasses beginning from level - public void addClasses ( int level, int nbClasses, float percentage ) { - String classURI; - //the parent class -> if level is 1 then we create a new class - //else we get a random class from the level : level-1 to be the parent of the class - OntClass parentClass; - OntClass childClass; - List<OntClass> parentClasses = new ArrayList<OntClass>(); - List<OntClass> childClasses = new ArrayList<OntClass>(); - - checkClassHierarchy(); //check if the class hierarchy is built - if ( level == 1 ) { //the parent of the class is Thing, we add the class and then the rest of the classes - classURI = this.getRandomString(); - parentClass = modifiedModel.createClass( this.namespace + classURI );//create a new class to the model - this.classHierarchy.addClass( this.namespace + classURI, "Thing" ); //add the node in the hierarchy of classes - childClasses.add(parentClass); - } - else { - parentClasses = this.classHierarchy.getClassesFromLevel(modifiedModel, level); - int nbParentClasses = parentClasses.size(); //number of classes from the Ontology - int toAdd = (int) ( percentage * nbClasses ); // 1 can be replaced by percentage - - for ( OntClass pClass : parentClasses ) { - classURI = this.getRandomString(); - childClass = addClass (pClass, classURI ); - pClass = childClass; - childClasses.add( childClass ); - } - } - - for ( OntClass pClass : childClasses ) { - classURI = pClass.getLocalName(); - for ( int i=level+1; i<level + nbClasses; i++ ) { - classURI = "IS_" + classURI; - childClass = addClass (pClass, classURI); - pClass = childClass; - } //this.classHierarchy.printClassHierarchy(); - } - } - - //changes the unionOf, intersectionOf - public OntModel changeDomainRange ( HashMap<String, String> uris ) { - OntModel newModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);//create new Model - boolean isSubj, isObj, isPred; - String subjectNameSpace, subjectLocalName; - String objectNameSpace, objectLocalName; - String predicateNameSpace, predicateLocalName; - - //iterate and modify the identifiers - for ( Statement stm : modifiedModel.listStatements().toList() ) { - Resource subject = stm.getSubject(); //the subject - Property predicate = stm.getPredicate(); //the predicate - RDFNode object = stm.getObject(); //the object - Resource subj = null; - Property pred = null; - Resource obj = null; - isSubj = isObj = isPred = false; - - //if the class appears as the subject of a proposition - if ( subject.getURI() != null ) - if ( uris.containsKey( subject.getURI() ) ) { - isSubj = true; - subj = newModel.createResource( uris.get( subject.getURI() ) ); - } - - //if appears as the predicate - never - if ( predicate.getURI() != null ) - if ( uris.containsKey( predicate.getURI() ) ) { - isPred = true; - pred = newModel.createProperty( uris.get( predicate.getURI() ) ); - } - - //if appears as the object of the statement - if ( object.canAs( Resource.class ) ) - if ( object.isURIResource() ) { - if ( object.asResource().getURI() != null ) - if ( uris.containsKey( object.asResource().getURI() ) ) { - isObj = true; - obj = newModel.createResource( uris.get( object.asResource().getURI() ) ); - } - } - - if ( isSubj ) { - if ( isPred ) { - if ( isObj ) newModel.add( subj, pred, obj ); - else newModel.add( subj, pred, object ); - } - else { - if ( isObj ) newModel.add( subj, predicate, obj ); - else newModel.add( subj, predicate, object ); - } - } else { - if ( isPred ) { - if ( isObj ) newModel.add( subject, pred, obj ); - else newModel.add( subject, pred, object ); - } - else { - if ( isObj ) newModel.add( subject, predicate, obj ); - else newModel.add( subject, predicate, object ); - } - } - } - return newModel; - } - - //check if the removed class appears as AllValueFrom or SomeValueFrom in a restriction - @SuppressWarnings("unchecked") - public void checkClassesRestrictions ( OntClass childClass, OntClass parentClass ) { - Restriction restr = null; - for ( Iterator it = modifiedModel.listRestrictions(); it.hasNext(); ) { - restr = (Restriction)it.next(); //get the restriction - /* isAllValuesFromRestriction */ - if ( restr.isAllValuesFromRestriction() ) { - AllValuesFromRestriction av = restr.asAllValuesFromRestriction(); - if ( av.getAllValuesFrom().getURI() != null ) //if points to the childClass - //if ( av.getNameSpace().equals( this.namespace ) ) - if ( av.getAllValuesFrom().getURI().equals( childClass.getURI() ) ) - av.setAllValuesFrom( parentClass ); //change to point to the parentClass - } - /* isHasValueRestriction */ - if ( restr.isSomeValuesFromRestriction() ) { - SomeValuesFromRestriction sv = restr.asSomeValuesFromRestriction(); - if ( sv.getSomeValuesFrom().getURI() != null ) //if points to the childClass - //if ( sv.getNameSpace().equals( this.namespace ) ) - if ( sv.getSomeValuesFrom().getURI().equals( childClass.getURI() ) ) - sv.setSomeValuesFrom( parentClass ); //change to point to the parentClass - } - - } - } - - //removes a class, returns the uri of his parent - @SuppressWarnings("unchecked") - public String removeClass ( OntClass cls ) { - OntClass parentClass; - ArrayList<OntClass> subClasses = new ArrayList<OntClass>(); //the list of all the subclasses of the class - OntClass thing = modifiedModel.createClass( OWL.Thing.getURI() ); //Thing class - checkClassHierarchy(); //check if the class hierarchy is built - parentClass = this.classHierarchy.removeClass( modifiedModel, cls );//get the parent of the class - - for (Iterator it1 = cls.listSubClasses(); it1.hasNext(); ) { //build the list of subclasses - OntClass subCls = (OntClass)it1.next(); //because we can't change the - subClasses.add( subCls ); //model while we are iterating - } - - if ( parentClass != thing ) //now we change the superclass of classes - for (OntClass clss : subClasses) //new superclass => - clss.setSuperClass( parentClass ); //=>the superclass of the node - - checkClassesRestrictions( cls, parentClass ); - cls.remove(); //remove the class from the Ontology - return parentClass.getURI(); - } - - //remove the subClasses from the list - public void removeSubClasses ( float percentage ) { - List<OntClass> classes = this.getOntologyClasses(); //the list of classes from Ontologu - List<OntClass> removedClasses = new ArrayList<OntClass>(); - List<String> cl = new ArrayList<String>(); - HashMap<String, String> uris = new HashMap<String, String>(); //the HashMap of strings - String parentURI = ""; - int nbClasses = classes.size(); //number of classes - checkClassHierarchy(); //check if the class hierarchy is built - int toBeRemoved = (int) (percentage*nbClasses); //the number of classes to be removed - - //build the list of classes to be removed - int [] n = this.randNumbers(nbClasses, toBeRemoved); - for ( int i=0; i<toBeRemoved; i++ ) { - OntClass cls = classes.get(n[i]); - removedClasses.add( cls ); - cl.add( cls.getURI() ); //builds the list of labels of classes to be removed - } - - for ( OntClass cls : removedClasses ) { //remove the classes from the list - parentURI = removeClass (cls); - uris.put(cls.getURI(), parentURI); - } - - //checks if the class appears like unionOf.. and replaces its appearence with the superclass - modifiedModel = changeDomainRange( uris ); - - //remove the URI of the class from the reference alignment - for ( String key : alignment.stringPropertyNames() ) { - String value = alignment.getProperty( key ); - if ( cl.contains( this.namespace + key.substring(key.indexOf(this.base) + this.base.length() )) ) - alignment.remove( key ); - if ( cl.contains( this.namespace + value.substring(value.indexOf(this.base) + this.base.length() )) ) //we iterate to check if the class appears only like value - alignment.remove( key ); - } - } - - //remove all the classes from a specific level - public void removeClassesFromLevel ( int level ) { - HashMap<String, String> uris = new HashMap<String, String>(); - String parentURI = ""; - //if ( debug ) System.err.println( "Level " + level ); - /* if ( level == 1 ) //except classes from level 1 - return; */ - List<OntClass> classes = new ArrayList<OntClass>(); - checkClassHierarchy(); //check if the class hierarchy is built - classes = this.classHierarchy.getClassesFromLevel(modifiedModel, level); - for ( int i=0; i<classes.size(); i++ ) { //remove the classes from the hierarchy - parentURI = removeClass ( classes.get(i) ); - uris.put(classes.get(i).getURI(), parentURI); - } - //checks if the class appears like unionOf .. and replaces its appearence with the superclass - modifiedModel = changeDomainRange( uris ); - } - - //remove percentage individuals from Ontology - public void removeIndividuals( float percentage ) { - boolean isSubj, isObj; //the individual can appear as subject or object - List<Individual> individuals = modifiedModel.listIndividuals().toList(); - List<Individual> individualsTo = new ArrayList<Individual>(); //the list of individuals to be removed - int nbIndividuals = individuals.size(); //the number of individuals - int toBeRemoved = (int)( percentage*nbIndividuals ); //the number of individuals to be removed - - int [] n = this.randNumbers(nbIndividuals, toBeRemoved); //build the list of individuals to be removed - for ( int i=0; i<toBeRemoved; i++ ) { - Individual indiv = individuals.get(n[i]); //remove the individual from the reference alignment - individualsTo.add( indiv ); - //alignment.remove( indiv.getURI() ); - } - - for ( Statement st : modifiedModel.listStatements().toList() ) { - Resource subject = st.getSubject(); - RDFNode object = st.getObject(); - isSubj = isObj = false; - - if ( individualsTo.contains( subject ) ) - isSubj = true; - if ( object.canAs( Resource.class ) ) - if ( individualsTo.contains( object.asResource() ) ) - isObj = true; - if ( isSubj ) //the individual appears as subject in the statement - modifiedModel.remove( st ); - if ( isObj ) //the individual appears as object in the statement - modifiedModel.remove( st ); - } - } - - //remove properties from the model - @SuppressWarnings("unchecked") - public void removeProperties ( float percentage ) { - List <OntProperty> properties = this.getOntologyProperties(); //the list of all properties from the model - ArrayList <OntProperty> propertiesToBeRemoved = new ArrayList<OntProperty>(); - ArrayList<Restriction> restrictions = new ArrayList<Restriction>(); - ArrayList<OntClass> resources = new ArrayList<OntClass>(); - List<String> pr = new ArrayList<String>(); - boolean isObj, isSubj, isPred; - - int nbProperties = properties.size(); //the number of properties - int toBeRemoved = (int)( percentage*nbProperties ); //the number of properties to be removed - - //build the list of classes to be removed - int [] n = this.randNumbers(nbProperties, toBeRemoved); - for ( int i=0; i<toBeRemoved; i++ ) { //build the list of properties to be removed - OntProperty p = properties.get(n[i]); - propertiesToBeRemoved.add( p ); - pr.add( p.getURI() ); - - - //alignment.remove( p.getURI() ); - for ( Iterator it = p.listReferringRestrictions(); it.hasNext(); ) {//get the restrictions of that property - restrictions.add( (Restriction)it.next() ); - } - for ( Restriction r : restrictions ) //delete all the restrictions - r.remove(); - - //the domain of the property is a unionOf class - if ( p.hasDomain(null) ) { - if ( p.getDomain().canAs( OntResource.class ) ) { - OntResource res = p.getDomain(); - if ( res.canAs( UnionClass.class ) ) { - OntClass cls = res.asClass(); - resources.add(cls); - } - } - } - //the range of the property is a unionOf class - if ( p.hasRange(null) ) { - if ( p.getRange().canAs( OntResource.class ) ) { - OntResource res = p.getRange(); - if ( res.canAs( UnionClass.class ) ) { - OntClass cls = res.asClass(); - resources.add(cls); - } - } - } - } - - for ( OntClass c : resources ) c.remove(); - - //remove that property from alignment - //since we don't respect any order the value can appear as a value, thus we must iterate among all alignment to delete it - int baselength = base.length(); - for ( String key : alignment.stringPropertyNames() ) { - String value = alignment.getProperty(key); - if ( pr.contains( this.namespace + key.substring(key.indexOf(this.base) + baselength ) ) ) { //if ( debug ) System.err.println( "Elimin " + key ); - alignment.remove( key ); - } - if ( pr.contains( this.namespace + value.substring(key.indexOf(this.base) + baselength) ) ) { //if ( debug ) System.err.println( "Elimin " + key ); - alignment.remove( key ); - } - } - - for ( Statement st : modifiedModel.listStatements().toList() ) { //remove the declaration of properties from the model - Resource subject = st.getSubject(); - Property predicate = st.getPredicate(); - RDFNode object = st.getObject(); - isSubj = isPred = isObj = false; - - if ( propertiesToBeRemoved.contains( subject ) ) //if appears as subject - if ( subject.getNameSpace().equals( this.namespace ) ) - isSubj = true; - - if ( propertiesToBeRemoved.contains( predicate ) ) //if appears as predicate - if ( predicate.getNameSpace().equals( this.namespace ) ) - isPred = true; - - if ( object.canAs( Resource.class ) ) //if appears as object - if ( propertiesToBeRemoved.contains( object ) ) - if ( object.asResource().getNameSpace().equals( this.namespace ) ) - isObj = true; - - if ( isSubj || isPred || isObj ) //remove the statement in which the prop - modifiedModel.remove( st ); //appears as subject, predicate or object - } - } - - //add object properties to the Ontology - public void addProperties ( float percentage ) { - List<OntProperty> properties = this.getOntologyProperties(); - List<OntClass> classes = this.getOntologyClasses(); - ObjectProperty p = null; - DatatypeProperty d = null; - Random classRand = new Random(); - int index; - int nbClasses = classes.size(); //the number of classes - int nbProperties = properties.size(); //the number of properties - int toBeAdd = (int)( percentage*nbProperties ); //the number of properties to be add - - for ( int i=0; i<toBeAdd/2; i++ ) { //add object properties - //p = modifiedModel.createObjectProperty( this.namespace + "OBJECT_PROPERTY_" + getRandomString() ); - p = modifiedModel.createObjectProperty( this.namespace + getRandomString() ); - index = classRand.nextInt( nbClasses ); //pick random domain - p.addDomain( classes.get( index ) ); - index = classRand.nextInt( nbClasses ); //pick random range - p.addRange( classes.get( index ) ); - } - - for ( int i=toBeAdd/2; i<toBeAdd; i++ ) { //add datatype properties - //d = modifiedModel.createDatatypeProperty( this.namespace + "DATATYPE_PROPERTY_" + getRandomString() ); - d = modifiedModel.createDatatypeProperty( this.namespace + getRandomString() ); - index = classRand.nextInt( nbClasses ); //add domain - d.addDomain( classes.get( index ) ); - d.addRange( XSD.xstring ); //add range -> string - } - } - - //remove classes comments - @SuppressWarnings("unchecked") - public void removeClassesComments ( float percentage ) { - ArrayList<Literal> comments = new ArrayList<Literal>(); - List<OntClass> classes = modifiedModel.listNamedClasses().toList(); - ArrayList<OntClass> classesTo = new ArrayList<OntClass>(); - int nbClasses = classes.size(); - int toBeRemoved = (int)( percentage * nbClasses ); //number of classes comments to be removed - - int [] n = this.randNumbers(nbClasses, toBeRemoved); - for ( int i=0; i<toBeRemoved; i++ ) { - OntClass cls = classes.get(n[i]); - classesTo.add( cls ); - } - - for ( OntClass c : classesTo ) { - for (Iterator it2 = c.listComments(null); it2.hasNext();) - comments.add(((Literal) it2.next())); - for (Literal lit : comments) // remove comments - c.removeComment( lit ); - comments.clear(); - } - } - - //remove properties comments - @SuppressWarnings("unchecked") - public void removePropertiesComments ( float percentage ) { - ArrayList<Literal> comments = new ArrayList<Literal>(); // an array list to hold all the comments - List<OntProperty> properties = modifiedModel.listAllOntProperties().toList(); - ArrayList<OntProperty> propertiesTo = new ArrayList<OntProperty>(); - int nbProperties = properties.size(); - int toBeRemoved = (int)( percentage * nbProperties ); //the number of properties comments to be removed - - int [] n = this.randNumbers(nbProperties, toBeRemoved); - for ( int i=0; i<toBeRemoved; i++ ) { - OntProperty p = properties.get(n[i]); - propertiesTo.add( p ); - } - - for ( OntProperty prop : propertiesTo ) { - for (Iterator it2 = prop.listComments(null); it2.hasNext();) // get all comments - comments.add(((Literal) it2.next())); - for (Literal lit : comments) //remove comments - prop.removeComment( lit ); - comments.clear(); - } - } - - //remove individuals comments - @SuppressWarnings("unchecked") - public void removeIndividualsComments ( float percentage ) { - ArrayList<Literal> comments = new ArrayList<Literal>(); // an array list to hold all the comments - List<Individual> individuals = modifiedModel.listIndividuals().toList(); - ArrayList<Individual> individualsTo = new ArrayList<Individual>(); - int nbIndividuals = individuals.size(); - int toBeRemoved = (int)( percentage * nbIndividuals ); //number of classes to be removed - - int [] n = this.randNumbers(nbIndividuals, toBeRemoved); - for ( int i=0; i<toBeRemoved; i++ ) { - Individual indiv = individuals.get(n[i]); - individualsTo.add( indiv ); - } - for ( Individual indiv : individuals ) { - for (Iterator it2 = indiv.listComments(null); it2.hasNext(); ) //get all comments - comments.add( ((Literal) it2.next()) ); - for (Literal lit : comments ) //remove comments - indiv.removeComment( lit ); - comments.clear(); - } - } - - //remove Ontologies comments - @SuppressWarnings("unchecked") - public void removeOntologiesComments ( float percentage ) { - ArrayList<Literal> comments = new ArrayList<Literal>(); // an array list to hold all the comments - List<Ontology> ontologies = modifiedModel.listOntologies().toList(); - ArrayList<Ontology> ontologiesTo = new ArrayList<Ontology>(); - int nbOntologies = ontologies.size(); - int toBeRemoved = (int)( percentage * nbOntologies ); //the number of Ontologies comments to be removed - - int [] n = this.randNumbers(nbOntologies, toBeRemoved); - for ( int i=0; i<toBeRemoved; i++ ) { - Ontology onto = ontologies.get(n[i]); - ontologiesTo.add( onto ); - } - - for ( Ontology onto : ontologies ) { - for (Iterator it2 = onto.listComments(null); it2.hasNext(); ) // get all comments - comments.add(((Literal) it2.next())); - for ( Literal lit : comments ) //remove all comments - onto.removeComment( lit ); - comments.clear(); - } - } - - //remove percentage comments - public void removeComments ( float percentage ) { - removeClassesComments ( percentage ); - removeIndividualsComments ( percentage ); - removePropertiesComments ( percentage ); - removeOntologiesComments ( percentage ); - } - - //flatten level - public void levelFlattened ( int level ) { - int size; - boolean active = false; - ArrayList<OntClass> levelClasses = new ArrayList<OntClass>(); //the list of classes from that level - ArrayList<OntClass> parentLevelClasses = new ArrayList<OntClass>(); //the list of parent of the child classes from that level - ArrayList<OntClass> superLevelClasses = new ArrayList<OntClass>(); //the list of parent of the parent classes from that level - if ( level == 1 ) //no change - return; - checkClassHierarchy(); //check if the class hierarchy is built - active = this.classHierarchy.flattenClassHierarchy( modifiedModel, level, levelClasses, parentLevelClasses, superLevelClasses); - size = levelClasses.size(); - - /* remove duplicates from list */ - HashMap<String, ArrayList<Restriction>> restrictions = new HashMap<String, ArrayList<Restriction>>(); - List<String> parentURI = new ArrayList<String>(); - HashMap<String, String> unionOf = new HashMap<String, String>(); - - for ( int i=0; i<size; i++ ) { - OntClass childClass = levelClasses.get( i ); //child class - OntClass parentClass = parentLevelClasses.get( i ); //parent class - - //build the list of restrictions of the parent class - ArrayList<Restriction> restr = new ArrayList<Restriction>(); - List<OntClass> supCls = parentClass.listSuperClasses().toList(); - for ( OntClass cls : supCls ) { - if ( cls.isRestriction() ) { - Restriction r = cls.asRestriction(); - if ( r.isAllValuesFromRestriction() ) - restr.add(r); - if ( r.isCardinalityRestriction() ) - restr.add(r); - if ( r.isHasValueRestriction() ) - restr.add(r); - if ( r.isMaxCardinalityRestriction() ) - restr.add(r); - if ( r.isMinCardinalityRestriction() ) - restr.add(r); - if ( r.isSomeValuesFromRestriction() ) - restr.add(r); - //if ( debug ) System.err.println( cls.getURI() + cls.getLocalName() ); - } - } - //if ( debug ) System.err.println( restr.size() ); - - if ( !restrictions.containsKey( parentClass.getURI() ) ) { - restrictions.put( parentClass.getURI(), restr ); - } - parentURI.add( parentClass.getURI() ); - - //all the classes are subclasses of owl: Thing - if ( active ) { //if ( !parentClass.getURI().equals( "Thing" ) ) { - OntClass superClass = superLevelClasses.get( i ); //parent class of the child class parents - - //if ( debug ) System.err.println("SuperClass class [" + superClass.getURI() + "]"); - //if ( debug ) System.err.println("Parent class [" + parentClass.getURI() + "]"); - //if ( debug ) System.err.println("Child class [" + childClass.getURI() + "]"); - - if ( modifiedModel.containsResource(parentClass) ) { - //to check if the class appears as unionOf, someValuesFrom, allValuesFrom .. - unionOf.put(parentClass.getURI(), superClass.getURI()); - checkClassesRestrictions ( parentClass, superClass ); - parentClass.remove(); - } - childClass.addSuperClass( superClass ); - parentClass.removeSubClass( childClass ); - } else { - OntClass superClass = modifiedModel.createClass( OWL.Thing.getURI() ); //Thing class - - if ( modifiedModel.containsResource(parentClass) ) { - //to check if the class appears as unionOf.. - unionOf.put(parentClass.getURI(), superClass.getURI()); - checkClassesRestrictions ( parentClass, superClass ); - parentClass.remove(); - } - - parentClass.removeSubClass( childClass ); - } - } - - int i = 0; - for ( String uri : parentURI ) { - OntClass childClass = levelClasses.get( i ); - List<Restriction> restr = restrictions.get( uri ); - for ( Restriction r : restr ) { - childClass.addSuperClass(r); - } - i++; - } - - //checks if the class appears like unionOf, someValuesFrom, allValuesFrom .. and replaces its appearence with the superclass - modifiedModel = changeDomainRange(unionOf); - - //remove the parentClass from the alignment - int baselength = base.length(); - for ( String key : alignment.stringPropertyNames() ) { - String value = alignment.getProperty(key); - if ( parentURI.contains( this.namespace + key.substring(key.indexOf(this.base) + baselength) ) ) { //this.classHierarchy.removeUri("Thing", key); - alignment.remove(key); - } - if ( parentURI.contains( this.namespace + value.substring(key.indexOf(this.base) + baselength ))) { //this.classHierarchy.removeUri("Thing", value); - alignment.remove(key); - } - } - - } - - //flatten level - for noHierarchy - public void _noHierarchy ( int level ) { - if ( level == 1 ) return; - int size; - boolean active = false; - ArrayList<OntClass> levelClasses = new ArrayList<OntClass>(); //the list of classes from that level - ArrayList<OntClass> parentLevelClasses = new ArrayList<OntClass>(); //the list of parent of the child classes from that level - ArrayList<OntClass> superLevelClasses = new ArrayList<OntClass>(); //the list of parent of the parent classes from that level - checkClassHierarchy(); //check if the class hierarchy is built - active = this.classHierarchy.flattenClassHierarchy( modifiedModel, level, levelClasses, parentLevelClasses, superLevelClasses); - size = levelClasses.size(); - - for ( int i=0; i<size; i++ ) { - OntClass childClass = levelClasses.get( i ); //child class - OntClass parentClass = parentLevelClasses.get( i ); //parent class - //all the classes are subclasses of owl: Thing - if ( active ) { //if ( !parentClass.getURI().equals( "Thing" ) ) { - OntClass superClass = superLevelClasses.get( i ); //parent class of the child class parents - childClass.addSuperClass( superClass ); - parentClass.removeSubClass( childClass ); - } else { - parentClass.removeSubClass( childClass ); - } - } - } - - public void noHierarchy () { - int level = this.getMaxLevel(); //this.classHierarchy.printClassHierarchy(); - while ( this.getMaxLevel() != 1 ) { - //this.classHierarchy.printClassHierarchy(); - _noHierarchy ( level ); - level--; - - } - } - - //remove percentage restrictions from the model - public void removeRestrictions( float percentage ) { - List<Restriction> restrictions = new ArrayList<Restriction>(); - List<Restriction> restrictionsTo = new ArrayList<Restriction>(); //the array list of restrictions to be removed - restrictions = modifiedModel.listRestrictions().toList(); - int nbRestrictions = restrictions.size(); //the number of restrictions - int toBeRemoved = (int)( percentage*nbRestrictions ); //the number of restrictions to be removed - - int [] n = this.randNumbers(nbRestrictions, toBeRemoved); //build the list of restrictions to be removed - for ( int i=0; i<toBeRemoved; i++ ) { - Restriction res = restrictions.get(n[i]); - restrictionsTo.add( res ); - } - - for ( Restriction res : restrictionsTo ) - res.remove(); - } - - // ------------------------- - // Alignment management - - // isAlign is a not so good way to test initialisation - // (initialisation with an empty Properties is done in the initialiser) - // but the "alignment" is used everywhere... - - //the initial reference alignment - // JE: !!!: no order guarantee in properties !!! - public void initializeAlignment( Properties al ) { - alignment = al; - - Enumeration e = alignment.propertyNames(); - String aux = (String)e.nextElement(); - base = aux.substring(0, aux.lastIndexOf("#")+1); - - isAlign = true; - } - - /** - * copy101 indicates if the ontology is copied in the directory and aligned with itself - * or if it is not copied... - */ - public void initializeAlignment( boolean copy101 ) { - //if ( namespaceNew == null ) new AlignmentException( "New namespace should have been initialised" ); - List<OntClass> classes = modifiedModel.listNamedClasses().toList();//all classes - List<OntProperty> properties = modifiedModel.listAllOntProperties().toList();//all properties - List<Individual> individuals = modifiedModel.listIndividuals().toList();//all individuals - List<Ontology> ontologies = modifiedModel.listOntologies().toList();//all Ontologies - - alignment = new Properties(); - - if ( copy101 ) { - base = namespaceNew; - } else { - base = namespace; - } - - // JE: the namespace change is only correct for '#' namespaces... - for ( OntClass cls : classes ) //list all classes - if ( cls.getNameSpace().equals( namespace ) ) { - // Change URI - String u = cls.getURI(); - String frag = u.substring( namespace.length(), u.length() ); - String uri = base+frag; - alignment.put( uri, uri ); //add them to the initial alignment - } - - for ( OntProperty prop : properties ) //list all properties - if ( prop.getNameSpace().equals( namespace ) ) { - // Change URI - String u = prop.getURI(); - String frag = u.substring( namespace.length(), u.length() ); - String uri = base+frag; - alignment.put( uri, uri ); //add them to the initial alignment - } - isAlign = true; //the alignment has been computed for the first time - } - - //compute the alignment after the modifications - // JE: I'd rather have an alignment - @SuppressWarnings("unchecked") - public Alignment getAlignment() { - Alignment extractedAlignment = new URIAlignment(); - - try { - URI onto1 = new URI( base.substring(0, base.lastIndexOf("#")) ); - URI onto2 = new URI( namespaceNew.substring(0, namespaceNew.lastIndexOf("#")) ); - - extractedAlignment.init(onto1, onto2); - extractedAlignment.setFile1(onto1); - extractedAlignment.setFile2(onto2); - - //Cell addAlignCell(Object ob1, Object ob2, String relation, double measure) throws AlignmentException { - for ( String key : alignment.stringPropertyNames() ) { - String value = alignment.getProperty(key); - URI uri1 = URI.create(key); - URI uri2 = URI.create(this.namespaceNew + value.substring(value.indexOf(this.base) + this.base.length())); - //if ( debug ) System.err.println( "[" + key + "][" + value + "]" ); - extractedAlignment.addAlignCell( uri1, uri2, "=", 1 ); - } - } catch ( Exception ex ) { - ex.printStackTrace(); - } - return extractedAlignment; - } - - // ------------------------- - // Namespace management and change - - //change the namespace of the modified ontology - // JE: ?? - public OntModel changeNamespace () { - this.isChanged = true; - boolean isSubj, isPred, isObj;; - - OntModel newModel = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );//create new Model - - //iterate through all the statements and change the namespace - for ( Statement stm : modifiedModel.listStatements().toList() ) { - Resource subject = stm.getSubject(); //the subject - Property predicate = stm.getPredicate(); //the predicate - RDFNode object = stm.getObject(); //the object - - Resource subj = null; - Property pred = null; - Resource obj = null; - - isPred = isSubj = isObj = false; - - if ( subject.getLocalName() != null ) - if ( !subject.isLiteral() ) - if ( subject.getNameSpace().equals( this.namespace ) ) { - subj = newModel.createResource( this.namespaceNew + subject.getLocalName() ); - isSubj = true; - } - - if ( !object.isLiteral() ) - if ( object.canAs( Resource.class ) ) - if ( object.isURIResource() ) - if ( object.asResource().getNameSpace().equals( this.namespace ) ) { - obj = newModel.createResource( this.namespaceNew + object.asResource().getLocalName() ); - isObj = true; - } - - if ( !predicate.isLiteral() ) - if ( predicate.getNameSpace().equals( this.namespace ) ) { - pred = newModel.createProperty( this.namespaceNew + predicate.getLocalName() ); - isPred = true; - } - - if ( isSubj ) { - if ( isPred ) { - if ( isObj ) - newModel.add( subj, pred, obj ); - else - newModel.add(subj, pred, object); - } - else { - if ( isObj ) - newModel.add( subj, predicate, obj ); - else - newModel.add( subj, predicate, object ); - } - } else { - if ( isPred ) { - if ( isObj ) - newModel.add( subject, pred, obj ); - else - newModel.add( subject, pred, object ); - } - else { - if ( isObj ) - newModel.add( subject, predicate, obj ); - else - newModel.add( subject, predicate, object ); - } - } - } - - //rename the namespace of owl:Ontology - List<Ontology> ontos = newModel.listOntologies().toList(); - for ( Ontology o : ontos ) { - ResourceUtils.renameResource( o, this.namespaceNew ); - } - - return newModel; - } - - // ------------------------- - // Main entry point - - //OntModel model, OntModel modifiedModel, Alignment alignment - public void modifyOntology( String name, String param ) { - if ( param == null ) return; - if ( name == null || name.equals("") ) { - System.err.println( "No parameter" ); //no parameter as input - return; - }; - float value = 0.0f; - String aux = ""; - - if ( param.equals( ParametersIds.NO_HIERARCHY ) ) - ; - else if( param != null) //the value of the parameter - value = Float.valueOf( param ).floatValue(); // ?? - else - aux = param; - - if ( !isAlign ) { - initializeAlignment( false ); //determine the elements from the initial reference alignment - } - - if ( name.equals( ParametersIds.ADD_CLASSES ) ) { //add percentage classes - if ( debug ) System.err.println( "Add Class" + "[" + value + "]"); - addSubClasses( value ); - } else if ( name.equals( ParametersIds.REMOVE_CLASSES ) ) { //remove percentage classes - if ( debug ) System.err.println( "Remove Class" + "[" + value + "]"); - removeSubClasses( value ); - } else if ( name.equals( ParametersIds.REMOVE_COMMENTS ) ) { //remove percentage comments - if ( debug ) System.err.println( "Remove Comments" + "[" + value + "]"); - removeComments ( value ); - } else if ( name.equals( ParametersIds.REMOVE_PROPERTIES ) ) { //remove percentage properties - if ( debug ) System.err.println( "Remove Property" + "[" + value + "]"); - removeProperties ( value ); - } else if ( name.equals( ParametersIds.ADD_PROPERTIES ) ) { //add percentage properties - if ( debug ) System.err.println( "Add Property" + "[" + value + "]"); - addProperties ( value ); - } else if ( name.equals( ParametersIds.ADD_CLASSESLEVEL ) ) { //recursive add nbClasses starting from level level - aux = ((Float)value).toString(); - int index = aux.indexOf("."); - int level = Integer.valueOf( aux.substring(0, index) ); - int nbClasses = Integer.valueOf( aux.substring(index+1, aux.length()) ); - if ( debug ) System.err.println( "level " + level ); - if ( debug ) System.err.println( "nbClasses " + nbClasses ); - float percentage = 1.00f; - addClasses ( level, nbClasses, percentage ); - } else if ( name.equals( ParametersIds.REMOVE_CLASSESLEVEL ) ) { //remove all the classes from the level level - if ( debug ) System.err.println("Remove all classes from level" + (int)value ); - removeClassesFromLevel ( (int)value ); - } else if ( name.equals( ParametersIds.LEVEL_FLATTENED ) ) { //flatten a level - //levelFlattened ( level ); - levelFlattened ( (int)value ); - if ( debug ) System.err.println( "New class hierarchy level " + getMaxLevel() ) ; - } else if ( name.equals( ParametersIds.RENAME_CLASSES ) ) { //rename classes - if ( debug ) System.err.println("Rename classes" + "[" + value + "]" ); - //if ( debug ) System.err.println("\nValue = " + value + "\n"); //activeProperties, activeClasses, .. - modifiedModel = renameResource ( false, true, value, true, false, false, 0); - } else if ( name.equals( ParametersIds.RENAME_PROPERTIES ) ) { //rename properties - if ( debug ) System.err.println("Rename properties " + "[" + value + "]" ); - //if ( debug ) System.err.println("\nValue = " + value + "\n"); //activeProperties, activeClasses, .. - modifiedModel = renameResource ( true, false, value, true, false, false, 0); - } else if ( name.equals( ParametersIds.REMOVE_RESTRICTIONS ) ) { //remove percentage restrictions - if ( debug ) System.err.println("Remove restrictions" + "[" + value + "]"); - removeRestrictions( value ); - } else if ( name.equals( ParametersIds.REMOVE_INDIVIDUALS ) ) { //remove percentage individuals - if ( debug ) System.err.println("Remove individuals" + "[" + value + "]"); - removeIndividuals( value ); - } else if ( name.equals( ParametersIds.NO_HIERARCHY ) ) { //no hierarchy - if ( debug ) System.err.println( "NoHierarchy" ); - noHierarchy(); - } - - //rebuild the class hierarchy every time - this.isBuild = false; - this.isChanged = false; - } - - -} diff --git a/src/fr/inrialpes/exmo/align/gen/TestGenerator.java b/src/fr/inrialpes/exmo/align/gen/TestGenerator.java index 019f9e018f2886cb4b0c7cc887d14384aa0448f0..4ad44a4a0ecd9d9beae91cdba0cf75dae3e7fad3 100644 --- a/src/fr/inrialpes/exmo/align/gen/TestGenerator.java +++ b/src/fr/inrialpes/exmo/align/gen/TestGenerator.java @@ -31,7 +31,6 @@ package fr.inrialpes.exmo.align.gen; // Alignment API implementation classes -import fr.inrialpes.exmo.align.gen.inter.AlignedOntologyGenerator; import fr.inrialpes.exmo.align.impl.URIAlignment; import fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor; @@ -57,20 +56,19 @@ import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.RDFWriter; import com.hp.hpl.jena.util.FileManager; +import fr.inrialpes.exmo.align.gen.alt.EmptyModification; + import java.util.Properties; -// implements AlignedOntologyGenerator public class TestGenerator { private String urlprefix = "http://example.com/"; // Prefix (before testnumber) of test URL private String dirprefix = ""; // Prefix (idem) of directory private String ontoname = "onto.rdf"; // name of ontology to generate private String alignname = "refalign.rdf"; // name of alignment to generate private String initOntoURI = null; // URI of initial ontology - private Properties params; //the modifications private OntModel modifiedOntology; //modified ontology private Alignment resultAlignment; //the reference alignment - private String namespace = ""; //the namespace - private OntologyModifier modifier = null; //the modifier + private Alterator modifier = null; //the modifier private boolean debug = false; public TestGenerator() {} @@ -92,10 +90,6 @@ public class TestGenerator { //returns the modified ontology public void setInitOntoURI( String uri ) { initOntoURI = uri; } - public void setNamespace( String ns ) { namespace = ns; } - //return the newNamespace - public String getNamespace() { return namespace; } - // ******************************************************* GB STUFF //gets the URI @@ -119,6 +113,7 @@ public class TestGenerator { } public static void writeOntology( OntModel model, String destFile, String ns ) { + //System.err.println( " ==> Writing: "+ns ); try { File f = new File( destFile ); FileOutputStream fout = new FileOutputStream( f ); @@ -175,7 +170,6 @@ public class TestGenerator { * Generate a test by altering an existing test */ public Properties incrementModifyOntology( String prevTestDir, Properties al, String testDir, Properties params ) { - // JE: maybe ERROR crtDirName return modifyOntology( dirprefix+"/"+prevTestDir+"/"+ontoname, al, testDir, params ); } @@ -187,78 +181,35 @@ public class TestGenerator { if ( debug ) System.err.println( "Source: "+file+" Target "+testNumber ); //set the TestGenerator ontology OntModel onto = loadOntology( file ); - //set the namespace - setNamespace( getURI( testNumber ) ); - Alignment align = generate( onto, params, al ); - - outputTestDirectory( getModifiedOntology(), align, testNumber ); - return modifier.getProperties(); + Alterator modifier = generate( onto, params, al ); + // Prepare to generate + modifier.relocateTest( getURI( testNumber ) ); + Alignment align = modifier.getAlignment(); // process, not just get + modifiedOntology = modifier.getModifiedOntology(); + //saves the alignment into the file "refalign.rdf", null->System.out + //at the end, compute the reference alignment + outputTestDirectory( modifiedOntology, align, testNumber ); + return modifier.getProtoAlignment(); } // ******************************************************* GENERATOR //generate the alingnment - public Alignment generate( OntModel onto, Properties params, Properties initalign ) { + public Alterator generate( OntModel onto, Properties params, Properties initalign ) { if ( debug ) { System.err.println( "[-------------------------------------------------]" ); System.err.println( urlprefix+" / "+dirprefix+" / "+ontoname+" / "+alignname ); - System.err.println( namespace ); } - // Initialise the modifier class - modifier = new OntologyModifier( onto, new URIAlignment() ); - modifier.setDebug( debug ); - modifier.setNewNamespace( namespace ); + // Load the ontology + Alterator modifier = new EmptyModification( onto ); + ((EmptyModification)modifier).setDebug( debug ); // Initialize the reference alignment - if ( initalign == null ) { - if ( params.getProperty( "copy101" ) != null ) { - modifier.initializeAlignment( true ); - } else { - modifier.initializeAlignment( false ); - } - } else { - modifier.initializeAlignment( initalign ); - } - + if ( initalign != null ) ((EmptyModification)modifier).initializeAlignment( initalign ); + modifier.modify( params ); // Apply all modifications - // JE: Here there is an obvious problems that the modifications are NOT applied in the specified order! - // Hence we should have a mega reordering of these parameter (for all of these, if they are here, do something) - // That would be better as a list in this case than parameters - // But parameters are more flexible... - applyModification( modifier, params, ParametersIds.REMOVE_CLASSES ); - applyModification( modifier, params, ParametersIds.REMOVE_PROPERTIES ); - applyModification( modifier, params, ParametersIds.REMOVE_RESTRICTIONS ); - applyModification( modifier, params, ParametersIds.REMOVE_COMMENTS ); - - applyModification( modifier, params, ParametersIds.ADD_CLASSES ); - applyModification( modifier, params, ParametersIds.ADD_PROPERTIES ); - - applyModification( modifier, params, ParametersIds.RENAME_CLASSES ); - applyModification( modifier, params, ParametersIds.RENAME_PROPERTIES ); - // UNTIL HERE, WE USE THE DOCUMENTED ORDER - - applyModification( modifier, params, ParametersIds.REMOVE_INDIVIDUALS ); - applyModification( modifier, params, ParametersIds.REMOVE_CLASSESLEVEL ); - applyModification( modifier, params, ParametersIds.LEVEL_FLATTENED ); - applyModification( modifier, params, ParametersIds.ADD_CLASSESLEVEL ); - applyModification( modifier, params, ParametersIds.NO_HIERARCHY ); - - /* - for( String key : params.stringPropertyNames() ) { - String value = params.getProperty(key); - //if ( debug ) System.out.println( "[" +key + "] => [" + value + "]"); - modifier.modifyOntology( key, value ); //modify the ontology according to it - } - */ - - //saves the alignment into the file "refalign.rdf", null->System.out - //at the end, compute the reference alignment - resultAlignment = modifier.getAlignment(); //get the reference alignment - modifiedOntology = modifier.getModifiedOntology(); //get the modified ontology - return resultAlignment; + modifier = AlteratorFactory.cascadeAlterators( modifier, params ); + return modifier; } - public void applyModification( OntologyModifier modifier, Properties p, String m ) { - modifier.modifyOntology( m, p.getProperty( m ) ); - } } diff --git a/src/fr/inrialpes/exmo/align/gen/alt/AddClassLevel.java b/src/fr/inrialpes/exmo/align/gen/alt/AddClassLevel.java new file mode 100755 index 0000000000000000000000000000000000000000..308a5d4082f3899872fa408a0df2bf689c7e7da7 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/AddClassLevel.java @@ -0,0 +1,89 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + + +public class AddClassLevel extends BasicAlterator { + + public AddClassLevel( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.ADD_CLASSESLEVEL ); + if ( p == null ) return null; + // JE: FIND A BETTER ENCODING (or several parameters) + int index = p.indexOf("."); + int level = Integer.valueOf( p.substring(0, index) ); + int nbClasses = Integer.valueOf( p.substring(index+1, p.length()) ); + if ( debug ) System.err.println( "level " + level ); + if ( debug ) System.err.println( "nbClasses " + nbClasses ); + float percentage = 1.00f; + String classURI; + //the parent class -> if level is 1 then we create a new class + //else we get a random class from the level : level-1 to be the parent of the class + OntClass parentClass; + OntClass childClass; + List<OntClass> parentClasses = new ArrayList<OntClass>(); + List<OntClass> childClasses = new ArrayList<OntClass>(); + + buildClassHierarchy(); //check if the class hierarchy is built + if ( level == 1 ) { //the parent of the class is Thing, we add the class and then the rest of the classes + classURI = this.getRandomString(); + parentClass = modifiedModel.createClass( modifiedOntologyNS + classURI );//create a new class to the model + classHierarchy.addClass( modifiedOntologyNS + classURI, "Thing" ); //add the node in the hierarchy of classes + childClasses.add(parentClass); + } + else { + parentClasses = classHierarchy.getClassesFromLevel(modifiedModel, level); + int nbParentClasses = parentClasses.size(); //number of classes from the Ontology + int toAdd = Math.round( percentage*nbClasses ); // 1 can be replaced by percentage + + for ( OntClass pClass : parentClasses ) { + classURI = this.getRandomString(); + childClass = addClass (pClass, classURI ); + pClass = childClass; + childClasses.add( childClass ); + } + } + + for ( OntClass pClass : childClasses ) { + classURI = pClass.getLocalName(); + for ( int i=level+1; i<level + nbClasses; i++ ) { + classURI = "IS_" + classURI; + childClass = addClass (pClass, classURI); + pClass = childClass; + } //this.classHierarchy.printClassHierarchy(); + } + return this; // useless + }; + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/AddClasses.java b/src/fr/inrialpes/exmo/align/gen/alt/AddClasses.java new file mode 100755 index 0000000000000000000000000000000000000000..db69d90d89ddf557727e0734363d3a63862eb0de --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/AddClasses.java @@ -0,0 +1,57 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; + +import java.util.Properties; +import java.util.List; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + + +public class AddClasses extends BasicAlterator { + + public AddClasses( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.ADD_CLASSES ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + List<OntClass> classes = getOntologyClasses(); //get the list of classes from the Ontology + int nbClasses = classes.size(); //number of classes from the Ontology + int toAdd = Math.round( percentage*nbClasses ); + + buildClassHierarchy(); //check if the classHierarchy is built + + //build the list of properties to be renamed + int[] n = this.randNumbers( nbClasses, toAdd ); + for ( int i=0; i<toAdd; i++ ) { + addClass( classes.get(n[i]), getRandomString() ); //give a random URI to the new class + } + return this; // useless + }; + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/AddProperties.java b/src/fr/inrialpes/exmo/align/gen/alt/AddProperties.java new file mode 100755 index 0000000000000000000000000000000000000000..33731affb95eb058ef69c586a8f69f24b7dbeaa9 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/AddProperties.java @@ -0,0 +1,78 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.OntProperty; +import com.hp.hpl.jena.ontology.ObjectProperty; +import com.hp.hpl.jena.ontology.DatatypeProperty; +import com.hp.hpl.jena.vocabulary.XSD; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; +import java.util.Random; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + + +public class AddProperties extends BasicAlterator { + + public AddProperties( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.ADD_PROPERTIES ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + List<OntProperty> properties = this.getOntologyProperties(); + List<OntClass> classes = this.getOntologyClasses(); + ObjectProperty property = null; + DatatypeProperty d = null; + Random classRand = new Random(); + int index; + int nbClasses = classes.size(); //the number of classes + int nbProperties = properties.size(); //the number of properties + int toBeAdd = Math.round( percentage*nbProperties ); //the number of properties to be add + + for ( int i=0; i<toBeAdd/2; i++ ) { //add object properties + //p = modifiedModel.createObjectProperty( modifiedOntologyNS + "OBJECT_PROPERTY_" + getRandomString() ); + property = modifiedModel.createObjectProperty( modifiedOntologyNS + getRandomString() ); + index = classRand.nextInt( nbClasses ); //pick random domain + property.addDomain( classes.get( index ) ); + index = classRand.nextInt( nbClasses ); //pick random range + property.addRange( classes.get( index ) ); + } + + for ( int i=toBeAdd/2; i<toBeAdd; i++ ) { //add datatype properties + //d = modifiedModel.createDatatypeProperty( modifiedOntologyNS + "DATATYPE_PROPERTY_" + getRandomString() ); + d = modifiedModel.createDatatypeProperty( modifiedOntologyNS + getRandomString() ); + index = classRand.nextInt( nbClasses ); //add domain + d.addDomain( classes.get( index ) ); + d.addRange( XSD.xstring ); //add range -> string + } + return this; // useless + }; + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/BasicAlterator.java b/src/fr/inrialpes/exmo/align/gen/alt/BasicAlterator.java new file mode 100644 index 0000000000000000000000000000000000000000..4b2180d7c067b23f4547661dccf1a2979a1506f6 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/BasicAlterator.java @@ -0,0 +1,508 @@ +/** + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +/* This program receives as input two ontologies (the original ontology, the ontology that must be modified), + an alignment and a parameter with the modification that must be applied to the input ontology. + After the modification of the initial ontology the alignment must be computed + The file in which we store the alignment is "referenceAlignment.rdf" +*/ + +/* This program receives as input two ontologies (the original ontology, the ontology that must be modified), + an alignment and a parameter with the modification that must be applied to the input ontology. + After the modification of the initial ontology the alignment must be computed + The file in which we store the alignment is "referenceAlignment.rdf" +*/ + +package fr.inrialpes.exmo.align.gen.alt; + +//Java classes +import java.net.URI; +import java.util.HashMap; +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.Random; +import java.util.Enumeration; + +//Alignment API classes +import org.semanticweb.owl.align.Alignment; +import org.semanticweb.owl.align.AlignmentException; + +import fr.inrialpes.exmo.align.impl.URIAlignment; + +//JENA classes +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Property; +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.OWL; +import com.hp.hpl.jena.vocabulary.RDFS; +import com.hp.hpl.jena.util.ResourceUtils; +import com.hp.hpl.jena.ontology.Individual; +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.ontology.OntProperty; +import com.hp.hpl.jena.ontology.Ontology; +import com.hp.hpl.jena.ontology.Restriction; +import com.hp.hpl.jena.ontology.AllValuesFromRestriction; +import com.hp.hpl.jena.ontology.SomeValuesFromRestriction; + + +//gen +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ClassHierarchy; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +public abstract class BasicAlterator implements Alterator { + protected boolean debug = false; + + protected ClassHierarchy classHierarchy; // the class hierarchy + protected OntModel modifiedModel; // the modified Ontology + protected Properties alignment; // the alignment + protected Alignment extractedAlignment; // the alignment corresponding to alignment + + // Policy with respect to namespacess. + // See the doc in html... it explains well what an alterator should be... + // All this should go in the Parameters... + + // Currently (as loaded in empty): + // + // modifiedOntologyNS -> the one from the loaded ontology (e.g, 201-2) + // modifiedOntologyNS is to be used in the loaded ontology + // initOntologyNS -> the one from the loaded alignment (e.g., 101) [it is 101->201-2] + // initOntologyNS is to be used in the alignment + + // There are two possible path to improvements which would improve legibility and speed + // (1) do not put URIs in parameters! + // (2) replace alignment by real Alignments + + protected String modifiedOntologyNS; // the namespace of the loaded OntModel + protected String initOntologyNS; // the namespace of the source ontology + // (the OntModel may already be a modified ontology wrt the source) + + // ------------------------- + // Constructors + // Ontology init, Ontology modified, Alignment align + // This could be a legitimate constructor in which the + // Alignment is transformed in properties + // At the moment it is useless and unused + //public BasicAlterator ( OntModel model, Alignment al ) { + // modifiedModel = model; + // // get the default namespace of the model + // modifiedOntologyNS = model.getNsPrefixURI(""); + // alignment = new Properties(); + //} + + public BasicAlterator() {} + + public BasicAlterator( Alterator om ) { + initModel( om ); + } + + protected void initModel( Alterator om ) { + // cloning + modifiedModel = om.getProtoOntology(); + alignment = om.getProtoAlignment(); + classHierarchy = om.getHierarchy(); + modifiedOntologyNS = om.getNamespace(); + initOntologyNS = om.getBase(); + } + + // abstract + public abstract Alterator modify( Properties params ); + + // ------------------------- + // Accessors + + public void setDebug( boolean d ) { + debug = d; + } + + //returns the modified ontology after changing the namespace + public OntModel getModifiedOntology () { + return modifiedModel; + } + + public void setModifiedModel(OntModel model) { + modifiedModel = model; + } + + public OntModel getModifiedModel() { + return modifiedModel; + } + + public ClassHierarchy getHierarchy() { + return classHierarchy; + } + + //get properties + public Properties getProtoAlignment() { + return alignment; + } + + public OntModel getProtoOntology() { + return modifiedModel; + } + + public String getNamespace() { + return modifiedOntologyNS; + } + + public String getBase() { + return initOntologyNS; + } + + // ------------------------- + // Utility (string) functions + + //generates a random string with the length "length" + // JE: the name if these strings may be unusually too long... + // Think about some variation (based on average length and standard variation?) + // Length and upper casing may be an argument + public String getRandomString() { + Random generator = new Random(); + String characters = "abcdefghijklmnopqrstuvwxyz"; + int length = characters.length(); + char[] text = new char[length]; + for (int i = 0; i < length; i++) { + text[i] = characters.charAt( generator.nextInt(length) ); + } + return new String(text); // JE suppressed toUpperCase() + } + + // ------------------------- + // Utility (randomizing) functions + + //count - the number of elements from the vector + //the random numElems that must be selected + //uses the Fisher and Yates method to shuffle integers from an array + public int [] randNumbers (int count, int numElems) { + int [] vect = new int[count]; + int [] n = new int[numElems]; + int aux, rand; + Random generator = new Random(); + + for ( int i=0; i<count; i++ ) vect[i] = i; //fill the array with sorted elements + for ( int j=0; j<numElems; j++ ) { + rand = generator.nextInt( count-j ); //choose a random number from the interval + n[j] = vect[rand]; //build the new vector + aux = vect[rand]; //swap + vect[rand] = vect[count-j-1]; + vect[count-j-1] = aux; + } + return n; + } + + // ------------------------- + // Class hierarchy utilities + + //if we add / remove a class we need to keep track of the class hierarchy + public void buildClassHierarchy () { + if ( classHierarchy == null ) { + classHierarchy = new ClassHierarchy(); + classHierarchy.buildClassHierarchy( modifiedModel ); + } + //classHierarchy.printClassHierarchy(); + } + + //gets the Ontology classes + @SuppressWarnings("unchecked") + public List<OntClass> getOntologyClasses () { + List<OntClass> classes = new ArrayList<OntClass>(); + for ( Iterator it = modifiedModel.listNamedClasses(); it.hasNext(); ) { + OntClass aux = (OntClass)it.next(); + if ( aux.getNameSpace().equals( modifiedOntologyNS ) ) { + classes.add( aux ); + } + } + return classes; + } + + //gets the Ontology properties + @SuppressWarnings("unchecked") + public List<OntProperty> getOntologyProperties () { + List<OntProperty> properties = new ArrayList<OntProperty>(); + for ( Iterator it = modifiedModel.listAllOntProperties(); it.hasNext(); ) { + OntProperty prop = (OntProperty)it.next(); + if ( prop.getNameSpace().equals( modifiedOntologyNS ) ) + properties.add( prop ); + } + return properties; + } + + //adds a class with a random URI to the parent class parentURI + public OntClass addClass ( OntClass parentClass, String name ) { + String childURI = modifiedOntologyNS+name; + OntClass childClass = modifiedModel.createClass( childURI );//create a new class to the model + + classHierarchy.addClass( childURI, parentClass.getURI() );//add the node in the hierarchy of classes + parentClass.addSubClass( childClass ); //add the childClass as subclass of parentClass + modifiedModel.add( childClass, RDFS.subClassOf, parentClass ); //add the class to the model + return childClass; + } + + //changes the unionOf, intersectionOf + public OntModel changeDomainRange ( HashMap<String, String> uris ) { + OntModel newModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);//create new Model + boolean isSubj, isObj, isPred; + String subjectNameSpace, subjectLocalName; + String objectNameSpace, objectLocalName; + String predicateNameSpace, predicateLocalName; + + //iterate and modify the identifiers + for ( Statement stm : modifiedModel.listStatements().toList() ) { + Resource subject = stm.getSubject(); //the subject + Property predicate = stm.getPredicate(); //the predicate + RDFNode object = stm.getObject(); //the object + Resource subj = null; + Property pred = null; + Resource obj = null; + isSubj = isObj = isPred = false; + + //if the class appears as the subject of a proposition + if ( subject.getURI() != null ) + if ( uris.containsKey( subject.getURI() ) ) { + isSubj = true; + subj = newModel.createResource( uris.get( subject.getURI() ) ); + } + + //if appears as the predicate - never + if ( predicate.getURI() != null ) + if ( uris.containsKey( predicate.getURI() ) ) { + isPred = true; + pred = newModel.createProperty( uris.get( predicate.getURI() ) ); + } + + //if appears as the object of the statement + if ( object.canAs( Resource.class ) ) + if ( object.isURIResource() ) { + if ( object.asResource().getURI() != null ) + if ( uris.containsKey( object.asResource().getURI() ) ) { + isObj = true; + obj = newModel.createResource( uris.get( object.asResource().getURI() ) ); + } + } + + if ( isSubj ) { + if ( isPred ) { + if ( isObj ) newModel.add( subj, pred, obj ); + else newModel.add( subj, pred, object ); + } + else { + if ( isObj ) newModel.add( subj, predicate, obj ); + else newModel.add( subj, predicate, object ); + } + } else { + if ( isPred ) { + if ( isObj ) newModel.add( subject, pred, obj ); + else newModel.add( subject, pred, object ); + } + else { + if ( isObj ) newModel.add( subject, predicate, obj ); + else newModel.add( subject, predicate, object ); + } + } + } + return newModel; + } + + //check if the removed class appears as AllValueFrom or SomeValueFrom in a restriction + @SuppressWarnings("unchecked") + public void checkClassesRestrictions ( OntClass childClass, OntClass parentClass ) { + Restriction restr = null; + for ( Iterator it = modifiedModel.listRestrictions(); it.hasNext(); ) { + restr = (Restriction)it.next(); //get the restriction + /* isAllValuesFromRestriction */ + if ( restr.isAllValuesFromRestriction() ) { + AllValuesFromRestriction av = restr.asAllValuesFromRestriction(); + if ( av.getAllValuesFrom().getURI() != null ) //if points to the childClass + //if ( av.getNameSpace().equals( this.modifiedOntologyNS ) ) + if ( av.getAllValuesFrom().getURI().equals( childClass.getURI() ) ) + av.setAllValuesFrom( parentClass ); //change to point to the parentClass + } + /* isHasValueRestriction */ + if ( restr.isSomeValuesFromRestriction() ) { + SomeValuesFromRestriction sv = restr.asSomeValuesFromRestriction(); + if ( sv.getSomeValuesFrom().getURI() != null ) //if points to the childClass + //if ( sv.getNameSpace().equals( this.modifiedOntologyNS ) ) + if ( sv.getSomeValuesFrom().getURI().equals( childClass.getURI() ) ) + sv.setSomeValuesFrom( parentClass ); //change to point to the parentClass + } + + } + } + + //removes a class, returns the uri of his parent + @SuppressWarnings("unchecked") + public String removeClass ( OntClass cls ) { + OntClass parentClass; + ArrayList<OntClass> subClasses = new ArrayList<OntClass>(); //the list of all the subclasses of the class + OntClass thing = modifiedModel.createClass( OWL.Thing.getURI() ); //Thing class + buildClassHierarchy(); //check if the class hierarchy is built + parentClass = this.classHierarchy.removeClass( modifiedModel, cls );//get the parent of the class + + for (Iterator it1 = cls.listSubClasses(); it1.hasNext(); ) { //build the list of subclasses + OntClass subCls = (OntClass)it1.next(); //because we can't change the + subClasses.add( subCls ); //model while we are iterating + } + + if ( parentClass != thing ) //now we change the superclass of classes + for (OntClass clss : subClasses) //new superclass => + clss.setSuperClass( parentClass ); //=>the superclass of the node + + checkClassesRestrictions( cls, parentClass ); + cls.remove(); //remove the class from the Ontology + return parentClass.getURI(); + } + + //compute the alignment after the modifications + public Alignment getAlignment() { + if ( extractedAlignment == null ) extractAlignment( initOntologyNS, modifiedOntologyNS ); + return extractedAlignment; + } + + /** + * Generates an Alignment from the property list hosting the alignment. + * On the fly rename the matched entities from the base1 (source) and + * base2 (target) namespaces. + * + * The property list is also modified for reflecting the renaming of entities. + * This is useful when the property list is reused when generating TestSets. + */ + public void relocateTest( String namespaceNew ) { + relocateTest( initOntologyNS, namespaceNew ); + } + + public void relocateTest( String base1, String base2 ) { + extractedAlignment = extractAlignment( base1, base2 ); + modifiedModel = changeNamespace( base2 ); + } + + @SuppressWarnings("unchecked") + public Alignment extractAlignment( String base1, String base2 ) { + Alignment extractedAlignment = new URIAlignment(); + + //System.err.println( "\n-----> "+initOntologyNS ); + //System.err.println( "-----> "+base1 ); + //System.err.println( "-----> "+base2 ); + try { + URI onto1 = new URI( base1.substring(0, base1.lastIndexOf("#")) ); + URI onto2 = new URI( base2.substring(0, base2.lastIndexOf("#")) ); + + extractedAlignment.init( onto1, onto2 ); + // JE: not likely correct + extractedAlignment.setFile1( onto1 ); + extractedAlignment.setFile2( onto2 ); + + int endBase = initOntologyNS.lastIndexOf("#")+1; + int endBase2 = base2.lastIndexOf("#")+1; + Properties newProp = new Properties(); + for ( String key : alignment.stringPropertyNames() ) { + String value = alignment.getProperty(key); + String source = key; + // JE: This is useless in principle... + if ( !key.startsWith( base1 ) ) { + String fragment = key.substring( endBase ); + source = base1+fragment; + } + // JE: not efficient certainly + String target = base2+value.substring( value.lastIndexOf("#")+1 ); + //if ( debug ) System.err.println( "[" + source + "][" + target + "]" ); + extractedAlignment.addAlignCell( URI.create( source ), URI.create( target ) ); + newProp.put( source, target ); + } + alignment = newProp; + } catch ( Exception ex ) { + ex.printStackTrace(); + } + return extractedAlignment; + } + + // ------------------------- + // Namespace management and change + + /** + * Modifies the namespace of the generated ontology + */ + // It may be in fact faster to output in a String and to modify namespaces on the fly + // To be tested. + public OntModel changeNamespace ( String ns ) { + boolean isSubj, isPred, isObj; + + OntModel newModel = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );//create new Model + + //iterate through all the statements and change the namespace + for ( Statement stm : modifiedModel.listStatements().toList() ) { + Resource subject = stm.getSubject(); //the subject + Property predicate = stm.getPredicate(); //the predicate + RDFNode object = stm.getObject(); //the object + + Resource subj = null; + Property pred = null; + Resource obj = null; + + isPred = isSubj = isObj = false; + + if ( ( subject.getLocalName() != null ) && ( !subject.isLiteral() ) + && ( subject.getNameSpace().equals( modifiedOntologyNS ) ) ) { + subj = newModel.createResource( ns + subject.getLocalName() ); + isSubj = true; + } + if ( !object.isLiteral() && ( object.canAs( Resource.class ) ) && ( object.isURIResource() ) + && ( object.asResource().getNameSpace().equals( modifiedOntologyNS ) ) ) { + obj = newModel.createResource( ns + object.asResource().getLocalName() ); + isObj = true; + } + if ( !predicate.isLiteral() && ( predicate.getNameSpace().equals( modifiedOntologyNS ) ) ) { + pred = newModel.createProperty( ns + predicate.getLocalName() ); + isPred = true; + } + if ( isSubj ) { + if ( isPred ) { + if ( isObj ) + newModel.add( subj, pred, obj ); + else + newModel.add(subj, pred, object); + } else if ( isObj ) + newModel.add( subj, predicate, obj ); + else + newModel.add( subj, predicate, object ); + } else if ( isPred ) { + if ( isObj ) newModel.add( subject, pred, obj ); + else newModel.add( subject, pred, object ); + } else if ( isObj ) newModel.add( subject, predicate, obj ); + else newModel.add( subject, predicate, object ); + } + + //rename the namespace of owl:Ontology + List<Ontology> ontos = newModel.listOntologies().toList(); + for ( Ontology o : ontos ) { + ResourceUtils.renameResource( o, ns ); + } + + return newModel; + } + + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/EmptyModification.java b/src/fr/inrialpes/exmo/align/gen/alt/EmptyModification.java new file mode 100755 index 0000000000000000000000000000000000000000..af02be9802ca1f42284fad7dd9c4c634dcddf82d --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/EmptyModification.java @@ -0,0 +1,91 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.OntProperty; +import com.hp.hpl.jena.ontology.Individual; +import com.hp.hpl.jena.ontology.Ontology; + +import java.util.Properties; +import java.util.Enumeration; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +import org.semanticweb.owl.align.Alignment; + +public class EmptyModification extends BasicAlterator { + + protected boolean relocateSource = false; + + public EmptyModification( OntModel o ) { + modifiedModel = o; + // get the default namespace of the model + modifiedOntologyNS = modifiedModel.getNsPrefixURI(""); + }; + + // Clearly here setDebug, setNamespace are important + + public Alterator modify( Properties params ) { + relocateSource = ( params.getProperty( "copy101" ) != null ); + + if ( alignment == null ) { + initOntologyNS = modifiedOntologyNS; + + alignment = new Properties(); + + for ( OntClass cls : modifiedModel.listNamedClasses().toList() ) { + if ( cls.getNameSpace().equals( modifiedOntologyNS ) ) { + String uri = cls.getURI(); + alignment.put( uri, uri ); //add them to the initial alignment + } + } + for ( OntProperty prop : modifiedModel.listAllOntProperties().toList() ) { + if ( prop.getNameSpace().equals( modifiedOntologyNS ) ) { + String uri = prop.getURI(); + alignment.put( uri, uri ); //add them to the initial alignment + } + } + } + return this; + } + + // In case of 101, I want to have the empty test + public void relocateTest( String base1, String base2 ) { + super.relocateTest( relocateSource?base2:base1, base2 ); + } + + //the initial reference alignment + public void initializeAlignment( Properties al ) { + alignment = al; + + Enumeration e = alignment.propertyNames(); + String aux = (String)e.nextElement(); + initOntologyNS = aux.substring(0, aux.lastIndexOf("#")+1); + } + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/FlattenLevel.java b/src/fr/inrialpes/exmo/align/gen/alt/FlattenLevel.java new file mode 100755 index 0000000000000000000000000000000000000000..38d0b5a0aedefb7953d1f73ec5cd792c73d17cdf --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/FlattenLevel.java @@ -0,0 +1,151 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.Restriction; +import com.hp.hpl.jena.vocabulary.OWL; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +public class FlattenLevel extends BasicAlterator { + + public FlattenLevel( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.LEVEL_FLATTENED ); + if ( p == null ) return null; + // Should be an float casted in int!!! + int level = (int)Float.parseFloat( p ); + int size; + boolean active = false; + ArrayList<OntClass> levelClasses = new ArrayList<OntClass>(); //the list of classes from that level + ArrayList<OntClass> parentLevelClasses = new ArrayList<OntClass>(); //the list of parent of the child classes from that level + ArrayList<OntClass> superLevelClasses = new ArrayList<OntClass>(); //the list of parent of the parent classes from that level + if ( level == 1 ) return this; //no change + buildClassHierarchy(); //check if the class hierarchy is built + active = classHierarchy.flattenClassHierarchy( modifiedModel, level, levelClasses, parentLevelClasses, superLevelClasses); + size = levelClasses.size(); + + /* remove duplicates from list */ + HashMap<String, ArrayList<Restriction>> restrictions = new HashMap<String, ArrayList<Restriction>>(); + List<String> parentURI = new ArrayList<String>(); + HashMap<String, String> unionOf = new HashMap<String, String>(); + + for ( int i=0; i<size; i++ ) { + OntClass childClass = levelClasses.get( i ); //child class + OntClass parentClass = parentLevelClasses.get( i ); //parent class + + //build the list of restrictions of the parent class + ArrayList<Restriction> restr = new ArrayList<Restriction>(); + List<OntClass> supCls = parentClass.listSuperClasses().toList(); + for ( OntClass cls : supCls ) { + if ( cls.isRestriction() ) { + Restriction r = cls.asRestriction(); + if ( r.isAllValuesFromRestriction() ) + restr.add(r); + if ( r.isCardinalityRestriction() ) + restr.add(r); + if ( r.isHasValueRestriction() ) + restr.add(r); + if ( r.isMaxCardinalityRestriction() ) + restr.add(r); + if ( r.isMinCardinalityRestriction() ) + restr.add(r); + if ( r.isSomeValuesFromRestriction() ) + restr.add(r); + //if ( debug ) System.err.println( cls.getURI() + cls.getLocalName() ); + } + } + //if ( debug ) System.err.println( restr.size() ); + + if ( !restrictions.containsKey( parentClass.getURI() ) ) { + restrictions.put( parentClass.getURI(), restr ); + } + parentURI.add( parentClass.getURI() ); + + //all the classes are subclasses of owl: Thing + if ( active ) { //if ( !parentClass.getURI().equals( "Thing" ) ) { + OntClass superClass = superLevelClasses.get( i ); //parent class of the child class parents + + //if ( debug ) System.err.println("SuperClass class [" + superClass.getURI() + "]"); + //if ( debug ) System.err.println("Parent class [" + parentClass.getURI() + "]"); + //if ( debug ) System.err.println("Child class [" + childClass.getURI() + "]"); + + if ( modifiedModel.containsResource(parentClass) ) { + //to check if the class appears as unionOf, someValuesFrom, allValuesFrom .. + unionOf.put(parentClass.getURI(), superClass.getURI()); + checkClassesRestrictions ( parentClass, superClass ); + parentClass.remove(); + } + childClass.addSuperClass( superClass ); + parentClass.removeSubClass( childClass ); + } else { + OntClass superClass = modifiedModel.createClass( OWL.Thing.getURI() ); //Thing class + + if ( modifiedModel.containsResource(parentClass) ) { + //to check if the class appears as unionOf.. + unionOf.put(parentClass.getURI(), superClass.getURI()); + checkClassesRestrictions ( parentClass, superClass ); + parentClass.remove(); + } + + parentClass.removeSubClass( childClass ); + } + } + + int i = 0; + for ( String uri : parentURI ) { + OntClass childClass = levelClasses.get( i ); + List<Restriction> restr = restrictions.get( uri ); + for ( Restriction r : restr ) { + childClass.addSuperClass(r); + } + i++; + } + + //checks if the class appears like unionOf, someValuesFrom, allValuesFrom .. and replaces its appearence with the superclass + modifiedModel = changeDomainRange(unionOf); + + //remove the parentClass from the alignment + int baselength = initOntologyNS.length(); // key.indexOf+baselenght == baselenght... + for ( String key : alignment.stringPropertyNames() ) { + String value = alignment.getProperty( key ); + if ( parentURI.contains( modifiedOntologyNS + key.substring( key.indexOf( initOntologyNS ) + baselength) ) ) { //this.classHierarchy.removeUri("Thing", key); + alignment.remove( key ); + } + if ( parentURI.contains( modifiedOntologyNS + value.substring( key.indexOf( initOntologyNS ) + baselength ))) { //this.classHierarchy.removeUri("Thing", value); + alignment.remove( key ); + } + } + return this; // useless + }; + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RemoveClassLevel.java b/src/fr/inrialpes/exmo/align/gen/alt/RemoveClassLevel.java new file mode 100755 index 0000000000000000000000000000000000000000..a0f1c08d66b6210c50adbb473d520824079a776e --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/RemoveClassLevel.java @@ -0,0 +1,61 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +public class RemoveClassLevel extends BasicAlterator { + + public RemoveClassLevel( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.REMOVE_CLASSESLEVEL ); + if ( p == null ) return null; + int level = Integer.parseInt( p ); + HashMap<String, String> uris = new HashMap<String, String>(); + String parentURI = ""; + //if ( debug ) System.err.println( "Level " + level ); + /* if ( level == 1 ) //except classes from level 1 + return; */ + List<OntClass> classes = new ArrayList<OntClass>(); + buildClassHierarchy(); //check if the class hierarchy is built + classes = this.classHierarchy.getClassesFromLevel(modifiedModel, level); + for ( int i=0; i<classes.size(); i++ ) { //remove the classes from the hierarchy + parentURI = removeClass ( classes.get(i) ); + uris.put(classes.get(i).getURI(), parentURI); + } + //checks if the class appears like unionOf .. and replaces its appearence with the superclass + modifiedModel = changeDomainRange( uris ); + return this; // useless + }; + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RemoveClasses.java b/src/fr/inrialpes/exmo/align/gen/alt/RemoveClasses.java new file mode 100755 index 0000000000000000000000000000000000000000..ffc83d066498ff1ccae722cb8f93d9f107d7e47b --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/RemoveClasses.java @@ -0,0 +1,78 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +public class RemoveClasses extends BasicAlterator { + + public RemoveClasses( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.REMOVE_CLASSES ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + List<OntClass> classes = this.getOntologyClasses(); //the list of classes from Ontologu + List<OntClass> removedClasses = new ArrayList<OntClass>(); + List<String> cl = new ArrayList<String>(); + HashMap<String, String> uris = new HashMap<String, String>(); //the HashMap of strings + String parentURI = ""; + int nbClasses = classes.size(); //number of classes + buildClassHierarchy(); //check if the class hierarchy is built + int toBeRemoved = Math.round(percentage*nbClasses); //the number of classes to be removed + + //build the list of classes to be removed + int [] n = this.randNumbers(nbClasses, toBeRemoved); + for ( int i=0; i<toBeRemoved; i++ ) { + OntClass cls = classes.get(n[i]); + removedClasses.add( cls ); + cl.add( cls.getURI() ); //builds the list of labels of classes to be removed + } + + for ( OntClass cls : removedClasses ) { //remove the classes from the list + parentURI = removeClass (cls); + uris.put(cls.getURI(), parentURI); + } + + //checks if the class appears like unionOf.. and replaces its appearence with the superclass + modifiedModel = changeDomainRange( uris ); + + //remove the URI of the class from the reference alignment + for ( String key : alignment.stringPropertyNames() ) { + if ( cl.contains( alignment.getProperty( key ) ) ) + alignment.remove( key ); + } + return this; // useless + }; + + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RemoveComments.java b/src/fr/inrialpes/exmo/align/gen/alt/RemoveComments.java new file mode 100755 index 0000000000000000000000000000000000000000..66c6887a2206b1cd1701b25099a9a261f8d01f78 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/RemoveComments.java @@ -0,0 +1,154 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.rdf.model.Literal; +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.ontology.Ontology; +import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.OntProperty; +import com.hp.hpl.jena.ontology.Individual; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + + +public class RemoveComments extends BasicAlterator { + + public RemoveComments( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.REMOVE_COMMENTS ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + removeClassesComments ( percentage ); + removeIndividualsComments ( percentage ); + removePropertiesComments ( percentage ); + removeOntologiesComments ( percentage ); + return this; // useless + }; + + //remove classes comments + @SuppressWarnings("unchecked") + public void removeClassesComments ( float percentage ) { + ArrayList<Literal> comments = new ArrayList<Literal>(); + List<OntClass> classes = modifiedModel.listNamedClasses().toList(); + ArrayList<OntClass> classesTo = new ArrayList<OntClass>(); + int nbClasses = classes.size(); + int toBeRemoved = Math.round( percentage*nbClasses ); //number of classes comments to be removed + + int [] n = this.randNumbers(nbClasses, toBeRemoved); + for ( int i=0; i<toBeRemoved; i++ ) { + OntClass cls = classes.get(n[i]); + classesTo.add( cls ); + } + + for ( OntClass c : classesTo ) { + for (Iterator it2 = c.listComments(null); it2.hasNext();) + comments.add(((Literal) it2.next())); + for (Literal lit : comments) // remove comments + c.removeComment( lit ); + comments.clear(); + } + } + + //remove properties comments + @SuppressWarnings("unchecked") + public void removePropertiesComments ( float percentage ) { + ArrayList<Literal> comments = new ArrayList<Literal>(); // an array list to hold all the comments + List<OntProperty> properties = modifiedModel.listAllOntProperties().toList(); + ArrayList<OntProperty> propertiesTo = new ArrayList<OntProperty>(); + int nbProperties = properties.size(); + int toBeRemoved = Math.round( percentage*nbProperties ); //the number of properties comments to be removed + + int [] n = this.randNumbers(nbProperties, toBeRemoved); + for ( int i=0; i<toBeRemoved; i++ ) { + OntProperty p = properties.get(n[i]); + propertiesTo.add( p ); + } + + for ( OntProperty prop : propertiesTo ) { + for (Iterator it2 = prop.listComments(null); it2.hasNext();) // get all comments + comments.add(((Literal) it2.next())); + for (Literal lit : comments) //remove comments + prop.removeComment( lit ); + comments.clear(); + } + } + + //remove individuals comments + @SuppressWarnings("unchecked") + public void removeIndividualsComments ( float percentage ) { + ArrayList<Literal> comments = new ArrayList<Literal>(); // an array list to hold all the comments + List<Individual> individuals = modifiedModel.listIndividuals().toList(); + ArrayList<Individual> individualsTo = new ArrayList<Individual>(); + int nbIndividuals = individuals.size(); + int toBeRemoved = Math.round( percentage*nbIndividuals ); //number of classes to be removed + + int [] n = this.randNumbers(nbIndividuals, toBeRemoved); + for ( int i=0; i<toBeRemoved; i++ ) { + Individual indiv = individuals.get(n[i]); + individualsTo.add( indiv ); + } + for ( Individual indiv : individuals ) { + for (Iterator it2 = indiv.listComments(null); it2.hasNext(); ) //get all comments + comments.add( ((Literal) it2.next()) ); + for (Literal lit : comments ) //remove comments + indiv.removeComment( lit ); + comments.clear(); + } + } + + //remove Ontologies comments + @SuppressWarnings("unchecked") + public void removeOntologiesComments ( float percentage ) { + ArrayList<Literal> comments = new ArrayList<Literal>(); // an array list to hold all the comments + List<Ontology> ontologies = modifiedModel.listOntologies().toList(); + ArrayList<Ontology> ontologiesTo = new ArrayList<Ontology>(); + int nbOntologies = ontologies.size(); + int toBeRemoved = Math.round( percentage*nbOntologies ); //the number of Ontologies comments to be removed + + int [] n = this.randNumbers(nbOntologies, toBeRemoved); + for ( int i=0; i<toBeRemoved; i++ ) { + Ontology onto = ontologies.get(n[i]); + ontologiesTo.add( onto ); + } + + for ( Ontology onto : ontologies ) { + for (Iterator it2 = onto.listComments(null); it2.hasNext(); ) // get all comments + comments.add(((Literal) it2.next())); + for ( Literal lit : comments ) //remove all comments + onto.removeComment( lit ); + comments.clear(); + } + } + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RemoveIndividuals.java b/src/fr/inrialpes/exmo/align/gen/alt/RemoveIndividuals.java new file mode 100755 index 0000000000000000000000000000000000000000..c564ac57f74a4aaa88ae260c1b63950e265daf0c --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/RemoveIndividuals.java @@ -0,0 +1,79 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +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.ontology.Individual; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + + +public class RemoveIndividuals extends BasicAlterator { + + public RemoveIndividuals( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.REMOVE_INDIVIDUALS ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + boolean isSubj, isObj; //the individual can appear as subject or object + List<Individual> individuals = modifiedModel.listIndividuals().toList(); + List<Individual> individualsTo = new ArrayList<Individual>(); //the list of individuals to be removed + int nbIndividuals = individuals.size(); //the number of individuals + int toBeRemoved = Math.round( percentage*nbIndividuals ); //the number of individuals to be removed + + int [] n = this.randNumbers(nbIndividuals, toBeRemoved); //build the list of individuals to be removed + for ( int i=0; i<toBeRemoved; i++ ) { + Individual indiv = individuals.get(n[i]); //remove the individual from the reference alignment + individualsTo.add( indiv ); + //alignment.remove( indiv.getURI() ); + } + + for ( Statement st : modifiedModel.listStatements().toList() ) { + Resource subject = st.getSubject(); + RDFNode object = st.getObject(); + isSubj = isObj = false; + + if ( individualsTo.contains( subject ) ) + isSubj = true; + if ( object.canAs( Resource.class ) ) + if ( individualsTo.contains( object.asResource() ) ) + isObj = true; + if ( isSubj ) //the individual appears as subject in the statement + modifiedModel.remove( st ); + if ( isObj ) //the individual appears as object in the statement + modifiedModel.remove( st ); + } + return this; // useless + }; + + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RemoveProperties.java b/src/fr/inrialpes/exmo/align/gen/alt/RemoveProperties.java new file mode 100755 index 0000000000000000000000000000000000000000..a8b00bdac66887ccf446956cb31baa1ec3536c6b --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/RemoveProperties.java @@ -0,0 +1,137 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +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.rdf.model.Property; +import com.hp.hpl.jena.ontology.OntResource; +import com.hp.hpl.jena.ontology.OntProperty; +import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.UnionClass; +import com.hp.hpl.jena.ontology.Restriction; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + + +public class RemoveProperties extends BasicAlterator { + + public RemoveProperties( Alterator om ) { + initModel( om ); + }; + + //@SuppressWarnings("unchecked") + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.REMOVE_PROPERTIES ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + List <OntProperty> properties = getOntologyProperties(); //the list of all properties from the model + ArrayList <OntProperty> propertiesToBeRemoved = new ArrayList<OntProperty>(); + ArrayList<Restriction> restrictions = new ArrayList<Restriction>(); + ArrayList<OntClass> resources = new ArrayList<OntClass>(); + List<String> pr = new ArrayList<String>(); + boolean isObj, isSubj, isPred; + + int nbProperties = properties.size(); //the number of properties + + int toBeRemoved = Math.round( percentage*nbProperties ); //the number of properties to be removed + + //build the list of classes to be removed + int[] n = randNumbers( nbProperties, toBeRemoved ); + for ( int i=0; i<toBeRemoved; i++ ) { //build the list of properties to be removed + OntProperty property = properties.get( n[i] ); + propertiesToBeRemoved.add( property ); + pr.add( property.getURI() ); + + //alignment.remove( p.getURI() ); + //get the restrictions of that property + for ( Iterator it = property.listReferringRestrictions(); it.hasNext(); ) { + restrictions.add( (Restriction)it.next() ); + } + //delete all the restrictions + for ( Restriction r : restrictions ) r.remove(); + + //the domain of the property is a unionOf class + if ( property.hasDomain(null) ) { + if ( property.getDomain().canAs( OntResource.class ) ) { + OntResource res = property.getDomain(); + if ( res.canAs( UnionClass.class ) ) { + OntClass cls = res.asClass(); + resources.add(cls); + } + } + } + //the range of the property is a unionOf class + if ( property.hasRange(null) ) { + if ( property.getRange().canAs( OntResource.class ) ) { + OntResource res = property.getRange(); + if ( res.canAs( UnionClass.class ) ) { + OntClass cls = res.asClass(); + resources.add(cls); + } + } + } + } + + for ( OntClass c : resources ) c.remove(); // Remove the class descriptions + + //remove that property from alignment + for ( String key : alignment.stringPropertyNames() ) { + if ( pr.contains( alignment.getProperty( key ) ) ) { + alignment.remove( key ); + } + } + + for ( Statement st : modifiedModel.listStatements().toList() ) { //remove the declaration of properties from the model + Resource subject = st.getSubject(); + Property predicate = st.getPredicate(); + RDFNode object = st.getObject(); + isSubj = isPred = isObj = false; + + if ( propertiesToBeRemoved.contains( subject ) ) //if appears as subject + if ( subject.getNameSpace().equals( modifiedOntologyNS ) ) + isSubj = true; + + if ( propertiesToBeRemoved.contains( predicate ) ) //if appears as predicate + if ( predicate.getNameSpace().equals( modifiedOntologyNS ) ) + isPred = true; + + if ( object.canAs( Resource.class ) ) //if appears as object + if ( propertiesToBeRemoved.contains( object ) ) + if ( object.asResource().getNameSpace().equals( modifiedOntologyNS ) ) + isObj = true; + + if ( isSubj || isPred || isObj ) //remove the statement in which the prop + modifiedModel.remove( st ); //appears as subject, predicate or object + } + return this; // useless + }; + + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RemoveRestrictions.java b/src/fr/inrialpes/exmo/align/gen/alt/RemoveRestrictions.java new file mode 100755 index 0000000000000000000000000000000000000000..6e15105ec5580a5b1549e0ebdf3159da86473b42 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/RemoveRestrictions.java @@ -0,0 +1,59 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.Restriction; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +public class RemoveRestrictions extends BasicAlterator { + + public RemoveRestrictions( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.REMOVE_RESTRICTIONS ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + List<Restriction> restrictions = new ArrayList<Restriction>(); + List<Restriction> restrictionsTo = new ArrayList<Restriction>(); //the array list of restrictions to be removed + restrictions = modifiedModel.listRestrictions().toList(); + int nbRestrictions = restrictions.size(); //the number of restrictions + int toBeRemoved = Math.round( percentage*nbRestrictions ); //the number of restrictions to be removed + + int [] n = this.randNumbers(nbRestrictions, toBeRemoved); //build the list of restrictions to be removed + for ( int i=0; i<toBeRemoved; i++ ) { + Restriction res = restrictions.get(n[i]); + restrictionsTo.add( res ); + } + for ( Restriction res : restrictionsTo ) res.remove(); + return this; // useless + }; + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RenameClasses.java b/src/fr/inrialpes/exmo/align/gen/alt/RenameClasses.java new file mode 100755 index 0000000000000000000000000000000000000000..f52bd1ce1d16f6777ea6e8922cbaf789769cf6f9 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/RenameClasses.java @@ -0,0 +1,47 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; +import com.hp.hpl.jena.ontology.Restriction; +import com.hp.hpl.jena.vocabulary.OWL; + +import java.util.Properties; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +public class RenameClasses extends RenameThings { + + public RenameClasses( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.RENAME_CLASSES ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + modifiedModel = renameResource ( false, true, percentage, true, false, false, 0); + return this; // useless + }; + +} diff --git a/src/fr/inrialpes/exmo/align/gen/inter/AlignedOntologyGenerator.java b/src/fr/inrialpes/exmo/align/gen/alt/RenameProperties.java old mode 100644 new mode 100755 similarity index 59% rename from src/fr/inrialpes/exmo/align/gen/inter/AlignedOntologyGenerator.java rename to src/fr/inrialpes/exmo/align/gen/alt/RenameProperties.java index 881679d26134026e4c5dcee2fdc6a213c4f16d8a..2d0da7b76b1dae5d56e82182be4d297240fd45ca --- a/src/fr/inrialpes/exmo/align/gen/inter/AlignedOntologyGenerator.java +++ b/src/fr/inrialpes/exmo/align/gen/alt/RenameProperties.java @@ -19,16 +19,25 @@ * USA. */ +package fr.inrialpes.exmo.align.gen.alt; -package fr.inrialpes.exmo.align.gen.inter; - -import com.hp.hpl.jena.ontology.OntModel; -import org.semanticweb.owl.align.Alignment; import java.util.Properties; -public interface AlignedOntologyGenerator { +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +public class RenameProperties extends RenameThings { + + public RenameProperties( Alterator om ) { + initModel( om ); + }; - //generate an Alignment refering to the generated Ontology as onto2 (to be saved) - public Alignment generate( OntModel o, Properties p ); + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.RENAME_PROPERTIES ); + if ( p == null ) return null; + float percentage = Float.parseFloat( p ); + modifiedModel = renameResource ( true, false, percentage, true, false, false, 0); + return this; // useless + }; } diff --git a/src/fr/inrialpes/exmo/align/gen/alt/RenameThings.java b/src/fr/inrialpes/exmo/align/gen/alt/RenameThings.java new file mode 100755 index 0000000000000000000000000000000000000000..044b409b3fbbc76d47910ba98533a549e4b5fc76 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/RenameThings.java @@ -0,0 +1,524 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +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.rdf.model.Property; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntProperty; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.ontology.OntClass; + +//Google API classes +import com.google.api.GoogleAPI; +import com.google.api.translate.Language; +import com.google.api.translate.Translate; + +/* +//WordNet API classes +import edu.smu.tspell.wordnet.Synset; +import edu.smu.tspell.wordnet.WordNetDatabase; +*/ + +// JE: reengineer this class... (what have we to rename) + +//activeRandomString is true -> we replace the label with a random string +//activeTranslateString is true -> we translate the label + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; +import java.util.HashMap; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +/** + * This is only an abstract class gathering the renaming routines + */ +public abstract class RenameThings extends BasicAlterator { + + // ------------------------- + // Label replacement + + //replaces the label of the property + public void replacePropertyLabel( String uri, String newLabel, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation ) { + OntProperty prop = modifiedModel.getOntProperty( uri ); + if ( prop.getLabel( "en" ) != null ) { + if ( activeTranslateString ) { + prop.setLabel( newLabel, "fr" ); + } else { + prop.setLabel( newLabel, "en" ); + } + } + } + + // get the URIs of the properties and their translation + public HashMap<String, String> getPropertiesIdentifiers( float percentage, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation) { + HashMap<String, String> propertiesIdentifiers = new HashMap<String, String>(); //the HashMap of the properties identifiers + List<String> propertiesName = new ArrayList<String>(); //the properties identifiers + + List<OntProperty> propertiesTo = new ArrayList<OntProperty>(); //the list of properties to be renamed + List<OntProperty> notRenamedProperties = new ArrayList<OntProperty>(); //the list of not renamed properties + List<OntProperty> properties = getOntologyProperties(); //the list of all the properties + + int nbProperties, toBeRenamed, renamedProperties; + + // build the list of all unrenamed properties from the model + for ( OntProperty p : properties ) { + String local = p.getLocalName(); + String uri = initOntologyNS+local; + if ( alignment.containsKey( uri ) ) { + if ( alignment.getProperty( uri ).equals( modifiedOntologyNS+local ) ) + notRenamedProperties.add( p ); //add the property to not renamed properties + } + } + + nbProperties = properties.size(); //the number of renamed properties + renamedProperties = nbProperties - notRenamedProperties.size(); + toBeRenamed = Math.round(percentage*nbProperties) - renamedProperties; // -renamedProperties -> for Benchmark + + // toBeRenamed is negative when properties have been added to the model + if ( toBeRenamed < 0 ) toBeRenamed = 0; + //builds the list of properties to be renamed + int [] n = randNumbers(notRenamedProperties.size(), toBeRenamed); + for ( int i=0; i<toBeRenamed; i++ ) { + OntProperty p = notRenamedProperties.get(n[i]); + propertiesTo.add(p); + if ( p.getNameSpace().equals( modifiedOntologyNS ) ) + propertiesName.add( p.getLocalName() ); + } + + for ( OntProperty prop : propertiesTo ) { + String prefix = prop.getNameSpace(); + String localName = prop.getLocalName(); + //has the same Namespace as the Ontology Namespace + if ( prefix.equals( modifiedOntologyNS ) ) { + if ( !propertiesIdentifiers.containsKey( localName ) ) { + if ( activeTranslateString ) { //replace the URI with the translated one + String translateStrg = parseString ( localName, true, false); + propertiesIdentifiers.put( localName , translateStrg ); + replacePropertyLabel( prop.getURI(), translateStrg, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + + if ( alignment.containsKey( initOntologyNS + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); + alignment.put( initOntologyNS + prop.getLocalName() , initOntologyNS + translateStrg );//the reference alignment + } + } else if ( activeRandomString ) { //replace the URI with a random string + String newStrg = getRandomString(); + propertiesIdentifiers.put( localName , newStrg ); + replacePropertyLabel( prop.getURI(), newStrg, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); + alignment.put( initOntologyNS + prop.getLocalName() , initOntologyNS + newStrg);//the reference alignment + } + } else if ( activeSynonym ) { + String synonym = parseString (localName, false, true); + if ( propertiesName.contains( synonym ) ) + propertiesIdentifiers.put( localName, localName ); + else { + propertiesIdentifiers.put( localName, synonym ); + replacePropertyLabel( prop.getURI(), synonym, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); + alignment.put( initOntologyNS + prop.getLocalName() , initOntologyNS + synonym ); //the reference alignment + } + } + } else if ( activeStringOperation == 1 ) { //replace the URI with the UpperCase URI + propertiesIdentifiers.put( localName , localName.toUpperCase() ); + replacePropertyLabel( prop.getURI(), localName.toUpperCase(), activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); + alignment.put( initOntologyNS + prop.getLocalName() , initOntologyNS + localName.toUpperCase() ); //the reference alignment + } + } else if ( activeStringOperation == 2 ) { + propertiesIdentifiers.put( localName , localName.toLowerCase() ); + replacePropertyLabel( prop.getURI(), localName.toLowerCase(), activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + prop.getLocalName() ) ) { // alignment.remove( prop.getURI() ); + alignment.put( initOntologyNS + prop.getLocalName() , initOntologyNS + localName.toLowerCase() ); //the reference alignment + } + } else { + propertiesIdentifiers.put( localName, localName + "PROPERTY" ); + replacePropertyLabel( prop.getURI(), localName + "PROPERTY", activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + prop.getLocalName() ) ) { //alignment.remove( prop.getURI() ); + alignment.put( initOntologyNS + prop.getLocalName() , initOntologyNS + localName + "PROPERTY" ); + } + } + } + } + } + return propertiesIdentifiers; + } + + //replaces the label of the class + public void replaceClassLabel( String uri, String newLabel, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation ) { + OntClass c = modifiedModel.getOntClass( uri ); + + if ( c.getLabel( "en" ) != null ) { + if ( activeTranslateString ) { + c.setLabel( newLabel, "fr" ); + } else + c.setLabel( newLabel, "en" ); + } + } + + //gets the URIs of the classes and their translation + public HashMap<String, String> getClassesIdentifiers ( float percentage, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation ) { + HashMap<String, String> classesIdentifiers = new HashMap<String, String>(); //the HashMap of classes identifiers + + int nbClasses, toBeRenamed, renamedClasses; + + List<OntClass> notRenamedClasses = new ArrayList<OntClass>(); //the list of not renamed classes + List<OntClass> classes = getOntologyClasses(); //the list of ontology classes + List<OntClass> classesTo = new ArrayList<OntClass>(); //the list of classes to be renamed + + // alignment contains those classes which have already been renamed + //builds the list of all unrenamed classes from the model + // JE: All these operations are very expensive (be better with either no namespace or alignment) + for ( OntClass c : classes ) { + String local = c.getLocalName(); + String uri = initOntologyNS + local; + if ( alignment.containsKey( uri ) ) { + if ( alignment.getProperty( uri ).equals( modifiedOntologyNS+local ) ) + notRenamedClasses.add( c ); //add the class to not renamed classes + } + } + + nbClasses = classes.size(); + renamedClasses = nbClasses - notRenamedClasses.size(); //the number of renamed classes + toBeRenamed = Math.round(percentage*nbClasses) - renamedClasses; // -renamedClasses -> for Benchmark + + //System.err.println( "NbClasses = "+nbClasses+ " YetToRename = "+notRenamedClasses.size()+" I will rename = "+toBeRenamed ); + + // toBeRenamed is negative when classes have been added to the model + if ( toBeRenamed < 0 ) toBeRenamed = 0; + //build the list of classes to be renamed + int[] n = randNumbers( notRenamedClasses.size(), toBeRenamed ); + for ( int i=0; i<toBeRenamed; i++ ) { + OntClass cls = notRenamedClasses.get(n[i]); + classesTo.add(cls); + } + + for ( OntClass cls : classesTo ) { + if ( !cls.isRestriction() ) { + if ( !cls.isAnon() ) { + String prefix = cls.getNameSpace(); + String localName = cls.getLocalName(); + + //has the same Namespace as the Ontology Namespace + if ( prefix.equals( modifiedOntologyNS ) ) { + if ( !classesIdentifiers.containsKey( localName ) ) { + if ( activeTranslateString ) { //replace the URI with the translated one + String translateStrg = parseString (localName, true, false); + classesIdentifiers.put( localName , translateStrg ); + replaceClassLabel( cls.getURI(), translateStrg, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); + alignment.put( initOntologyNS + cls.getLocalName() , initOntologyNS + translateStrg); //the reference alignment + } + } else if ( activeRandomString ) { //replace the URI with a random string + String newStrg = getRandomString(); + classesIdentifiers.put( localName , newStrg ); + replaceClassLabel( cls.getURI(), newStrg, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); + alignment.put( initOntologyNS + cls.getLocalName() , initOntologyNS + newStrg ); //the reference alignment + } + } else if ( activeSynonym ) { //replace the URI with a synonym + String synonym = parseString (localName, false, true); + classesIdentifiers.put( localName, synonym ); + replaceClassLabel( cls.getURI(), synonym, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); + alignment.put( initOntologyNS + cls.getLocalName() , initOntologyNS + synonym );//the reference alignment + } + } else if ( activeStringOperation == 1 ){ //replace the URI with the UpperCase URI + classesIdentifiers.put( localName , localName.toUpperCase() ); + replaceClassLabel( cls.getURI(), localName.toUpperCase(), activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); + alignment.put( initOntologyNS + cls.getLocalName() , initOntologyNS + localName.toUpperCase() ); //the reference alignment + } + } else if ( activeStringOperation == 2 ){ //replace the URI with the LowerCase URI + classesIdentifiers.put( localName , localName.toLowerCase() ); + replaceClassLabel( cls.getURI(), localName.toLowerCase(), activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); + alignment.put( initOntologyNS + cls.getLocalName() , initOntologyNS + localName.toLowerCase() ); //the reference alignment + } + } else { + classesIdentifiers.put( localName, localName + "CLASS" ); + replaceClassLabel( cls.getURI(), localName + "CLASS", activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + if ( alignment.containsKey( initOntologyNS + cls.getLocalName() ) ) { //alignment.remove( cls.getURI() ); + alignment.put( initOntologyNS + cls.getLocalName() , initOntologyNS + localName + "CLASS" ); + } + } + } + } + } + } + } + return classesIdentifiers; + } + + //renames percentage properties and classes + //activeProperties -> if true, then rename properties + //activeClasses -> if true, then rename classes + public OntModel renameResource ( boolean activeProperties, boolean activeClasses, float percentage, boolean activeRandomString, boolean activeTranslateString, boolean activeSynonym, int activeStringOperation) { + List<Statement> statements = null; //the list of all statements + HashMap<String, String> propertiesIdentifiers = null; //the HashMap of the properties identifiers + HashMap<String, String> classesIdentifiers = null; //the HashMap of the classes identifiers + + OntModel newModel = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );//create new Model + //get properties and classes identifiers + if ( activeProperties ) + propertiesIdentifiers = getPropertiesIdentifiers( percentage, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation); + if ( activeClasses ) + classesIdentifiers = getClassesIdentifiers( percentage, activeRandomString, activeTranslateString, activeSynonym, activeStringOperation ); + + //iterate and modify the identifiers + for ( Statement stm : modifiedModel.listStatements().toList() ) { + + Resource subject = stm.getSubject(); //the subject + Property predicate = stm.getPredicate(); //the predicate + RDFNode object = stm.getObject(); //the object + + String subjectLocalName, subjectNameSpace; + String predicateLocalName, predicateNameSpace; + String objectLocalName, objectNameSpace; + + boolean isPred, isSubj, isObj; + + Resource subj = null; + Property pred = null; + Resource obj = null; + isPred = isSubj = isObj = false; + + //if it is the subject of the statement + if ( subject.getLocalName() != null ) { + if ( activeProperties ) { + if ( propertiesIdentifiers.containsKey( subject.getLocalName() ) ) { + //if the namespace of the subject is the same as the namespace of the property identifier + if ( subject.getNameSpace().equals( modifiedOntologyNS ) ) {//that we want to remove + isSubj = true; + subjectNameSpace = subject.getNameSpace(); + subjectLocalName = subject.getLocalName(); + subj = newModel.createResource( subjectNameSpace + propertiesIdentifiers.get( subjectLocalName ) ); + } + } + } + + if ( activeClasses ) { + if ( classesIdentifiers.containsKey( subject.getLocalName() ) ) { + //if the namespace of the subject is the same as the namespace of the property identifier + //that we want to remove + if (subject.getNameSpace().equals( modifiedOntologyNS ) ) { + isSubj = true; + subjectNameSpace = subject.getNameSpace(); + subjectLocalName = subject.getLocalName(); + subj = newModel.createResource( subjectNameSpace + classesIdentifiers.get( subjectLocalName ) ); + } + } + } + } + + //if it is the predicate of the statement + if ( activeProperties ) { + if ( propertiesIdentifiers.containsKey( predicate.getLocalName() ) ) { + //if the namespace of the predicate is the same as the namespace of the property identifier + //that we want to remove + if ( predicate.getNameSpace().equals( modifiedOntologyNS ) ) { + isPred = true; + predicateNameSpace = predicate.getNameSpace(); + predicateLocalName = predicate.getLocalName(); + pred = newModel.createProperty(predicateNameSpace, propertiesIdentifiers.get( predicateLocalName ) ); + } + } + } + + if ( activeClasses ) { + if ( classesIdentifiers.containsKey( predicate.getLocalName() ) ) { + //if the namespace of the predicate is the same as the namespace of the property identifier + //that we want to remove + if ( predicate.getNameSpace().equals( modifiedOntologyNS ) ) { + isPred = true; + predicateNameSpace = predicate.getNameSpace(); + predicateLocalName = predicate.getLocalName(); + pred = newModel.createProperty(predicateNameSpace, classesIdentifiers.get( predicateLocalName ) ); + } + } + } + + //if it is the object of the statement + if ( object.canAs( Resource.class ) ) + if ( object.isURIResource() ) { + if ( activeProperties ) { + if ( propertiesIdentifiers.containsKey( object.asResource().getLocalName() ) ) { + //if the namespace of the object is the same as the namespace of the property identifier + //that we want to remove + if ( object.asResource().getNameSpace().equals( modifiedOntologyNS ) ) { + isObj = true; + objectNameSpace = object.asResource().getNameSpace(); + objectLocalName = object.asResource().getLocalName(); + obj = newModel.createResource(objectNameSpace + propertiesIdentifiers.get( objectLocalName ) ); + } + } + } + + if ( activeClasses ) { + if ( classesIdentifiers.containsKey( object.asResource().getLocalName() ) ) { + //if the namespace of the object is the same as the namespace of the property identifier that we want to remove + if ( object.asResource().getNameSpace().equals( modifiedOntologyNS ) ) { + isObj = true; + objectNameSpace = object.asResource().getNameSpace(); + objectLocalName = object.asResource().getLocalName(); + obj = newModel.createResource(objectNameSpace + classesIdentifiers.get( objectLocalName ) ); + } + } + } + } + + if ( isSubj ) { + if ( isPred ) { + if ( isObj ) + newModel.add( subj, pred, obj ); + else + newModel.add( subj, pred, object ); + } + else { + if ( isObj ) + newModel.add( subj, predicate, obj ); + else + newModel.add( subj, predicate, object ); + } + } else { + if ( isPred ) { + if ( isObj ) + newModel.add( subject, pred, obj ); + else + newModel.add( subject, pred, object ); + } + else { + if ( isObj ) + newModel.add( subject, predicate, obj ); + else + newModel.add( subject, predicate, object ); + } + } + } + if ( activeClasses ) { + buildClassHierarchy(); + //we update the class hierarchy according to the new modifications + classHierarchy.updateClassHierarchy( alignment ); + //classHierarchy.printClassHierarchy(); + } + return newModel; + } + + // ------------------------- + // Utility (string) functions + + //removes spaces from a string + public String removeSpaces ( String str ) { + //return str.replaceAll("\\s+", ""); + if ( !str.contains( " " ) ) + return str; + else { + String aux = "", aux1=""; + int index; + + if ( str.contains( " " ) ) { + while ( str.indexOf( " " ) != -1 ) { + index = str.indexOf( " " ); + aux += str.substring( 0, index ); + aux1 = str.substring(index+2); + str = str.substring(index+1, index+2).toUpperCase().concat( aux1 ); + } + aux += str; + return aux; + } + } + return str; + } + + //translates the string from English to French + public String translateString( String source ) { + String translatedText = ""; + GoogleAPI.setHttpReferrer("http://code.google.com/p/google-api-translate-java/"); + //Translate.setHttpReferrer("http://code.google.com/p/google-api-translate-java/"); + try { + translatedText = Translate.execute(source, Language.ENGLISH, Language.FRENCH); + } catch (Exception e) { + System.err.println( "Exception " + e.getMessage() ); + } + return removeSpaces ( translatedText ); + } + + public String getSynonym( String source ) { + return source; + } + /* + //synonym of the word + public String getSynonym ( String source ) { + String synonym = ""; + //set this variable according to your WordNet installation folder + //see : http://lyle.smu.edu/~tspell/jaws/index.html + System.setProperty("wordnet.database.dir", "/usr/Wordnet/WordNet-3.0/dict"); + WordNetDatabase database = WordNetDatabase.getFileInstance(); + Synset[] synsets = database.getSynsets( source ); + if (synsets.length > 0) { + for (int i = 0; i < synsets.length; i++) { + String[] wordForms = synsets[i].getWordForms(); + for (int j = 0; j < wordForms.length; j++) { + if ( !wordForms[j].equals( source ) ) { + synonym = removeSpaces ( wordForms[j] ); + return synonym; + } + } + } + } + else + return source; + return source; + } + */ + + public String parseString (String str, boolean activeTranslateString, boolean activeSynonym) { + // if ( debug ) System.err.println ( "str = [" + str + "]" ); + char [] parsed = str.toCharArray(); + String newString = ""; + + for ( int i=1; i<parsed.length; i++ ) { + if( Character.isUpperCase( parsed[i] ) ) { + String aux = str.substring(0, i); + + if ( activeTranslateString ) + newString = newString.concat( translateString( str.substring(0, i) ) ); + if ( activeSynonym ) + newString = newString.concat( getSynonym( str.substring(0, i) ) ); + + str = str.substring(i); + } + } + + if ( activeTranslateString ) + newString = newString.concat( translateString(str.substring(0)) ); + if ( activeSynonym ) + newString = newString.concat( getSynonym(str.substring(0)) ); + return newString; + } + +} diff --git a/src/fr/inrialpes/exmo/align/gen/alt/SuppressHierarchy.java b/src/fr/inrialpes/exmo/align/gen/alt/SuppressHierarchy.java new file mode 100755 index 0000000000000000000000000000000000000000..de9971dac00686c4a3d31512cb3b19aa4f159ce7 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/gen/alt/SuppressHierarchy.java @@ -0,0 +1,83 @@ +/* + * $Id$ + * + * Copyright (C) 2011, INRIA + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + */ + +package fr.inrialpes.exmo.align.gen.alt; + +import com.hp.hpl.jena.ontology.OntClass; + +import java.util.Properties; +import java.util.List; +import java.util.ArrayList; + +import fr.inrialpes.exmo.align.gen.Alterator; +import fr.inrialpes.exmo.align.gen.ParametersIds; + +public class SuppressHierarchy extends BasicAlterator { + + public SuppressHierarchy( Alterator om ) { + initModel( om ); + }; + + public Alterator modify( Properties params ) { + String p = params.getProperty( ParametersIds.NO_HIERARCHY ); + if ( p == null ) return null; + int level = getMaxLevel(); + while ( getMaxLevel() != 1 ) { // JE: dangerous to not use level + //this.classHierarchy.printClassHierarchy(); + noHierarchy ( level ); + level--; + } + return this; // useless + }; + + // flatten level + public void noHierarchy ( int level ) { + if ( level == 1 ) return; + int size; + boolean active = false; + ArrayList<OntClass> levelClasses = new ArrayList<OntClass>(); //the list of classes from that level + ArrayList<OntClass> parentLevelClasses = new ArrayList<OntClass>(); //the list of parent of the child classes from that level + ArrayList<OntClass> superLevelClasses = new ArrayList<OntClass>(); //the list of parent of the parent classes from that level + buildClassHierarchy(); //check if the class hierarchy is built + active = this.classHierarchy.flattenClassHierarchy( modifiedModel, level, levelClasses, parentLevelClasses, superLevelClasses); + size = levelClasses.size(); + + for ( int i=0; i<size; i++ ) { + OntClass childClass = levelClasses.get( i ); //child class + OntClass parentClass = parentLevelClasses.get( i ); //parent class + //all the classes are subclasses of owl: Thing + if ( active ) { //if ( !parentClass.getURI().equals( "Thing" ) ) { + OntClass superClass = superLevelClasses.get( i ); //parent class of the child class parents + childClass.addSuperClass( superClass ); + parentClass.removeSubClass( childClass ); + } else { + parentClass.removeSubClass( childClass ); + } + } + } + + //must have the max level of the class hierarchy + public int getMaxLevel() { + buildClassHierarchy(); //check if the class hierarchy is built + return classHierarchy.getMaxLevel(); + } + +}