|
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 |
}
|