a/src/net/timbusproject/dpes/alternative/PreservationIdentifierService.java b/src/net/timbusproject/dpes/alternative/PreservationIdentifierService.java
...
...
16
 * See the License for the specific language governing permissions and limitation under the License.
16
 * See the License for the specific language governing permissions and limitation under the License.
17
 */
17
 */
18
18
19
package net.timbusproject.dpes.alternative;
19
package net.timbusproject.dpes.alternative;
20
20
21
import ch.lambdaj.function.convert.Converter;
21
import net.timbusproject.dpes.alternative.AlternativesBuilder.PreservationAlternativesBuilder;
22
import com.hp.hpl.jena.query.QuerySolution;
22
import net.timbusproject.dpes.alternative.AlternativesBuilder.FileAlternativesBuilder;
23
import net.timbusproject.dpes.alternative.AlternativesBuilder.ToolAlternativesBuilder;
23
import org.apache.commons.io.IOUtils;
24
import org.apache.commons.io.IOUtils;
24
import org.apache.commons.lang3.tuple.ImmutablePair;
25
import org.apache.commons.lang3.tuple.Pair;
26
import org.sba_research.timbus.kb.FormatMigrationOption;
27
import org.sba_research.timbus.kb.ToolKnowledgeBase;
25
import org.sba_research.timbus.kb.ToolKnowledgeBase;
28
import org.sba_research.timbus.kb.timbus.TimbusToolKnowledgeBase;
26
import org.sba_research.timbus.kb.timbus.TimbusToolKnowledgeBase;
29
import org.sbaresearch.owl.AlternativesBuilder;
30
import org.sbaresearch.owl.JenaQueryFacade;
27
import org.sbaresearch.owl.JenaQueryFacade;
31
import org.sbaresearch.owl.OwlApiFacade;
28
import org.sbaresearch.owl.OwlApiFacade;
32
import org.sbaresearch.owl.OwlElementNotFoundException;
29
import org.sbaresearch.owl.OwlElementNotFoundException;
33
import org.semanticweb.owlapi.apibinding.OWLManager;
30
import org.semanticweb.owlapi.apibinding.OWLManager;
34
import org.semanticweb.owlapi.io.OWLXMLOntologyFormat;
35
import org.semanticweb.owlapi.io.StreamDocumentSource;
31
import org.semanticweb.owlapi.io.StreamDocumentSource;
36
import org.semanticweb.owlapi.io.StringDocumentTarget;
37
import org.semanticweb.owlapi.model.*;
32
import org.semanticweb.owlapi.model.*;
38
import uk.ac.manchester.cs.owl.owlapi.OWLOntologyImpl;
39
33
40
import javax.jws.WebMethod;
34
import javax.jws.WebMethod;
41
import javax.jws.WebService;
35
import javax.jws.WebService;
42
import java.io.IOException;
36
import java.io.IOException;
37
import java.util.ArrayList;
43
import java.util.*;
38
import java.util.Date;
44
45
import static ch.lambdaj.Lambda.convert;
46
39
47
@WebService
40
@WebService
48
/**
41
/**
49
 * @author Rudolf Mayer
42
 * @author Rudolf Mayer
50
 */
43
 */
