2014-03-28 24 views
2

我一直在尋找一個解決方案,現在天,因爲沒有論壇在Apache Jena我不得不在stackoverflow創建一個帳戶問。
我的問題是我需要一個已經加載的本體的臨時(深層)副本,即OntModelImpl(帶有一些導入但沒有任何附加的推理機)的對象。其目的是在模型上應用一些驗證步驟,這些步驟需要一些SPARQL UPDATE查詢來首先添加一些自動生成的三元組。這些額外的三元組僅用於驗證,不應該找到原來的模型!
對象本身沒有複製或克隆方法,通過我的許多搜索,我無法在其他任何地方找到任何靜態(?)方法來實現此目的。相反,在OntModelImpl上有某種「複製構造函數」(沒有真正標記爲這樣),它需要一個規範(OntModelSpec)和一個Model。我試圖用這種方式:如何克隆或複製Jena-Ontology-Model(OntModel)以應用臨時更改?

workingModel = new OntModelImpl(ontModel.getSpecification(), ontModel); 

哪裏ontModel是先前通過的JenaOWLModel.getOntModel()調用創建了一個OntModelImplJenaOWLModel本身是Protégé-3-API的一部分,並且是通過致電OwlProjectFromReaderCreator.getOwlModel()創建的。這個創建者(連同必要的存儲庫)被用來加載原始本體和其導入。 workingModel表示我正在創建的工作副本。
顯示的代碼行的最初問題是它會拋出多個DoesNotExistException s,下面有十幾個或更多的調用級別。這些表示無法找到導入本體?正如我之前提到的,原始模型已經加載,包括所有導入。 (我跳過一些細節這裏來縮短故事。)
後來我發現,我可以通過構造函數調用之前設置

ontModel.getSpecification().getDocumentManager().setProcessImports(false); 

抑制例外。從這一點看,一切都很好,沒有例外,我得到了兩個不同的模型對象,它們在不同的圖中具有相同的三重計數(我對OntModelImpl這兩個實例的所有第一和第二級屬性的對象ID進行了快速比較,確保它是一個深層複製)。但是今天我意識到了一些奇怪的事情:第一次添加驗證三元組時沒有問題 - 我在SPARQL-UPDATE-INSERT請求之前和之後將三重計數寫入stdout。但是當我第二次調用驗證時,原始模型確實已經包含額外的三元組!?
這意味着要麼兩個模型以某種方式鏈接,我看不到或者耶拿使用某種全局鏈接 - 也許緩存機制我不知道哪個嘗試保持具有相同URI的所有模型彼此一致或完全不同的東西。

所以我真的需要幫助!如何獲得OntModelOntModelImpl)的副本以應用我想在之後丟棄的臨時更改?

的問候,並感謝您的時間

+1

問這裏沒什麼錯,但既然你提到「Apache jena沒有論壇」,值得指出的是,有一個相當敏感的用戶郵件列表。 –

+0

是的,我已閱讀關於支持列表的內容,但我不喜歡這種「封閉式通信」(我已閱讀它之後發佈)。他們還指出了「關於StackOverflow的耶拿問題集合」,所以我來到了這裏。此外,谷歌在過去的每一個問題都帶我來到這裏 - 而且從未去過我第一次看到的耶拿郵件存檔(這是不是Google的索引?)。 - 因此,自從 – user3471872

+0

以後,我多次來到這裏閱讀其他人的問題和答案(不僅對Jena,我承認),我認爲別人也會這樣。 – user3471872

回答

0

如何使Model的深層副本:

Model copyOfOntModel = ModelFactory.createModelForGraph(ontModel.getGraph()); 

然後用這個實例化新OntModelImpl

workingModel = new OntModelImpl(ontModel.getSpecification(),copyOfOntModel); 
0

的來自@ dr0i的回答並不適合我。

這工作: Model copy = ModelFactory.createDefaultModel().add(originalModel);

ModelFactory創建Model亞類:createInfModel()createOntologyModel()

我使用以下邏輯進行測試。

int size = originalModel.size(); 
Model copy = ModelFactory.createDefaultModel().add(originalModel); 
copy.removeAll(); 
assert originalModel.size() == size; 
+0

感謝您的回覆。我現在沒有在本體上工作(將近三年後),但我已經看到,你所顯示的邏輯並不能證明已經創建了一個深層複製(只是「複製」不僅僅引用了原文)。 - 你驗證過了嗎? 您至少應該在原件上調用'removeAll()',然後將其舊尺寸與副本尺寸進行比較。這應該顯示兩個模型的大小相同。 – user3471872

+0

是的,比較的工作原理也是如此:'originalModel.removeAll()'不影響'copy'。 – jaco0646