Professional Documents
Culture Documents
PluginAnatomyProtegeWiki
FromProtegeWiki
Contents
1Introduction
2Thevacuousplugininfiveminutes
2.1Build.xml
2.2MANIFEST.MF
2.3CompileandRun
3WritingViewandTabPlugins
3.1AddingaViewPlugintothePlugin.xmlfile
3.2LibrariesandtheBundleClasspath
3.3TabPluginsandtheViewconfig.xmlFile
3.3.1Step1:Declaretheplugin
3.3.2Step2:Layouttheviewsintheplugin
3.3.3Step3:Saveaconfigurationfile
3.3.4Step4:Testtheresults
4AddingMenuPlugins
5UsingaReasoner
6AdvancedTopics
6.1AddingNewPluginTypes
6.1.1ThePluginConsumer
6.1.2ThePluginLoader
6.1.3ThePlugin
6.1.4ThePluginInstance
6.2Frames,FrameSections,andRows
6.2.1FrameListsandFrames
6.2.2FrameSections
6.2.3FrameSectionRows
7Glossary
Introduction
Thepurposeofthiswebpageistodescribesomeofthekeyingredientsofaplugin.Thepagewillbedirectedbythequickdevelopmentofapluginandcanindeedbeused
asaquickstartguide.InordertofocusattentiononthecorepluginconceptswewillusethelowestcommondenominatorofJavadevelopmenttoolsandthistutorialwill
notuseaJavaIDE.WewillassumethatthereaderhasanunderstandingofJavadevelopmentandknowshowtofollowalonginhisfavoriteIDE.Formoreinformation
abouthowtoworkwithprotege4inanIDEIwilldirectthereadertothispage.Itispossibleforanexperienceddevelopertoskiptheantscriptssimplyfollowalonginan
IDEbutwewouldstillrecommendabuildfileforthefinalversion.
Thesourcesforthefirstplugin(theexampletab)canbefoundhere(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/plugin/trunk/org.protege.editor.owl.examples.tab).Youcaneitherchecktheseoutfromsvnandusethisasa
guideforreadingthetextorbuildthisprojectinaseriesofstepbystepstagesasdescribedbelow.Ifyoustartfromthecheckedoutversionthenyoucanbuildtheproject
byfollowingthedirectionshere.
Thevacuousplugininfiveminutes
Icreateda(vacuous)pluginfromscratch,installeditandranitinjustunderfourminutes.ThereisalsoanewexpereimentalquickstartguideforstartinganewProtege5
pluginwithmavenwhichwillprobablyevolveintothenewrecommendedstrategy.
Thesimplest(trivial)plugincanbebuiltfromsourcesinthefollowinglayout:
build.xml
METAINF
MANIFEST.MF
lib
resources
src
AswewillseeevenwithoutanyjavasourcesthisisasufficientbasisforbuildingapluginthatisrecognizedbyProtege4.Thereareonlytwofilesinthissourcetree
thebuild.xmlfileandtheMANIFEST.MF.Thesefilescanbequicklyputtogetherfromtemplates.
Build.xml
Thetemplateforthebuild.xmlfilecanbedownloadedfromhere(http://smiprotege.stanford.edu/repos/protege/protege4/protegebase/trunk/etc/templatepluginbuild.xml)
.Onlytwothingsneedtobechangedinthisbuildfile.Theycanbefoundbysearchingforthestring"CHANGEME"inthefile.Thefirstthingtochangeisthenameofthe
project.Iwillcalltheprojecttheplugintutoiralproject:
<projectname="plugintutorial"default="install"basedir=".">
Thenextsettingthatmustalmostalwaysbechangedisthenameoftheplugin.Inthiscase,thebuild.xmlalreadyhastherightnameforthepluginbutthisistheonlyplugin
forwhichthiswillbetrue:
<propertyname="plugin"value="org.protege.editor.owl.examples.tab"/>
Withtheseadjustmentsthebuild.xmlfileisready.
MANIFEST.MF
ThetemplatefortheMANIFEST.MFfilecanbedownloadedfromhere(http://smiprotege.stanford.edu/repos/protege/protege4/protegebase/trunk/etc/template
manifest.mf).Onlyfivethingsneedtobechangedinthisfiletomakeituseableandtwoareoptional.Thesecanbefoundbysearchingforthestring"CHANGEME"inthe
file.Thefirstchangeistosetthedisplaynamefortheplugin:
BundleName:TutorialPlugin
ThisisthenamethatisseenwhenProtege4startsupandinseveralpluginconfigurationscreens.Theseccondthingtochangeisthesymbolicnameoftheplugin.Theusual
defaultistousesthesamenameasthepluginnameinthebuild.xmlfile:
BundleSymbolicName:org.protege.editor.owl.examples.tab;singleton:=true
Notethe"singleton:=true"linethisisimportantsincemostProtege4pluginswillonlyworkiftheyareinstantiatedexactlyonce.Thenextthingstochangearethebundle
description,thevendorandthedocumentationurl:
BundleDescription:Asimplepluginforaplugindevelopmenttutorial
BundleVendor:TheProtegeDevelopmentTeam
BundleDocURL:www.perhaps.i.donthaveoneyet.com
Actuallythevendorandthedocurlareoptionalandcanbedeleted.TheMANIFEST.MFfileisnowready.
http://protegewiki.stanford.edu/wiki/PluginAnatomy
1/11
2/11/2016
PluginAnatomyProtegeWiki
CompileandRun
Beforewecanstart,wemustsetthePROTEGE_HOMEenvironmentvariabletopointtoaProtege4distribution.Thispagehasdirectionsonhowtodothisindifferent
operatingsystemsbutfornowIwillassumethatweareonaunix(orosx)system.Inthatcase,thesystemvariablecanbesetwithasimplecommand
exportPROTEGE_HOME=/Users/tredmond/Desktop/Protege_4.1_beta
Thisvacuouspluginisnowreadytocompileandrun.AssumingthatthePROTEGE_HOMEenvironmentvariableissetcorrectly,thisplugincanbecompiledwiththe
simplecommand
antinstall
Thefulltextofthebuildsessionisasfollows:
[tredmond@Andromedaorg.protege.editor.owl.examples.tab]$antinstall
Buildfile:build.xml
init:
[mkdir]Createddir:/private/tmp/org.protege.editor.owl.examples.tab/build
[mkdir]Createddir:/private/tmp/org.protege.editor.owl.examples.tab/build/classes
[mkdir]Createddir:/private/tmp/org.protege.editor.owl.examples.tab/build/classes/lib
[mkdir]Createddir:/private/tmp/org.protege.editor.owl.examples.tab/build/lib
checkProtegeLibs:
[echo]UsingProtegeHome=/Andromeda/Users/tredmond/dev/workspaces/protege4/owleditor/build/dist/equinoxtofindprotegejars
checkProtegeLibsAndReport:
buildlibs:
[unjar]Expanding:/Andromeda/Users/tredmond/dev/workspaces/protege4/owleditor/build/dist/equinox/bundles/org.protege.common.jarinto/private/tmp/org.protege.editor.owl.examples.tab/build
compile:
build.manifest:
[copy]Copying1fileto/private/tmp/org.protege.editor.owl.examples.tab/build
copy.resources:
[mkdir]Createddir:/private/tmp/org.protege.editor.owl.examples.tab/build/classes/METAINF
[copy]Copying1fileto/private/tmp/org.protege.editor.owl.examples.tab/build/classes/METAINF
jar:
[jar]Buildingjar:/private/tmp/org.protege.editor.owl.examples.tab/build/org.protege.editor.owl.examples.tab.jar
install:
[delete]Deletingdirectory/Andromeda/Users/tredmond/dev/workspaces/protege4/owleditor/build/dist/equinox/configuration/org.eclipse.core.runtime
[delete]Deletingdirectory/Andromeda/Users/tredmond/dev/workspaces/protege4/owleditor/build/dist/equinox/configuration/org.eclipse.osgi
[copy]Copying1fileto/Andromeda/Users/tredmond/dev/workspaces/protege4/owleditor/build/dist/equinox/plugins
BUILDSUCCESSFUL
Totaltime:2seconds
[tredmond@Andromedaorg.protege.editor.owl.examples.tab]$
IfthePROTEGE_HOMEenvironmentvariableisnotsetcorrectlytheuserwillinsteadseethefollowing:
BUILDFAILED
/private/tmp/org.protege.editor.owl.examples.tab/build.xml:74:missingprotegelibraries
Wecannowlookatwhatthebuildhasdonebyexploringtheprojectdirectorytree.
Weseethefollowingelements:
TheClassTreeis(approximately)aflattenedviewoftheplugin(thejarfile).Generallythislargelyconsistsofthe.classfilesthathavebeencompiledfromthejava.
Butsincewehavenotwrittenanyjavayetthisisnotfound.Inaddition,thiswillcontainresourcesneededbythepluginandlibrariesthatthepluginneedsbutwhich
cannotbefoundinotherProtegeplugins.
TheGeneratedLibrarieswhichareextractedfromProtegeplugins.ThisisneededbecauseofadifferencebetweenhowJavaandOSGigetresourcesoutofJar
files.OSGiallowsabundle(whichisaimplementedasajarfile)tocontainotherjarfiles.Ifthebundleclasspathisconfiguredcorrectly,OSGiwillloadclassesfrom
thosejarsinjars.ButJavadoesnothavethiscapability.SothebuildscriptextractsthejarfilesoutoftheOSGibundlesthatwillbeneededtocompilethebundle.
NotethatthesejarfilesarenotcopiedtotheclasstreebecausetheProtege4/OSGienvironmentwillmaketheclassesandresourcesofthesejarfilesavailable.
TheProtege4Pluginthisisthefinalartifactofthebuildprocess.Becausewehaverun"antinstall"ithasalsobeeninstalledintheProtegedistribution.
Ifthedeveloperisstillwithmethenheisnowreadytoruntheplugin.GototheProtegedistribution(theonepointedtobythePROTEGE_HOMEenvironmentvariable)
andrunit.Weareparticularlyinterestedintheconsoleoutputbecausethisisgoingtobetheonlyindicationthatthispluginisrecognizedatall.Theconsoleoutputshould
looklikethis:
StartingProtege4OWLEditor(Version4.1.111)
Platform:
Java:JVM1.5.0_16b06284Memory:207M
Language:en,Country:US
Framework:Eclipse(1.4.0)
OS:MacOSX(10.5.6)
Processor:ppc
InstalledpluginPelletReasoner
InstalledpluginDLQueryTab
InstalledpluginOwlvizPlugin
Installedpluginowleditor
InstalledpluginTutorialPlugin
InstalledpluginTheOWLAPI
InstalledpluginFactplusplusPlugin
TutorialPluginPluginhasnoplugin.xmlresource
InthisoutputweseethattheTutorialPluginhasbeenrecognizedandinstalled.Inadditionthereisainformationalmessagethattheplugin.xmlfilehasnotbeenfound.This
isalmostalwaysindicatesaproblembecausemostProtege4pluginsdependonaplugin.xmlresource.Wewilldescribehowtheplugin.xmlfileisgeneratedinthenext
sections.
http://protegewiki.stanford.edu/wiki/PluginAnatomy
2/11
2/11/2016
PluginAnatomyProtegeWiki
WritingViewandTabPlugins
ThepreviouspluginaddednofunctionalitytoProtege4.Wearenowgoingtodescribehowtoremedythissitutaion.SofarwehavenotmissedtheJavaIDEbutitisnow
whenwestartwritingabitofJavacodethattheJavaIDEwouldreallyshine.Buttoillustratethemainconcepts,wewillcontinuetoshowhowtobuildthepluginwithout
anydevelopmentenvironmentotherthanthatprovidedbythecoreJavatools.
AddingaViewPlugintothePlugin.xmlfile
Recallthatpreviouslywhenweranourplugin,Protege4complainedthattherewasnoplugin.xmlfile.Theplugin.xmlfilecontainsadeclarationofthewaysinwhichthe
pluginwillextendtheProtege4capabilitiesand(moreadvanced)thewaysinwhichtheplugincapabilitiescanbeextendedbyotherplugins.Wewillstartbyaddinga
declarationthatthispluginwillimplementaProtegeView.
SofirstwewillgiveadefinitionofaProtegeview.ThepurposeofaProtegeviewistoprovideaviewofsomeaspectofanontology.IntheProtegeinterface,aProtege
viewiseasilyrecognized.Ithasaclearlydefinedborder.AtthetopofaProtegeviewisatitlebarandacollectionofbuttonsallowingtheuserto
splittheprotegeviewintotwocopiesofthesameviewoneabovetheother,
splittheprotegeviewintotwocopiesofthesameviewonebesidetheother,
floattheviewabovetheProtegeclientsothatitisvisibleinanycontext,
closetheviewremovingitfromthetabthatcontainsit.
AnexampleofatypicalProtegeviewisshownbelow.
InordertodeclareourintentthatthispluginimplementaProtegeview,weaddthefollowingplugin.xmlfiletotherootoftheprojecttree:
<?xmlversion="1.0"encoding="UTF8"standalone="no"?>
<?eclipseversion="3.0"?>
<plugin>
<extensionid="ExampleViewComponent"
point="org.protege.editor.core.application.ViewComponent">
<labelvalue="ExampleViewComponent"/>
<classvalue="org.protege.editor.owl.examples.tab.ExampleViewComponent"/>
<categoryvalue="@org.protege.ontologycategory"/>
</extension>
</plugin>
Thisplugin.xmlfilestatesthatthispluginismakingasingleextensiontotheProtege4capabilities.Wewillcoverthemeaningofthepartsofthisextensiondeclarationline
byline.Thefirstlinedefinestheidoftheextension.ThisparticularextensioniscalledtheExampleViewComponent.Theseconddecleration,
point="org.protege.editor.core.application.ViewComponent",
stateswhattheextensionistryingtodo.Thisextensionisattemptingtoimplementthefunctionalityrepresentedbytheextensionpointwiththename
org.protege.editor.core.application.ViewComponent.
ThelabeldeclarationtellsProtegewhattoputinthetitlebaroftheview.Theclassdeclarationindicateswhichclassimplementsthefunctionalityneededbythisview.We
willgointotheimplementationofthatclassshortly.FinallythecategorydeclarationtellsProtegewhichmenuundertheViewmenushouldcontainthisview.
AverysimpleviewcanbewrittenbyextendingtheclassAbstractOWLViewComponentandimplementingthemethodsinitialiseOWLViewanddisposeOWLView.Avery
simplesuchimplementationcanbefoundhere(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/plugin/trunk/org.protege.editor.owl.examples.tab/src/org/protege/editor/owl/examples/tab/ExampleViewComponent.java)
.Nowthisplugindependsonalibrarythatcanbefoundhere(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/plugin/trunk/org.protege.editor.owl.examples.tab/lib/examplelib.jar).Thislibraryshouldbedepositedinthelib
directoryoftheproject.Thislibraryistrivialanditsonlypurposeistoshowhowtousealibraryinaplugin.Thedirectorytreeoftheprojectshouldnowlooklikethis:
http://protegewiki.stanford.edu/wiki/PluginAnatomy
3/11
2/11/2016
PluginAnatomyProtegeWiki
Atthispointtheantinstalloperationwillcompile,buildandinstallthenewpluginwiththe"antinstall"command.Buttheinstalledpluginwon'truncorrectlyandwewill
showhowtofixthisbelow.
LibrariesandtheBundleClasspath
Afterweinstalltheplugin,wecanstartProtegetotrytousethe"ExampleViewComponent".IfyouclickontheViewmenuandthenselect"OntologyViews"youwillsee
the"ExampleViewComponent"listedthere.HoweveronselectingthisviewandtryingtoplaceontheProtegescreen,thefollowingerrorwillarise:
Errorlogged
java.lang.NoClassDefFoundError:org/protege/owl/example/Metrics
atjava.lang.Class.getDeclaredConstructors0(NativeMethod)
atjava.lang.Class.privateGetDeclaredConstructors(Class.java:2357)
atjava.lang.Class.getConstructor0(Class.java:2671)
atjava.lang.Class.newInstance0(Class.java:321)
atjava.lang.Class.newInstance(Class.java:303)
...
Ifwelookattheplugincontentswiththe"jartf"commandthenwewillseethatthebuildfilecorrectlyputtheexamplelib.jarintotheplugin:
[tredmond@BlackHoleorg.protege.editor.owl.examples.tab]$jartfbuild/org.protege.editor.owl.examples.tab.jar
METAINF/
METAINF/MANIFEST.MF
lib/
org/
org/protege/
org/protege/owl/
org/protege/owl/examples/
org/protege/owl/examples/tab/
lib/examplelib.jar
org/protege/owl/examples/tab/ExampleViewComponent.class
plugin.xml
[tredmond@BlackHoleorg.protege.editor.owl.examples.tab]$
TheproblematthispointisintheMANIFEST.MFfile.TheBundleClasspathlineisasfollows:
BundleClassPath:.
Toincludetheexamplelib.jarinthejarfile,theBundleClasspathlinemustbemodifiedtoincludethislibrary:
BundleClassPath:.,lib/examplelib.jar
Notethatusingacolonorasemicoloninsteadofthecommadoesnotwork.Alsoentering./lib/examplib.jardoesnotworkeither.Thisistheosgimechanismformaking
thislibraryavailabletothisplugin.NotethatsincetheMANIFEST.MFfiledoesnothaveanExportPackagedeclaration,theseclasseswillonlybevisiblewithintheplugin
andwillnotbeexportedtoanyotherpluginintheProtege4environmeht.ThisispartofthepluginisolationprovidedbyOSGithatallowsdifferentpluginstousedifferent
librarieswithoutconflicts.
NowthepluginworkscorrectlyandIcaninstalltheviewintotheActiveOntologyTab:
TabPluginsandtheViewconfig.xmlFile
TheothermostcommonplugintypeistheProtegetab.InordertomakeaProtegetab,thedeveloperneedstogenerateanduseaviewconfig.xmlfilefortheproject.Inthis
sectionwewillshowhowtodothis.ItturnsoutthatatabcanusuallybeputtogetherwithoutwritinganyJavacode.Thestepsforwritingatabpluginare
1.addadeclarationofthetabpluginintheplugin.xmlfile.
2.startProtegeandgraphicallyconfigurethetabinquestion.
3.savetheconfigurationandincludeitwiththesourcefilesforthetab.
4.testbyrestartingProtegeandrunningthetabwiththedefaultconfiguration.
Thesestepsaredescribedinmoredetailbelow.
Step1:Declaretheplugin
Thefirstthingthatthatneedstobedoneistodeclarethetabintheplugin.xmlfile.
<?xmlversion="1.0"encoding="UTF8"standalone="no"?>
<?eclipseversion="3.0"?>
<plugin>
<extensionid="ExampleViewComponent"
point="org.protege.editor.core.application.ViewComponent">
<labelvalue="ExampleViewComponent"/>
<classvalue="org.protege.editor.owl.examples.tab.ExampleViewComponent"/>
<categoryvalue="@org.protege.ontologycategory"/>
http://protegewiki.stanford.edu/wiki/PluginAnatomy
4/11
2/11/2016
PluginAnatomyProtegeWiki
</extension>
<extensionid="ExampleWorkspaceTab"
point="org.protege.editor.core.application.WorkspaceTab">
<labelvalue="ExampleTab"/>
<classvalue="org.protege.editor.owl.ui.OWLWorkspaceViewsTab"/>
<indexvalue="X"/>
<editorKitIdvalue="OWLEditorKit"/>
<defaultViewConfigFileNamevalue="viewconfigexampleTab.xml"/>
</extension>
</plugin>
AnimportantlineintheabovedeclarationofthetabisthedefaultViewConfigFileName.Thisnamesaresourcethattheprotegepluginwilllookfortocreatethedefault
layoutofthetab.
Step2:Layouttheviewsintheplugin
Wecannowcompilethispluginandinstallitasbefore.NowwhenwerunProtege4,wewillseeanewtabcalledthe"ExampleTab"inthetabsmenu(Window>Tabs).
Enablethistab.SincewehavenotyetcreatedtheviewconfigexampleTab.xmlfile,youwillseethatthetabisempty.
Nowinstallandlayoutsomeviewsintothistab.InmycaseImadetheviewslooklikethis:
Step3:Saveaconfigurationfile
NowintheWindowmenuselect"ExportCurrentTab"andsavethefileas
viewconfigexampleTab.xml
intheprojectdirectory.InmycasetheviewconfigexampleTabfilelookedlikethis:
<?xmlversion="1.0"encoding="UTF8"?>
<layout>
<VSNodesplits="0.50.5">
<CNode>
<Componentlabel="Assertedclasshierarchy">
<Propertyid="pluginId"value="org.protege.editor.owl.OWLAssertedClassHierarchy"/>
</Component>
</CNode>
<CNode>
<Componentlabel="ExampleViewComponent">
<Propertyid="pluginId"value="org.protege.editor.owl.examples.tab.ExampleViewComponent"/>
</Component>
</CNode>
</VSNode>
</layout>
NowbeforewecompletethisProtegesession,gototheWindowmenuandclick"Resetselectedtabtodefaultstate".Youwillseethatthetabisnowemptyagain.Nowexit
Protege.
Thedirectorytreeoftheprojectshouldnowlooklikethis:
http://protegewiki.stanford.edu/wiki/PluginAnatomy
5/11
2/11/2016
PluginAnatomyProtegeWiki
Step4:Testtheresults
Installthepluginagain.NotethatthebuildscriptautomaticallyfoundtheviewconfigexampleTab.xmlfileandputitintotheplugin:
[tredmond@BlackHoleorg.protege.editor.owl.examples.tab]$jartfbuild/org.protege.editor.owl.examples.tab.jar
METAINF/
METAINF/MANIFEST.MF
lib/
org/
org/protege/
org/protege/owl/
org/protege/owl/examples/
org/protege/owl/examples/tab/
lib/examplelib.jar
org/protege/owl/examples/tab/ExampleViewComponent.class
plugin.xml
viewconfigexampleTab.xml
[tredmond@BlackHoleorg.protege.editor.owl.examples.tab]$
RunProtegeandgototheExampleTab.Itisempty?Thereasonforthisisthatthetabhasbeencustomizedtohavenothinginitfromthelastsession.Clickonthetabs
menuandclickon"Resetselectedtabtodefaultstate".Nowyouwillseetheviewsthatweconfiguredinthetabbefore.Thisisnowthedefaultstateforthetabanditwill
bewhatotherusersseewhentheyusethispluginforthefirsttime.
AddingMenuPlugins
Ihavecreatedasmallmenuprojecthere(http://smiprotege.stanford.edu/repos/protege/protege4/misc/examples/org.protege.example.menu/trunk)thatshowshowtocreate
severaldifferentmenutypes.Laterwewillusethisprojectastheexamplethatdrivesthiswikipage.
AddinganewmenutoProtege4.1isveryeasy.Thetwothingsthatthedeveloperneedstoaccomplisharetowritethecodeforthemenuactionandtoaddanentrytothe
plugin.xml.Iwilltakearealworldexampletoillustratetheprocess.Inthisexample,IamwritingapluginthatcausesProtegetodisplayanontologythatisstoredina
databaseformat.IwanttoputthisinthefilemenuofProtege4.1justunderotheritemssuchas"New","Open","OpenRecent"and"OpenfromURL".
Towritethecodeforthemenuplugin,thedevelopermerelyneedstoextendProtegeOWLAction.Thethreemethodsthatthedeveloperneedstowriteareinitialise,dispose
andactionPerformed.Ithinkthatthemeaningofthesethreemethodsisprettyclearandthiscanbeaveryeasytask.
Nowthedeveloperneedstoaddanentrytotheplugin.xml(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/org.protege.example.menu/trunk/plugin.xml)file.Inmycasetheentrylookslikethis:
<extensionid="loadDatabase"
point="org.protege.editor.core.application.EditorKitMenuAction">
<namevalue="LoadDatabaseOntology"/>
<classvalue="org.protege.owlapi.bridge.LoadDatabaseProjectMenu"/>
<toolTipvalue="LoadsontologiesfromadatabaseintoProtege"/>
<pathvalue="org.protege.editor.core.application.menu.FileMenu/SlotAAZ"/>
<editorKitIdvalue="OWLEditorKit"/>
</extension>
The"id"attributeofloadDatabaseissimplyashortidentifierforthepluginthatisnotseenbytheuser.The"point"attributeindicatesthatthepluginbeingdeclaredhereis
amenuplugin.The
<classvalue="org.protege.owlapi.bridge.LoadDatabaseProjectMenu"/>
lineindicatestheclassthatimplementstheactionthatthismenuperformsandthe
<editorKitIdvalue="OWLEditorKit"/>
lineindicatesthatthemenuistobeusedinthecontextoftheowleditor.Theonlyotherlineinthisplugin.xml(http://smi
protege/repos/protege/protege4/incubator/v3/org.protege.owlapi.bridge/trunk/plugin.xml)thatisabitmysteriousisthelinethatsays:
<pathvalue="org.protege.editor.core.application.menu.FileMenu/SlotAAZ"/>
Thepurposeofthislineistoindicateexactlywherethemenushouldbeplaced.Thefirstpartofthevalue,
org.protege.editor.core.application.menu.FileMenu
indicatesthattheparentofmy"LoadDatabaseOntology"menuisthefilemenu.Thestringismakingareferencetothefilemenudeclaration
<extension
id="menu.FileMenu"
name="FileMenu"
point="org.protege.editor.core.application.EditorKitMenuAction">
<namevalue="File"/>
<toolTipvalue="Filemenutooltip!"/>
<pathvalue="/SlotAA"/>
<editorKitIdvalue="any"/>
</extension>
fromtheplugin.xml(http://smiprotege/repos/protege/protege4/plugins/org.protege.editor.core.application/trunk/plugin.xml)filefortheorg.protege.editor.core.application
plugin.Thefirstpartofthestring
org.protege.editor.core.application.menu.FileMenu
is
org.protege.editor.core.application
whichistheidentifieroftheplugindeclaringthemenuand"menu.FileMenu"istheidofthepluginfromtheplugin.xmlfile.
ButnowIneedtoexplainthemeaningoftheSlotAAZportionofthepathinmyoriginalmenudeclaration:
<extensionid="loadDatabase"
point="org.protege.editor.core.application.EditorKitMenuAction">
<namevalue="LoadDatabaseOntology"/>
<classvalue="org.protege.owlapi.bridge.LoadDatabaseProjectMenu"/>
<toolTipvalue="LoadsontologiesfromadatabaseintoProtege"/>
<pathvalue="org.protege.editor.core.application.menu.FileMenu/SlotAAZ"/>
<editorKitIdvalue="OWLEditorKit"/>
</extension>
TheSlotAAZstringindicatesexactlywherethe"LoadDatabaseOntology"shouldappearintheFilemenu.Thisstring(SlotAAZ)isparsedasagroup(SlotAA)andan
index(Z).FirstthegroupandtheindexareusedtosortthechildrenoftheFilemenu.Thechildrenaresortedfirstbygroupbutwhentwochildrenhavethesamegroupthey
arethensortedbygroupindex.Inadditiontothis,childrenwiththesamegrouparegroupedtogetherinthemenu.
http://protegewiki.stanford.edu/wiki/PluginAnatomy
6/11
2/11/2016
PluginAnatomyProtegeWiki
Inparticular,ifItrackdownthedeclarationsofthe"New","Open","OpenRecent"and"OpenfromURL"menusIfindthattheyallhaveagroupidentifierofSlotAA.This
iswhytheyappearinthefilemenutogetherfollowedbyaseparatorbar.ByspecifyingthatmymenushouldhaveagroupofSlotAA,IamtellingProtegethatIwantmy
menutobegroupedwiththesemenus.BygivingmymenuanindexofZIamtellingProtegethatIwantmymenutogoattheendofthelist.
ThealgorithmusedbyProtegetodeterminethelocationoftheplugincanbeobservedbyturningonloggingforthemenubuilder.Thiscaneasilybedonebyeditingthe
log4j.xmlintheProtegeinstallationdirectory.Firstmodifythesectionthatsays
<appendername="console"class="org.apache.log4j.ConsoleAppender">
<paramname="Threshold"value="INFO"/>
<layoutclass="org.apache.log4j.PatternLayout">
<paramname="ConversionPattern"value="%m%n"/>
</layout>
</appender>
tosay
<appendername="console"class="org.apache.log4j.ConsoleAppender">
<paramname="Threshold"value="INFO"/>
<layoutclass="org.apache.log4j.PatternLayout">
<paramname="ConversionPattern"value="%m%n"/>
</layout>
</appender>
Thisallowstheconsoletoshowdebugmessages.Thenaddthelines
<categoryname="org.protege.editor.core.ui.menu">
<priorityvalue="debug"/>
</category>
ThiswillcauseProtegetogeneratesomewhatverboselogstotheconsole(theselogsalsoshowupinalogfilein${homedirectory}/.Protege/logs/protege###.log).The
relevantlinesformymenupluginareasfollows.First
Parsed:[Menu:LoadDatabaseOntology<SlotAA,Z>]parentId=org.protege.editor.core.application.menu.FileMenu
indicatesthatProtegewasabletoparsethepathformymenupluginanddeterminethattheidoftheparentis
org.protege.editor.core.application.menu.FileMenu
thegroupisSlotAAandthegroupindexisZ.Nextweseetheline
[Menu:File<SlotA,A>]parentof[Menu:LoadDatabaseOntology<SlotAA,Z>]
whichindicatesthatProtegewassuccessfullyabletofindadeclaredmenuwiththerightidtobetheparentofmymenu.ThislinealsoindicatesthatProtegesuccessfully
decipheredthegroup(SlotAA)andtheindex(Z).Finallytherearethelines:
Adding[Menu:File<SlotA,A>]tomenubar
GivingFilethechild[Menu:New...<SlotAA,E>]
GivingFilethechild[Menu:Open...<SlotAA,F>]
GivingFilethechild[Menu:Openrecent<SlotAA,G>]
GivingFilethechild[Menu:OpenfromURL...<SlotAA,G>]
GivingFilethechild[Menu:LoadDatabaseOntology<SlotAA,Z>]
GivingFilethechild[Menu:Save<SlotAB,A>]
GivingFilethechild[Menu:Saveas...<SlotAB,B>]
GivingFilethechild[Menu:Gatherontologies...<SlotAB,C>]
GivingFilethechild[Menu:Exportinferredaxiomsasontology...<SlotAB,D>]
GivingFilethechild[Menu:Ontologylibraries...<SlotD,A>]
GivingFilethechild[Menu:Loadedontologysources...<SlotD,B>]
GivingFilethechild[Menu:Checkforplugins...<SlotP,A>]
GivingFilethechild[Menu:Close<SlotY,M>]
thatindicatethattheFilemenuwassuccessfullypopulated.
UsingaReasoner
Usuallywhenapluginwantstouseareasoner,thepluginshouldusethereasonerthatisinitializedandusedbyProtege.ThisreasonercouldbetheFaCT++,HermiT,Pellet
orotherreasonersandisselectedandinitializedattheusersrequest.Toexplainhowthisworkswewillexplainhowthefollowing(nottoouseful)codefromamenuplugin
works.
publicvoidactionPerformed(ActionEvente){
OWLClasslastSelectedClass=getOWLWorkspace().getOWLSelectionModel().getLastSelectedClass();
if(lastSelectedClass!=null){
OWLReasonerManagerreasonerManager=getOWLModelManager().getOWLReasonerManager();
ReasonerUtilities.warnUserIfReasonerIsNotConfigured(getOWLWorkspace(),reasonerManager);
if(reasonerManager.getReasonerStatus()==ReasonerStatus.INITIALIZED){
OWLReasonerreasoner=reasonerManager.getCurrentReasoner();
Set<OWLClass>subClasses=reasoner.getSubClasses(lastSelectedClass,true).getFlattened();
if(!subClasses.isEmpty()){
LOGGER.info("Inferredsubclassesof"+getOWLModelManager().getRendering(lastSelectedClass)+"are:");
for(OWLClasssubClass:subClasses){
LOGGER.info("\t"+getOWLModelManager().getRendering(subClass));
}
}
else{
LOGGER.info(getOWLModelManager().getRendering(lastSelectedClass)+"hasnoinferredsubclasses.");
}
}
}
}
Thiscodecreatesanactionthatwheninvokedwillprintsomemessagesaboutinferredsubclassestothelog.ThefirstthingtonoticeisthattheOWLReasonerManageris
thecentralclassforaccessingtheProtegereasoneranditcanbeobtainedfromtheOWLModelManager.Thisclasscanbeusedtodeterminethestatusofthereasoner,get
thecurrentProtegereasonerorgetareasonerfactoryforcreatingnewinstancesofaProtegereasoner.
Oncethereasonermanagerisobtainedcodeaboveinformstheuserifthereasonerisnotinitializedorisininconsistentstate.Thiswarninghasbeenincludedasastandard
Protegeutilitysothattheuserwillgetaconsistentmessagewhenthereasonerisnotreadyforinference.ThisistheapproachtakenbytheDLQuerypluginforinstance
becauseitdoesnotmakesensetousetheDLQuerypluginifthereasonerisnotinitialized.Howeveranalternativeapproachistoquietlycheckthestatusofthereasonerand
onlyusethereasonerifitisinagoodenoughstate.Thisisthestrategytakenbythecodethatdisplaysinferencessuchastheinferredsuperclassesandtheconsistencyof
classesandpropertiesastheusernavigatesthroughtheProtegeinterface.
ThenextthingthathappensisthatthecodechecksthestatusofthecurrentreasonerwiththecallreasonerManager.getReasonerStatus().ThiscallreturnsaReasonerStatus
enumerationwhichcurrentlycantakeonthefollowingvalues:
NO_REASONER_FACTORY_CHOSEN:theuserhasnotyetselectedatypeofreasoner.
REASONER_NOT_INITIALIZED:theuserhasselectedwhattypeofreasonerhewantsbuthasnotinitializedityet.
INITIALIZATION_IN_PROGRESS:thereasonerisintheprocessofbeinginitialized.Pluginsshouldnotseethisstate.
INITIALIZED:thereasonerisreadyforuse.
INCONSISTENT:thereasonerwasinitializedbuttheontologyisinconsistent.Inthisstate,reasonersarenotusable.
OUT_OF_SYNC:thereasonerisreadybutitisnotuptodatewiththelatestchangesintheontology.Thereasonerisusableinthisstatebutitmayproduce
misleadingresults.Itcanbebroughtuptodatewithareasoner.flush()call.
http://protegewiki.stanford.edu/wiki/PluginAnatomy
7/11
2/11/2016
PluginAnatomyProtegeWiki
FinallythecodeaboveobtainstheProtegereasoner(whichimplementstheOWLapiOWLReasonerinterface)andusesOWLapicallstoobtaininformation.
Insomecasestheabovestrategyisnotsufficient.Forexample,theexplanationpluginsneedtocreatetheirownreasonersandsotheyneedareasonerfactory.Inthiscase
theplugincanmakethecall:
reasonerManager.getCurrentReasonerFactory().getReasonerFactory()
toobtainthereasonerfactory(aninstanceoftheOWLapiinterfaceOWLReasonerFactory).
AdvancedTopics
AddingNewPluginTypes
WorkinProgress
OneoftheadvantagesofusingtheOSGi/Eclipseframeworkisthatitnaturallyallowsdeveloperstodefinetheirownplugintypes.Forexample,theSWRLtab,being
writtenbyMartinO'Connor,delegatestheworkofexecutingtheSWRLrulestoaruleengineplugin.Itisanticipatedthattherewillbetworuleenginepluginsthatareare
compatiblewiththeSWRLtab.OneofthesepluginswillbebasedontheJessruleengineandtheotherpluginwillbebasedontheDROOLSruleengine.
WewillillustratehowthisisdonewithtwoProtegebundles.Thesourcesforthesebundlescanbefound
http://smiprotege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/consumer
and
http://smiprotege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/producer
Bothbundlescanbequicklyinstalledthroughtheincludedantscripts.
Theconsumerbundlebehavesasfollows.ItaddsamenuitemtoarunningProtegeenvironment.Thismenuisfoundatthebottomoftheeditmenu.Whentheuserclickson
thismenuitem,theconsumerbundleperformsthefollowingactions:
1.itlooksforallcustom_extension_pointpluginsintherunningProtegeenvironment,
2.itinstantiateseachpluginfoundandfinally
3.itcallsthedoSomething()methodonthatplugininstance.
Thisbehaviorisprovidedthroughtheinteractionoffourcomponents:
theconsumercodethatisresponsibleforloopingthroughasetofpluginsandinvokingthem.
thepluginloaderthatisresponsibleforcalculatingandreturningasetofpluginsthatmatchaspecifiction.
thepluginthatisajavaencodingofdataencodedinplugin.xmlfilesprovidedbythebundles.
theplugininstancethatisaninstantiationofapluginthatdoestheactualworkoftheplugin.
ThePluginConsumer
ThePluginconsumeressentiallyusesthepluginloader(describedbelow)toloopthroughaseriesofpluginsandinstantiateandinvokethem.Thecodethatdoesthiswork
canbefoundintheMyPluginConsumer(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/consumer/src/org/protege/example/extension/point/MyPluginConsumer.java)classand
lookslikethefollowing:
publicvoidactionPerformed(ActionEvente){
MyPluginLoaderloader=newMyPluginLoader(getOWLModelManager());
for(MyPluginplugin:loader.getPlugins()){
try{
MyPluginInstancei=plugin.newInstance();
i.doSomething();
}
catch(Exceptionex){
ProtegeApplication.getErrorLog().logError(ex);
}
}
}
Thisisatypicalexampleofhowapluginconsumerwillwork.Itusesapluginloadertofindasetofpluginsthataretheninstantiated(plugin.newInstance())andthen
invoked(i.doSomething()).Forthemostpart,thepluginconsumerdoesnothavetoworrytoomuchaboutthedetailsoftheProtegeplugininfrastructure.Thelogicofthe
Pluginconsumerisdefinedbythetaskathand.
ThePluginLoader
Thepluginloader(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/consumer/src/org/protege/example/extension/point/MyPluginLoader.java)is
responsibleforsearchingforpluginsofthecustom_extension_pointtype.ThepluginloaderextendstheAbstractPluginLoaderclasswhichhandlesmostofthelogicof
creatingandfindingplugins.Minimally,allthedeveloperneedstodotoimplementthepluginloaderistoimplementaconstructorandacreateinstancemethod.The
constructorlookslikethis:
publicMyPluginLoader(OWLModelManagerowlModelManager){
super(MyPlugin.CONSUMER_ID,MyPlugin.ID);
this.owlModelManager=owlModelManager;
}
andthisistypical.ThesignificanceofthetwoargumentstothesuperconstructorwillbeexplainedwhenIdescribethePluginimplementation.Essentiallytheydefine
whichtypeofpluginisbeingsearchedforbythisloader.Inaddition,theconstructorforthispluginloadertakesanowlModelManagerargumentsothathecanpassthis
argumenttotheconstructorfortheplugins.ThecreateInstancemethodthenisresponsibleforconstructingtheplugin:
protectedMyPlugincreateInstance(IExtensionextension){
returnnewMyPlugin(owlModelManager,extension);
}
InadditionthereisagetExtensionMatchermethodthatcanbeusedtorestrictthesetofpluginsthatarereturnedbythispluginloader.Generallyitisnotnecessaryto
implementthegetExtensionMatcherinterface.
ThePlugin
Essentiallytheplugin(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/consumer/src/org/protege/example/extension/point/MyPlugin.java)isaPOJO
representingadeclarationofaplugininaplugin.xmlfile.Tounderstandthisweneedtolookatthetwodeclarationsintwoseparateplugin.xmlfiles.Thefirstdeclarationis
foundinthebundlefortheconsumerplugin.Thisdeclarationrepresentsarequestforaparticulartypeofservice.Inourcasethedeclaration(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/consumer/plugin.xml)lookslikethis:
<extensionpointid="custom_extension_point"
name="CustomExtensionPoint"
schema="schema/custom_extension_point.exsd"/>
http://protegewiki.stanford.edu/wiki/PluginAnatomy
8/11
2/11/2016
PluginAnatomyProtegeWiki
Thisdeclarationdefines
theidentifieroftheplugintype,custom_extension_point,whichisthenamebywhichplugindevelopersrefertothisplugintype,Thisstringcorrespondstothe
MyPlugin.IDthatwepassedtotheAbstractPluginLoaderconstructorabove.Notethatitispossiblefordifferentbundlestodeclareanextensionpoint
theuserfriendlynameoftheplugintypeand
apointertothexmlschemafortheplugintype.
Ibelievethatthelastitem,theschema(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/consumer/schema/custom_extension_point.exsd),isnotmandatorybutitisextremely
usefulfordevelopersanditiscreatednaturallywhenpluginsaredevelopedusingtheeclipseIDE.
Thepluginproducerprovidedadeclaration(http://smiprotege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/producer/plugin.xml)forhis
extensionthatmatchestheextensionpointdeclarationabove.Inourexampletheextensiondeclarationlookslikethis:
<extensionid="SimpleImplementation"
point="org.protege.example.extension.point.custom_extension_point">
<classvalue="org.protege.example.extension.PluginImplementation"/>
<typevalue="LoggerType"/>
</extension>
Thepluginclass,MyPlugin(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/consumer/src/org/protege/example/extension/point/MyPlugin.java),extendsthe
AbstractProtegePluginclass.TheAbstractProtegePluginclassprovidesmanyutilitiesthatmakeiteasytowritethepluginclass.Inparticular,togetthe"type"fieldthe
MyPluginclassprovidesanaccessor:
/**
*getsthedeclaredtypefieldfortheplugin
*/
publicStringgetType(){
returngetPluginProperty(TYPE_PARAM,"nulltype");
}
Inaddition,theAbstractProtegePluginclassdoesthetrickyaspectsofinstantiatingthepluginleavingonlythetaskofinitializingtheinstantiatedplugintotheMyPlugin
class:
/**
*Createsaninstanceoftheplugin.Itisexpectedthat
*thisinstancewillbe"setup",buttheinstance's
*initialisemethodwillnothavebeencalledintheinstantiation
*process.
*/
publicMyPluginInstancenewInstance()throwsClassNotFoundException,IllegalAccessException,
InstantiationException{
MyPluginInstancempi=super.newInstance();
mpi.setup(modelManager,getType());
returnmpi;
}
ThePluginInstance
Theplugininstanceclass(http://smi
protege.stanford.edu/repos/protege/protege4/misc/examples/custom.extension/trunk/consumer/src/org/protege/example/extension/point/api/MyPluginInstance.java)is
responsibleforperformingwhatevertaskitisthatthepluginissupposedtoperform.InourcasetheplugininstancewillimplementthedoSomething()method.Thisclass
mustimplementtheProtegePluginInstanceinterfacethoughitisnotclearthatthisisreallyneededanymore.TheProtegePluginInstanceinterfacehasonlyonemethod,
initialise(),butmanyplugins,suchastheoneinthisexample,havetheirowninitailizationmethodsthatarecalledbythePluginLoader.
Frames,FrameSections,andRows
InProgress
ItisnotclearthatthisneedstobeherebutthisisanextremelycentralProtegeconcept.IngeneralplugindeveloperswillnotneedtobuildcustomFramelistsandcan
simplyusethetoplevelOWLFrameListconcepts.
MostofthediscussionwillfocusonasmallerandsmallersectionofthethefollowingProtege4.1screen.ThisdiagramshowsthestandardProtege4.1classestabasit
displayssomeinformationabouttheselectedclasswhichistheCountryclassinthepizzaontology.
http://protegewiki.stanford.edu/wiki/PluginAnatomy
9/11
2/11/2016
PluginAnatomyProtegeWiki
FrameListsandFrames
ThediagrambelowshowsaFrameListshowingadescriptionoftheCountryclass.TheOWLFrameLististheswingobjectthatisresponsiblefordisplayingsomeobject
calledtherootobjectfortheOWLFrameList.Inthiscase,therootobjectforthisframelististheCountryOWLclass.Frequentlytherootobjectoftheforaframelistisan
OWLentitybutthisisnotrequired.TheconstructorfortheOWLFrameListobjecttakesanOWLFrameobjectwhichmanagesthecontentmodeloftheOWLFrameList.
TheassociatedOWLFrameobjectalsohasarootobjectandinthiscasetherootobjectistheCountryclass.
Whileitmaynotbevisuallyimmediatelyapparent,theinformationbeingdisplayedisactuallyarenditionofalistofaxioms.Thusforinstance,theclassexpression
representedinthesectionunderneathEquivalentClassesrepresentstheaxiom
CountrySubClassOfDomainConceptand{America,England,France,Germany,Italy}.
SimilarlythefirstindividualdisplayedunderMembersrepresentstheaxiom
AmericaTypeCountry.
ThefactthatthesearenotdisplayedsimplyastheassociatedaxiomsisankeypartofthepurposeoftheOWLFrameList.ThetaskoftheOWLFrameListbelowisto
describetheCountryclass.ForauseritmakessensethatintheMemberssectionofthatOWLFrameListhewouldseealistoftheindividualsinthatclass.Itwouldmake
lesssensetotheuserifasetofaxiomswasdisplayedthere.
FrameSections
OWLFramesaregroupedintoaseriesofsectionseachofwhichshowsaparticulartypeofaxioms.Inthediagrambelowwehaveaframesectionthatisrenderingalistof
classassertionaxioms.
http://protegewiki.stanford.edu/wiki/PluginAnatomy
10/11
2/11/2016
PluginAnatomyProtegeWiki
FrameSectionRows
Glossary
TherearesometermsthatcomeupnaturallyinthediscussionofProtege4plugindevelopmentthatrequireabitofexplanation.TheProtege4pluginmechanismhasthree
layersandthetermsusedtodescribepluginsisslightlydifferentateachoftheselayers:
ExtensionPointistheeclipsetermforwhatProtegefolkoftencallaplugin.
OSGi(http://www.osgi.org/Main/HomePage)isthebottomlayeroftheProtegepluginarchitecture.Itisapowerfulindustrystandardframeworkwhichprovides
modularityandservicesbeyondthatprovidedbytheJavaspecifications.InOSGi,thetermOSGibundleisusedtorepresentaselfcontainedunitofcodethatcanbe
introducedintotheOSGiframeworkandwhichwillimportandexportclassesandresourcesinacontrolledway.
AnOSGiBundleiscollectionofsoftwaregroupedintoasinglejarfile.WhenthissoftwarerunsintheOSGienvironment,itrunsinaprotectedspacewhereitcan
defineexactlywhatjavaclassesfromthesurroundingenvironmentareneededandwhatjavaclassesareincompatiblewithitsoperation.Bundleshavenames,version
numbers,developercontactinformationandactivationentrypoints.
APluginisadeclaredservicethatimplementssomefunctionalityofusetotheProtegeplatform.TheProtegePluginmechanismisbasedontheEclipseplugin
mechanismwherepluginsaredeclaredinafilecalledplugin.xml.
TheEclipseRichClientPlatform(http://wiki.eclipse.org/index.php/Rich_Client_Platform)isanenvironmentbuiltontopofOSGiwhichprovidesadditional
featurestoeasethebuildingofa"Rich"client.Protege4onlyusessomeofthefeaturesofthisrichclientplatform.Inparticular,Protege4doesnotuseSWTand
manyofthegraphicalrelatedcapabilities.ButProtege4doesusethedeclarativeplugincapabilitiesprovidedbyeclipse.ItisherethatsomeofthepoweroftheOSGi
platformbecomesmanifest,becausewehavebeenabletouseonlythosebundlesfromtheeclipseRichClientplatformthatweneed.Inthissetting,OSGibundles
createdaccordingtocertainconventionsbecomeEclipsePlugins.
TheProtege4PluginlayerprovidessomeadditionalconveniencemethodsovertheEclipsePluginframework.CertaineclipsepluginsthatextendProtege4
capabilitiesarecalledProtege4plugins.
Retrievedfrom"http://protegewiki.stanford.edu/index.php?title=PluginAnatomy&oldid=12200"
ThispagewaslastmodifiedonSeptember1,2013,at06:34.
http://protegewiki.stanford.edu/wiki/PluginAnatomy
11/11