51
public class PreservationIdentifierService {
44
public class PreservationIdentifierService {
52
    public static final IRI IRI_SYSTEM_SOFTWARE = IRI.create("http://timbus.teco.edu/ontologies/DIO.owl#SystemSoftware");
45
    public static final IRI IRI_SYSTEM_SOFTWARE = IRI.create("http://timbus.teco.edu/ontologies/DIO.owl#SystemSoftware");
53
    public static final IRI IRI_FILE = IRI.create("http://id.loc.gov/ontologies/premis.rdf#File");
46
    public static final IRI IRI_FILE = IRI.create("http://id.loc.gov/ontologies/premis.rdf#File");
54
    public static final IRI IRI_OBJECT_CHARACTERISTICS_PROPERTY = IRI.create("http://multimedialab.elis.ugent.be/users/samcoppe/ontologies/Premis/premis.owl#objectCharacteristics");
55
    public static final IRI IRI_OBJECT_CHARACTERISTICS = IRI.create("http://www.loc.gov/premis/rdf/v1#ObjectCharacteristics");
56
    public static final IRI IRI_FORMAT_PROPERTY = IRI.create("http://id.loc.gov/ontologies/premis.rdf#Format");
57
    public static final IRI IRI_FORMAT_REGISTRY = IRI.create("http://id.loc.gov/ontologies/premis.rdf#FormatRegistry");
58
    public static final IRI IRI_FORMAT_REGISTRY_PROPERTY = IRI.create("http://id.loc.gov/ontologies/premis.rdf#FormatRegistry");
59
    public static final IRI IRI_FORMAT_REGISTRY_KEY_PROPERTY = IRI.create("http://www.loc.gov/premis/rdf/v1#hasFormatRegistryKey");
60
    public static final IRI IRI_FORMAT_REGISTRY_NAME_PROPERTY = IRI.create("http://www.loc.gov/premis/rdf/v1#hasFormatRegistryName");
61
47
62
    public static final String IRIPREFIX_CHANGES = "http://timbus.teco.edu/ontologies/preservationChanges/";
63
64
    public static final IRI IRI_PREMIS = IRI.create("http://multimedialab.elis.ugent.be/users/samcoppe/ontologies/Premis/premis.owl");
65
66
    public static final OWLClass PREMIS_EVENT_CLASS = OWLManager.getOWLDataFactory().getOWLClass(
67
            IRI.create(IRI_PREMIS.toString() + "#", "Event"));
68
69
    public static final OWLObjectProperty PREMIS_LINKING_SOURCE_OBJECTPROPERTY = OWLManager.getOWLDataFactory().getOWLObjectProperty(
70
            IRI.create(IRI_PREMIS.toString() + "#", "linkingSourceObject"));
71
72
    public static final OWLObjectProperty PREMIS_LINKING_OUTCOME_OBJECTPROPERTY = OWLManager.getOWLDataFactory().getOWLObjectProperty(
73
            IRI.create(IRI_PREMIS.toString() + "#", "linkingOutcomeObject"));
74
75
    public static final Set<OWLAnnotation> EMPTY_OWL_ANNOTATIONS = Collections.emptySet();
76
    private final ToolKnowledgeBase knowledgeBase;
48
    private final ToolKnowledgeBase knowledgeBase;
77
49
78
    public PreservationIdentifierService() {
50
    public PreservationIdentifierService() {
79
        String knowledgebasePath = "http://timbus.teco.edu/ontologies/preservationIdentifier/toolKB_instance.owl";
51
        String knowledgebasePath = "http://timbus.teco.edu/ontologies/preservationIdentifier/toolKB_instance.owl";
80
        this.knowledgeBase = new TimbusToolKnowledgeBase(new JenaQueryFacade(JenaQueryFacade.getModelFromPath(knowledgebasePath, true)));
52
        this.knowledgeBase = new TimbusToolKnowledgeBase(new JenaQueryFacade(JenaQueryFacade.getModelFromPath(knowledgebasePath, true)));
...
...
85
    public ArrayList<PreservationAlternative> identifyPreservationAlternatives(String originalContextModelAsXML,
57
    public ArrayList<PreservationAlternative> identifyPreservationAlternatives(String originalContextModelAsXML,
86
                                                                               ArrayList<Risk> identifiedRisks, String baseURL, String identifier)
58
                                                                               ArrayList<Risk> identifiedRisks, String baseURL, String identifier)
87
            throws OwlElementNotFoundException, OWLOntologyCreationException, OWLOntologyStorageException, IOException {
59
            throws OwlElementNotFoundException, OWLOntologyCreationException, OWLOntologyStorageException, IOException {
88
        System.out.println("New request: " + new Date());
60
        System.out.println("New request: " + new Date());
89
61
90
        ArrayList<PreservationAlternative> alternatives = new ArrayList<PreservationAlternative>();
62
        ArrayList<PreservationAlternative> alternatives = new ArrayList<>();
91
63
92
        OWLOntology originalModel = OWLManager.createOWLOntologyManager().loadOntologyFromOntologyDocument(
64
        OWLOntology originalModel = OWLManager.createOWLOntologyManager().loadOntologyFromOntologyDocument(
93
                new StreamDocumentSource(IOUtils.toInputStream(originalContextModelAsXML)));
65
                new StreamDocumentSource(IOUtils.toInputStream(originalContextModelAsXML)));
94
        OwlApiFacade originalModelFacade = new OwlApiFacade(originalModel);
66
        OwlApiFacade originalModelFacade = new OwlApiFacade(originalModel);
95
67
96
        System.out.println("\t" + originalModel.getOntologyID());
68
        System.out.println("\t" + originalModel.getOntologyID());
97
69
70
        PreservationAlternativesBuilder fileAlternativesBuilder = new FileAlternativesBuilder(knowledgeBase, baseURL, originalModelFacade, identifier);
71
        PreservationAlternativesBuilder alternativesBuilder = new ToolAlternativesBuilder(knowledgeBase, baseURL, originalModelFacade, identifier);
72
98
        // do preservation identification for each risk
73
        // do preservation identification for each risk
99
        for (Risk identifiedRisk : identifiedRisks) {
74
        for (Risk identifiedRisk : identifiedRisks) {
100
            System.out.println("Risk " + identifiedRisk.getRiskIdentifier());
75
            System.out.println("Risk " + identifiedRisk.getRiskIdentifier());
101
76
102
            String affectedResourceName = identifiedRisk.getAffectedResource();
77
            IRI individualAtRisk = originalModelFacade.findIndividualByFragmentAndLabel(identifiedRisk.getAffectedResource());
103
            IRI individualAtRisk = findIndividual(originalModelFacade, affectedResourceName);
78
            if (individualAtRisk == null) {
104
79
                System.out.println("Individual could not be found, ignoring: " + identifiedRisk.getAffectedResource());
105
            if (individualAtRisk == null) continue; // ignore affected resources that could not be found
80
                continue;
81
            }
106
            OWLNamedIndividual individualInOriginalModel = originalModelFacade.getIndividual(individualAtRisk.toString());
82
            OWLNamedIndividual individualInOriginalModel = originalModelFacade.getIndividual(individualAtRisk.toString());
107
            // currently only look at system software
108
            if (originalModelFacade.isIndividualOfClass(individualInOriginalModel, IRI_SYSTEM_SOFTWARE)) {
83
            if (originalModelFacade.isIndividualOfClass(individualInOriginalModel, IRI_SYSTEM_SOFTWARE)) {
109
                addToolAlternatives(baseURL, identifier, alternatives, originalModelFacade, identifiedRisk, affectedResourceName, individualInOriginalModel);
84
                alternatives.addAll(alternativesBuilder.createAlternatives(identifiedRisk, individualAtRisk));
110
            } else if (originalModelFacade.isIndividualOfClass(individualInOriginalModel, IRI_FILE)) {
85
            } else if (originalModelFacade.isIndividualOfClass(individualInOriginalModel, IRI_FILE)) {
111
                addFileAlternatives(baseURL, identifier, alternatives, originalModelFacade, identifiedRisk, individualAtRisk);
86
                alternatives.addAll(fileAlternativesBuilder.createAlternatives(identifiedRisk, individualAtRisk));
112
            } else {
87
            } else {
113
                System.out.println("This individual is not considered, as it is not of type system software or file: " + individualInOriginalModel.getIRI());
88
                System.out.println("This individual is not considered, as it is not of type system software or file: " + individualInOriginalModel.getIRI());
114
                continue;
115
            }
89
            }
116
117
        }
90
        }
118
        System.out.println(String.format("Returning %d alternatives.", alternatives.size()));
91
        System.out.println(String.format("Returning %d alternatives.", alternatives.size()));
119
        return alternatives;
92
        return alternatives;
120
    }
93
    }
121
94
122
    private void addFileAlternatives(String baseURL, String identifier, ArrayList<PreservationAlternative> alternatives, OwlApiFacade originalModelFacade, Risk identifiedRisk, IRI individualAtRisk) throws OWLOntologyCreationException, OWLOntologyStorageException, IOException, OwlElementNotFoundException {
123
        System.out.println("Searching for file alternatives...");
124
        List<FormatMigrationOption> alternativeFormats = getAlternativeFormats(originalModelFacade, individualAtRisk);
125
        AlternativesBuilder alternativesBuilder = new AlternativesBuilder(originalModelFacade);
126
        for (int i = 0; i < alternativeFormats.size(); ++i) {
127
            String formatName = alternativeFormats.get(i).getFormat();
128
            String toolName = alternativeFormats.get(i).getTool();
129
            System.out.println(String.format("Replacing %s with %s using %s.", individualAtRisk, formatName, toolName));
130
            String alternativeOntologyIri = createIriFragment(baseURL, identifier, identifiedRisk, i);
131
            OwlApiFacade modifiedModel = new OwlApiFacade(alternativesBuilder.copyOntology(IRI.create(alternativeOntologyIri, originalModelFacade.getOntology().getOntologyID().getOntologyIRI().getFragment())));
132
133
            OWLNamedIndividual individual = modifiedModel.addIndividual(formatName + "_file", IRI_FILE.toString());
134
            OWLNamedIndividual objectCharacteristics = modifiedModel.addIndividual(formatName + "Characteristics", IRI_OBJECT_CHARACTERISTICS.toString());
135
            modifiedModel.addObjectProperty(individual, IRI_OBJECT_CHARACTERISTICS_PROPERTY.toString(), objectCharacteristics);
136
            OWLNamedIndividual format = modifiedModel.addIndividual(formatName + "Format");
137
            modifiedModel.addObjectProperty(objectCharacteristics, IRI_FORMAT_PROPERTY.toString(), format);
138
            OWLNamedIndividual formatRegistry = modifiedModel.addIndividual(formatName + "FormatRegistry", IRI_FORMAT_REGISTRY.toString());
139
            modifiedModel.addObjectProperty(format, IRI_FORMAT_REGISTRY_PROPERTY.toString(), formatRegistry);
140
            modifiedModel.addDataProperty(formatRegistry, IRI_FORMAT_REGISTRY_NAME_PROPERTY.toString(), OWLManager.getOWLDataFactory().getOWLLiteral("http://www.nationalarchives.gov.uk/PRONOM/"));
141
            List<String> pronom_ids = knowledgeBase.getFormatIDs(formatName);
142
            for (String pronom_id: pronom_ids) {
143
                modifiedModel.addDataProperty(formatRegistry, IRI_FORMAT_REGISTRY_KEY_PROPERTY.toString(), OWLManager.getOWLDataFactory().getOWLLiteral(pronom_id));
144
            }
145
            if (pronom_ids.isEmpty()) {
146
                modifiedModel.addDataProperty(formatRegistry, IRI_FORMAT_REGISTRY_KEY_PROPERTY.toString(), OWLManager.getOWLDataFactory().getOWLLiteral("fmt/null"));
147
            }
148
            // TODO: copy relations
149
            // TODO: remove original individual
150
151
            // TODO: add converting tool to the changes ontology!
152
            IRI changesOntologyIri = IRI.create(IRIPREFIX_CHANGES + identifier + "/" + i);
153
            OWLOntology eventsOntology = createChangesOntology(
154
                    changesOntologyIri, originalModelFacade.getOntology(), originalModelFacade.getIndividual(individualAtRisk.toString()),
155
                    modifiedModel.getOntology(), individual, "FileReplacement");
156
            alternatives.add(new PreservationAlternative(
157
                    originalModelFacade.toOwlXml(), modifiedModel.toOwlXml(),
158
                    OwlApiFacade.toOwlXml(eventsOntology), identifiedRisk.getRiskIdentifier(), new ArrayList<String>()));
159
160
        }
161
        // TODO: avoid duplicate filecharacteristics and registries somehow
162
    }
163
164
    private void addToolAlternatives(String baseURL, String identifier, ArrayList<PreservationAlternative> alternatives, OwlApiFacade originalModelFacade, Risk identifiedRisk, String affectedResourceName, OWLNamedIndividual individualInOriginalModel) throws OWLOntologyStorageException, OWLOntologyCreationException, IOException, OwlElementNotFoundException {
165
        List<String> alternativeTools = getAlternativeTools(originalModelFacade, affectedResourceName);
166
        if (alternativeTools.size() < 1) {
167
            System.out.println("No alternatives found for risk: " + identifiedRisk.getRiskIdentifier());
168
            System.out.println("Using fake alternatives for test purposes...");
169
            for (int i = 0; i < 3; ++i) {
170
                System.out.println("Replacing identified software " + affectedResourceName);
171
                String replacingIndividual = affectedResourceName + "-replacement_" + i;
172
173
                String alternativeOntologyIri = createIriFragment(baseURL, identifier, identifiedRisk, i);//, originalModel.getOntologyID().getOntologyIRI());
174
                IRI changesOntologyIri = IRI.create(IRIPREFIX_CHANGES + identifier + "/" + i);
175
                alternatives.add(createAlternativeOntology(originalModelFacade.getOntology(), identifiedRisk,
176
                        individualInOriginalModel, replacingIndividual, alternativeOntologyIri, changesOntologyIri));
177
            }
178
        } else {
179
            for (int i = 0; i < alternativeTools.size(); ++i) {
180
                System.out.println("Replacing identified software " + affectedResourceName);
181
                String alternativeOntologyIri = createIriFragment(baseURL, identifier, identifiedRisk, i);//, originalModel.getOntologyID().getOntologyIRI());
182
                IRI changesOntologyIri = IRI.create(IRIPREFIX_CHANGES + identifier + "/" + i);
183
                alternatives.add(createAlternativeOntology(originalModelFacade.getOntology(), identifiedRisk,
184
                        individualInOriginalModel, alternativeTools.get(i), alternativeOntologyIri, changesOntologyIri));
185
            }
186
        }
187
    }
188
189
    private IRI findIndividual(OwlApiFacade originalModelFacade, String affectedResourceName) throws OwlElementNotFoundException {
190
        return originalModelFacade.findIndividualByFragmentAndLabel(affectedResourceName);
191
    }
192
193
    private List<String> getAlternativeTools(OwlApiFacade originalModelFacade, String affectedResourceName) throws OWLOntologyStorageException, OWLOntologyCreationException, IOException {
194
        // get alternatives based on the tool
195
        List<String> alternativeTools = knowledgeBase.getAlternativeTools(affectedResourceName);
196
        // get alternatives based on the formats
197
        JenaQueryFacade originalModelQueryFacade = new JenaQueryFacade(originalModelFacade.getJenaModel(false));
198
        List<Pair<String, String>> formatPairs = convertToIDs(originalModelQueryFacade.query(QueryHelper.getQueryFormatPairs(affectedResourceName)), originalModelQueryFacade);
199
        for (Pair<String, String> formatPair : formatPairs) {
200
            alternativeTools.addAll(JenaQueryFacade.removeNamespace(knowledgeBase.getSupportingTools(formatPair)));
201
        }
202
        return alternativeTools;
203
    }
204
205
    private List<FormatMigrationOption> getAlternativeFormats(OwlApiFacade originalModelFacade, IRI fileAtRisk) throws OWLOntologyStorageException, OWLOntologyCreationException, IOException {
206
        // get alternatives based on the tool
207
        JenaQueryFacade queryFacade = new JenaQueryFacade(originalModelFacade.getJenaModel(false));
208
        List<String> pronomIDs = JenaQueryFacade.extractColumn(queryFacade.query(QueryHelper.getQueryGetFormatID(fileAtRisk.toString())), "pronom_id");
209
        List<FormatMigrationOption> alternativeTools = knowledgeBase.getConvertToMigrationOptions(pronomIDs.get(0)); // TODO: also get ConvertFromMigrationOptions!
210
        System.out.println("Alternative options found: " + alternativeTools);
211
        return alternativeTools;
212
    }
213
214
    private PreservationAlternative createAlternativeOntology(OWLOntology originalModel,
215
                                                              Risk identifiedRisk, OWLNamedIndividual individualInOriginalModel,
216
                                                              String replacingIndividual, String alternativeOntologyIriPrefix, IRI changesOntologyIri) throws OWLOntologyCreationException, OwlElementNotFoundException, OWLOntologyStorageException {
217
218
        AlternativesBuilder alternativesBuilder = new AlternativesBuilder(new OwlApiFacade(originalModel));
219
        OWLOntology modifiedModel = alternativesBuilder.copyOntology(IRI.create(alternativeOntologyIriPrefix, originalModel.getOntologyID().getOntologyIRI().getFragment()));
220
        OWLOntologyManager modifiedModelOntologyManager = modifiedModel.getOWLOntologyManager();
221
222
223
        IRI individualInModifiedModelModifiedIRI = null;
224
        if (originalModel.containsIndividualInSignature(individualInOriginalModel.getIRI())) {
225
            individualInModifiedModelModifiedIRI = renameIndividual(individualInOriginalModel, replacingIndividual, modifiedModel);
226
        }
227
        List<String> changedOntologies = new ArrayList<String>();
228
229
        for (OWLOntology ontology : originalModel.getDirectImports()) {
230
            if (!ontology.containsIndividualInSignature(individualInOriginalModel.getIRI())) continue;
231
232
            AlternativesBuilder alternativesBuilderImportedOntology = new AlternativesBuilder(new OwlApiFacade(ontology));
233
            OWLOntology modifiedOntology = alternativesBuilderImportedOntology.copyOntology(
234
                    IRI.create(alternativeOntologyIriPrefix, ontology.getOntologyID().getOntologyIRI().getFragment()),
235
                    modifiedModel.getOWLOntologyManager()
236
            );
237
            individualInModifiedModelModifiedIRI = renameIndividual(individualInOriginalModel, replacingIndividual, modifiedOntology);
238
239
            modifiedModelOntologyManager.applyChange(new RemoveImport(modifiedModel,
240
                    modifiedModelOntologyManager.getOWLDataFactory().getOWLImportsDeclaration(ontology.getOntologyID().getOntologyIRI())));
241
            modifiedModelOntologyManager.applyChange(new AddImport(modifiedModel,
242
                    modifiedModelOntologyManager.getOWLDataFactory().getOWLImportsDeclaration(modifiedOntology.getOntologyID().getOntologyIRI())));
243
            changedOntologies.add(ontologyToXMLString(modifiedOntology));
244
        }
245
246
        OWLNamedIndividual modifiedIndividual = modifiedModelOntologyManager.getOWLDataFactory().getOWLNamedIndividual(individualInModifiedModelModifiedIRI);
247
248
        OWLOntology eventsOntology = createChangesOntology(changesOntologyIri, originalModel, individualInOriginalModel, modifiedModel, modifiedIndividual, "SoftwareReplacement");
249
        return new PreservationAlternative(
250
                ontologyToXMLString(originalModel), ontologyToXMLString(modifiedModel),
251
                ontologyToXMLString(eventsOntology), identifiedRisk.getRiskIdentifier(), changedOntologies);
252
    }
253
254
    private String createIriFragment(String baseURL, String identifier, Risk identifiedRisk, int count) {
255
        return baseURL + "/" + identifier + "/" + identifiedRisk.getRiskIdentifier()
256
                + "/" + count + "/";
257
    }
258
259
260
    private OWLOntology createChangesOntology(IRI iri, OWLOntology originalModel, OWLNamedIndividual individualInOriginalModel, OWLOntology modifiedModel, OWLNamedIndividual individualInModifiedModel, String replacementName) {
261
        // Finally, create the ontology that contains the PREMIS events
262
        OWLOntology eventsOntology = new OWLOntologyImpl(modifiedModel.getOWLOntologyManager(),
263
                new OWLOntologyID(iri));
264
        OWLOntologyManager eventsOntologyManager = eventsOntology.getOWLOntologyManager();
265
        OWLDataFactory eventsDataFactory = eventsOntologyManager.getOWLDataFactory();
266
267
        // import PREMIS OWL
268
        eventsOntologyManager.applyChange(new AddImport(eventsOntology,
269
                eventsDataFactory.getOWLImportsDeclaration(IRI_PREMIS)));
270
        eventsOntologyManager.applyChange(new AddImport(
271
                eventsOntology,
272
                eventsDataFactory.getOWLImportsDeclaration(originalModel.getOntologyID().getOntologyIRI())));
273
        eventsOntologyManager.applyChange(new AddImport(
274
                eventsOntology,
275
                eventsDataFactory.getOWLImportsDeclaration(modifiedModel.getOntologyID().getOntologyIRI())));
276
277
        // Make a new event individual
278
        OWLNamedIndividual eventIndividual = eventsDataFactory.getOWLNamedIndividual(IRI.create(
279
                iri.getNamespace(), replacementName));
280
        OWLClassAssertionAxiom eventClassAxiom = eventsDataFactory.getOWLClassAssertionAxiom(
281
                PREMIS_EVENT_CLASS, eventIndividual);
282
        eventsOntologyManager.applyChange(new AddAxiom(eventsOntology, eventClassAxiom));
283
284
        // Link the event individual to the entities
285
        OWLObjectPropertyAssertionAxiom linkingSourceObjectPropertyAxiom = eventsDataFactory.getOWLObjectPropertyAssertionAxiom(
286
                PREMIS_LINKING_SOURCE_OBJECTPROPERTY, eventIndividual, individualInOriginalModel,
287
                EMPTY_OWL_ANNOTATIONS);
288
        eventsOntologyManager.applyChange(new AddAxiom(eventsOntology, linkingSourceObjectPropertyAxiom));
289
        OWLObjectPropertyAssertionAxiom linkingOutcomeObjectPropertyAxiom = eventsDataFactory.getOWLObjectPropertyAssertionAxiom(
290
                PREMIS_LINKING_OUTCOME_OBJECTPROPERTY, eventIndividual, individualInModifiedModel,
291
                EMPTY_OWL_ANNOTATIONS);
292
        eventsOntologyManager.applyChange(new AddAxiom(eventsOntology,
293
                linkingOutcomeObjectPropertyAxiom));
294
        return eventsOntology;
295
    }
296
297
    private IRI renameIndividual(OWLNamedIndividual individualInOriginalModel, String replacingIndividual, OWLOntology modifiedModel) throws OwlElementNotFoundException {
298
        OwlApiFacade model = new OwlApiFacade(modifiedModel);
299
        IRI sourceIRI = model.createIri(OwlApiFacade.getFragment(individualInOriginalModel.getIRI()));
300
        if (!model.containsIndividual(sourceIRI.toString())) {
301
            throw new PreservationIdentifierException("Original individual not found in modified model: " + sourceIRI);
302
        }
303
304
        AlternativesBuilder alternativesBuilder = new AlternativesBuilder(model);
305
        alternativesBuilder.renameIndividualByIRI(model.createIri(OwlApiFacade.getFragment(individualInOriginalModel.getIRI())), replacingIndividual); // TODO: not sure why fragment only does not work... bug!
306
307
        IRI targetIRI = model.createIri(replacingIndividual);
308
        if (!model.containsIndividual(targetIRI.toString())) {
309
            throw new PreservationIdentifierException("Modified individual not found in modified model: " + targetIRI);
310
        }
311
        System.out.println("\tReplaced " + sourceIRI + " with " + targetIRI);
312
313
        return targetIRI;
314
    }
315
316
    public static String ontologyToXMLString(OWLOntology ontology) {
317
        StringDocumentTarget stringDocumentTarget = new StringDocumentTarget();
318
        try {
319
            OWLManager.createOWLOntologyManager().saveOntology(ontology, new OWLXMLOntologyFormat(),
320
                    stringDocumentTarget);
321
        } catch (OWLOntologyStorageException e) {
322
            e.printStackTrace();
323
        }
324
        return stringDocumentTarget.toString();
325
    }
326
327
    private List<Pair<String, String>> convertToIDs(List<QuerySolution> query, final JenaQueryFacade queryFacade) {
328
        return convert(query, new Converter<QuerySolution, Pair<String, String>>() {
329
            public Pair<String, String> convert(QuerySolution solution) {
330
                return new ImmutablePair<String, String>(getID(solution, "readFormat", queryFacade), getID(solution, "writeFormat", queryFacade));
331
            }
332
        });
333
    }
334
335
    private String getID(QuerySolution solution, String formatIndex, JenaQueryFacade queryFacade) {
336
        String format = solution.contains(formatIndex) ? solution.get(formatIndex).toString() : null;
337
        if (format == null) return null;
338
        List<String> pronomIDs = JenaQueryFacade.extractColumn(queryFacade.query(QueryHelper.getQueryGetFormatID(format)), "pronom_id");
339
        return (pronomIDs.size() > 0 ? pronomIDs.get(0) : format);
340
    }
341
}
95
}