summaryrefslogtreecommitdiff
path: root/configmgr
diff options
context:
space:
mode:
Diffstat (limited to 'configmgr')
-rw-r--r--configmgr/inc/makefile.mk52
-rw-r--r--configmgr/inc/pch/precompiled_configmgr.cxx32
-rw-r--r--configmgr/inc/pch/precompiled_configmgr.hxx248
-rw-r--r--configmgr/makefile.pmk32
-rw-r--r--configmgr/prj/build.lst18
-rw-r--r--configmgr/prj/d.lst10
-rw-r--r--configmgr/qa/unit/common.hxx114
-rw-r--r--configmgr/qa/unit/configmgrrc22
-rw-r--r--configmgr/qa/unit/data/org/openoffice/Setup.xcu46
-rw-r--r--configmgr/qa/unit/data/org/openoffice/UI/GenericCommands.xcu5072
-rw-r--r--configmgr/qa/unit/export.map7
-rw-r--r--configmgr/qa/unit/makefile.mk63
-rw-r--r--configmgr/qa/unit/performance.cxx271
-rw-r--r--configmgr/qa/unit/schema/org/openoffice/Setup.xcs75
-rw-r--r--configmgr/qa/unit/schema/org/openoffice/UI/Commands.xcs65
-rw-r--r--configmgr/qa/unit/schema/org/openoffice/UI/GenericCommands.xcs52
-rw-r--r--configmgr/qa/unit/threading.cxx262
-rw-r--r--configmgr/qa/unit/ubootstrap.cxx123
-rw-r--r--configmgr/qa/unoapi/cfgmgr2.sce34
-rw-r--r--configmgr/qa/unoapi/knownissues.xcl55
-rw-r--r--configmgr/qa/unoapi/makefile.mk48
-rw-r--r--configmgr/source/api/confevents.cxx305
-rw-r--r--configmgr/source/api/confsvccomponent.cxx103
-rw-r--r--configmgr/source/api/makefile.mk53
-rw-r--r--configmgr/source/api2/accessimpl.cxx807
-rw-r--r--configmgr/source/api2/accessimpl.hxx139
-rw-r--r--configmgr/source/api2/apiaccessobj.cxx293
-rw-r--r--configmgr/source/api2/apiaccessobj.hxx148
-rw-r--r--configmgr/source/api2/apiaccessobj.inl263
-rw-r--r--configmgr/source/api2/apifactory.cxx338
-rw-r--r--configmgr/source/api2/apifactory.hxx122
-rw-r--r--configmgr/source/api2/apifactoryimpl.cxx355
-rw-r--r--configmgr/source/api2/apifactoryimpl.hxx71
-rw-r--r--configmgr/source/api2/apinodeaccess.cxx181
-rw-r--r--configmgr/source/api2/apinodeaccess.hxx175
-rw-r--r--configmgr/source/api2/apinodeupdate.cxx172
-rw-r--r--configmgr/source/api2/apinodeupdate.hxx177
-rw-r--r--configmgr/source/api2/apinotifierimpl.cxx332
-rw-r--r--configmgr/source/api2/apinotifierimpl.hxx105
-rw-r--r--configmgr/source/api2/apiserviceinfo.cxx340
-rw-r--r--configmgr/source/api2/apiserviceinfo.hxx72
-rw-r--r--configmgr/source/api2/apitreeaccess.cxx113
-rw-r--r--configmgr/source/api2/apitreeaccess.hxx179
-rw-r--r--configmgr/source/api2/apitreeimplobj.cxx1004
-rw-r--r--configmgr/source/api2/apitreeimplobj.hxx192
-rw-r--r--configmgr/source/api2/broadcaster.cxx1229
-rw-r--r--configmgr/source/api2/broadcaster.hxx91
-rw-r--r--configmgr/source/api2/committer.cxx133
-rw-r--r--configmgr/source/api2/committer.hxx60
-rw-r--r--configmgr/source/api2/confignotifier.cxx246
-rw-r--r--configmgr/source/api2/confignotifier.hxx200
-rw-r--r--configmgr/source/api2/elementaccess.cxx489
-rw-r--r--configmgr/source/api2/elementaccess.hxx386
-rw-r--r--configmgr/source/api2/elementimpl.cxx591
-rw-r--r--configmgr/source/api2/elementimpl.hxx160
-rw-r--r--configmgr/source/api2/groupaccess.cxx147
-rw-r--r--configmgr/source/api2/groupaccess.hxx138
-rw-r--r--configmgr/source/api2/groupobjects.cxx410
-rw-r--r--configmgr/source/api2/groupobjects.hxx271
-rw-r--r--configmgr/source/api2/groupupdate.cxx107
-rw-r--r--configmgr/source/api2/groupupdate.hxx101
-rw-r--r--configmgr/source/api2/listenercontainer.cxx83
-rw-r--r--configmgr/source/api2/listenercontainer.hxx584
-rw-r--r--configmgr/source/api2/makefile.mk83
-rw-r--r--configmgr/source/api2/notifierimpl.hxx241
-rw-r--r--configmgr/source/api2/objectregistry.hxx98
-rw-r--r--configmgr/source/api2/propertiesfilterednotifier.cxx154
-rw-r--r--configmgr/source/api2/propertiesfilterednotifier.hxx79
-rw-r--r--configmgr/source/api2/propertyinfohelper.cxx75
-rw-r--r--configmgr/source/api2/propertyinfohelper.hxx59
-rw-r--r--configmgr/source/api2/propertysetaccess.cxx278
-rw-r--r--configmgr/source/api2/propertysetaccess.hxx218
-rw-r--r--configmgr/source/api2/propsetaccessimpl.cxx1287
-rw-r--r--configmgr/source/api2/propsetaccessimpl.hxx141
-rw-r--r--configmgr/source/api2/provider.cxx714
-rw-r--r--configmgr/source/api2/provider.hxx201
-rw-r--r--configmgr/source/api2/providerimpl.cxx896
-rw-r--r--configmgr/source/api2/providerimpl.hxx231
-rw-r--r--configmgr/source/api2/setaccess.cxx188
-rw-r--r--configmgr/source/api2/setaccess.hxx170
-rw-r--r--configmgr/source/api2/setobjects.cxx550
-rw-r--r--configmgr/source/api2/setobjects.hxx361
-rw-r--r--configmgr/source/api2/setupdate.cxx244
-rw-r--r--configmgr/source/api2/setupdate.hxx211
-rw-r--r--configmgr/source/api2/translatechanges.cxx286
-rw-r--r--configmgr/source/api2/translatechanges.hxx120
-rw-r--r--configmgr/source/api2/treeiterators.cxx96
-rw-r--r--configmgr/source/api2/treeiterators.hxx88
-rw-r--r--configmgr/source/api2/updateimpl.cxx650
-rw-r--r--configmgr/source/api2/updateimpl.hxx98
-rw-r--r--configmgr/source/backend/backendaccess.cxx830
-rw-r--r--configmgr/source/backend/backendaccess.hxx160
-rw-r--r--configmgr/source/backend/backendfactory.cxx332
-rw-r--r--configmgr/source/backend/backendnotifier.cxx198
-rw-r--r--configmgr/source/backend/backendnotifier.hxx123
-rw-r--r--configmgr/source/backend/backendstratalistener.cxx59
-rw-r--r--configmgr/source/backend/backendstratalistener.hxx77
-rw-r--r--configmgr/source/backend/basicimporthandler.cxx117
-rw-r--r--configmgr/source/backend/basicimporthandler.hxx99
-rw-r--r--configmgr/source/backend/basicupdatemerger.cxx341
-rw-r--r--configmgr/source/backend/basicupdatemerger.hxx160
-rw-r--r--configmgr/source/backend/binarycache.cxx251
-rw-r--r--configmgr/source/backend/binarycache.hxx103
-rw-r--r--configmgr/source/backend/binaryreader.cxx693
-rw-r--r--configmgr/source/backend/binaryreader.hxx88
-rw-r--r--configmgr/source/backend/binaryreadhandler.cxx690
-rw-r--r--configmgr/source/backend/binaryreadhandler.hxx136
-rw-r--r--configmgr/source/backend/binarytype.hxx61
-rw-r--r--configmgr/source/backend/binarywritehandler.cxx492
-rw-r--r--configmgr/source/backend/binarywritehandler.hxx120
-rw-r--r--configmgr/source/backend/binarywriter.cxx218
-rw-r--r--configmgr/source/backend/binarywriter.hxx79
-rw-r--r--configmgr/source/backend/componentdatahelper.cxx617
-rw-r--r--configmgr/source/backend/componentdatahelper.hxx222
-rw-r--r--configmgr/source/backend/emptylayer.cxx228
-rw-r--r--configmgr/source/backend/emptylayerimpl.hxx139
-rw-r--r--configmgr/source/backend/importmergehandler.cxx299
-rw-r--r--configmgr/source/backend/importmergehandler.hxx137
-rw-r--r--configmgr/source/backend/importsvc.cxx338
-rw-r--r--configmgr/source/backend/importsvc.hxx157
-rw-r--r--configmgr/source/backend/layerdefaultremover.cxx278
-rw-r--r--configmgr/source/backend/layerdefaultremover.hxx135
-rw-r--r--configmgr/source/backend/layermerge.cxx1039
-rw-r--r--configmgr/source/backend/layermerge.hxx191
-rw-r--r--configmgr/source/backend/layerupdate.cxx113
-rw-r--r--configmgr/source/backend/layerupdate.hxx90
-rw-r--r--configmgr/source/backend/layerupdatebuilder.cxx302
-rw-r--r--configmgr/source/backend/layerupdatebuilder.hxx108
-rw-r--r--configmgr/source/backend/layerupdatehandler.cxx316
-rw-r--r--configmgr/source/backend/layerupdatehandler.hxx157
-rw-r--r--configmgr/source/backend/layerupdatemerger.cxx515
-rw-r--r--configmgr/source/backend/layerupdatemerger.hxx133
-rw-r--r--configmgr/source/backend/makefile.mk81
-rw-r--r--configmgr/source/backend/mergedcomponentdata.cxx176
-rw-r--r--configmgr/source/backend/mergedcomponentdata.hxx102
-rw-r--r--configmgr/source/backend/multistratumbackend.cxx934
-rw-r--r--configmgr/source/backend/multistratumbackend.hxx222
-rw-r--r--configmgr/source/backend/schemabuilder.cxx539
-rw-r--r--configmgr/source/backend/schemabuilder.hxx154
-rw-r--r--configmgr/source/backend/singlebackendadapter.cxx339
-rw-r--r--configmgr/source/backend/singlebackendadapter.hxx145
-rw-r--r--configmgr/source/backend/updatedata.cxx458
-rw-r--r--configmgr/source/backend/updatedata.hxx269
-rw-r--r--configmgr/source/backend/updatedispatch.cxx499
-rw-r--r--configmgr/source/backend/updatedispatch.hxx106
-rw-r--r--configmgr/source/backend/updatesvc.cxx281
-rw-r--r--configmgr/source/backend/updatesvc.hxx125
-rw-r--r--configmgr/source/backendhelper/backendlayerhelper.cxx364
-rw-r--r--configmgr/source/backendhelper/backendlayerhelper.hxx168
-rw-r--r--configmgr/source/backendhelper/behelper.uno.xml35
-rw-r--r--configmgr/source/backendhelper/componentdf.cxx91
-rw-r--r--configmgr/source/backendhelper/exports.dxp3
-rw-r--r--configmgr/source/backendhelper/makefile.mk71
-rw-r--r--configmgr/source/data/anydata.cxx471
-rw-r--r--configmgr/source/data/makefile.mk54
-rw-r--r--configmgr/source/data/sequence.cxx493
-rw-r--r--configmgr/source/inc/anydata.hxx81
-rw-r--r--configmgr/source/inc/anynoderef.hxx160
-rw-r--r--configmgr/source/inc/anypair.hxx118
-rw-r--r--configmgr/source/inc/apitypes.hxx92
-rw-r--r--configmgr/source/inc/attributes.hxx136
-rw-r--r--configmgr/source/inc/autoobject.hxx100
-rw-r--r--configmgr/source/inc/autoreferencemap.hxx132
-rw-r--r--configmgr/source/inc/backendfactory.hxx71
-rw-r--r--configmgr/source/inc/bootstrap.hxx244
-rw-r--r--configmgr/source/inc/bootstrapcontext.hxx171
-rw-r--r--configmgr/source/inc/bufferedfile.hxx68
-rw-r--r--configmgr/source/inc/builddata.hxx72
-rw-r--r--configmgr/source/inc/cachefactory.hxx54
-rw-r--r--configmgr/source/inc/change.hxx507
-rw-r--r--configmgr/source/inc/confapifactory.hxx181
-rw-r--r--configmgr/source/inc/confevents.hxx216
-rw-r--r--configmgr/source/inc/configdefaultprovider.hxx98
-rw-r--r--configmgr/source/inc/configexcept.hxx120
-rw-r--r--configmgr/source/inc/configgroup.hxx117
-rw-r--r--configmgr/source/inc/configinteractionhandler.hxx84
-rw-r--r--configmgr/source/inc/configpath.hxx449
-rw-r--r--configmgr/source/inc/configset.hxx146
-rw-r--r--configmgr/source/inc/confsvccomponent.hxx91
-rw-r--r--configmgr/source/inc/datalock.hxx71
-rw-r--r--configmgr/source/inc/defaultprovider.hxx76
-rw-r--r--configmgr/source/inc/emptylayer.hxx56
-rw-r--r--configmgr/source/inc/filehelper.hxx117
-rw-r--r--configmgr/source/inc/flags.hxx136
-rw-r--r--configmgr/source/inc/interactionrequest.hxx166
-rw-r--r--configmgr/source/inc/localizedtreeactions.hxx55
-rw-r--r--configmgr/source/inc/logger.hxx116
-rw-r--r--configmgr/source/inc/matchlocale.hxx218
-rw-r--r--configmgr/source/inc/mergechange.hxx71
-rw-r--r--configmgr/source/inc/mergeddataprovider.hxx176
-rw-r--r--configmgr/source/inc/namecreator.hxx76
-rw-r--r--configmgr/source/inc/node.hxx232
-rw-r--r--configmgr/source/inc/nodechange.hxx160
-rw-r--r--configmgr/source/inc/nodechangeinfo.hxx249
-rw-r--r--configmgr/source/inc/nodeconverter.hxx64
-rw-r--r--configmgr/source/inc/noderef.hxx271
-rw-r--r--configmgr/source/inc/nodevisitor.hxx80
-rw-r--r--configmgr/source/inc/options.hxx105
-rw-r--r--configmgr/source/inc/oslstream.hxx134
-rw-r--r--configmgr/source/inc/propertysethelper.hxx113
-rw-r--r--configmgr/source/inc/request.hxx155
-rw-r--r--configmgr/source/inc/requestoptions.hxx124
-rw-r--r--configmgr/source/inc/requesttypes.hxx237
-rw-r--r--configmgr/source/inc/roottree.hxx115
-rw-r--r--configmgr/source/inc/sequence.hxx108
-rw-r--r--configmgr/source/inc/serviceinfohelper.hxx138
-rw-r--r--configmgr/source/inc/simpleinteractionrequest.hxx104
-rw-r--r--configmgr/source/inc/simpletypehelper.hxx56
-rw-r--r--configmgr/source/inc/stack.hxx61
-rw-r--r--configmgr/source/inc/strdecl.hxx63
-rw-r--r--configmgr/source/inc/strings.hxx77
-rw-r--r--configmgr/source/inc/template.hxx110
-rw-r--r--configmgr/source/inc/tracer.hxx138
-rw-r--r--configmgr/source/inc/tree.hxx668
-rw-r--r--configmgr/source/inc/treeactions.hxx92
-rw-r--r--configmgr/source/inc/treechangefactory.hxx107
-rw-r--r--configmgr/source/inc/treechangelist.hxx123
-rw-r--r--configmgr/source/inc/treefragment.hxx141
-rw-r--r--configmgr/source/inc/treemanager.hxx160
-rw-r--r--configmgr/source/inc/treenodefactory.hxx99
-rw-r--r--configmgr/source/inc/treesegment.hxx76
-rw-r--r--configmgr/source/inc/typeconverter.hxx83
-rw-r--r--configmgr/source/inc/updatehelper.hxx49
-rw-r--r--configmgr/source/inc/utility.hxx53
-rw-r--r--configmgr/source/inc/valuenode.hxx296
-rw-r--r--configmgr/source/inc/valueref.hxx135
-rw-r--r--configmgr/source/inc/valuetypeconverter.hxx158
-rw-r--r--configmgr/source/inc/wrapexception.hxx131
-rw-r--r--configmgr/source/localbe/localdataimportsvc.cxx360
-rw-r--r--configmgr/source/localbe/localdataimportsvc.hxx101
-rw-r--r--configmgr/source/localbe/localfilehelper.cxx245
-rw-r--r--configmgr/source/localbe/localfilehelper.hxx124
-rw-r--r--configmgr/source/localbe/localfilelayer.cxx611
-rw-r--r--configmgr/source/localbe/localfilelayer.hxx495
-rw-r--r--configmgr/source/localbe/localhierarchybrowsersvc.cxx536
-rw-r--r--configmgr/source/localbe/localhierarchybrowsersvc.hxx103
-rw-r--r--configmgr/source/localbe/localmultistratum.cxx250
-rw-r--r--configmgr/source/localbe/localmultistratum.hxx100
-rw-r--r--configmgr/source/localbe/localoutputstream.cxx199
-rw-r--r--configmgr/source/localbe/localoutputstream.hxx106
-rw-r--r--configmgr/source/localbe/localschemasupplier.cxx291
-rw-r--r--configmgr/source/localbe/localschemasupplier.hxx118
-rw-r--r--configmgr/source/localbe/localsinglebackend.cxx801
-rw-r--r--configmgr/source/localbe/localsinglebackend.hxx248
-rw-r--r--configmgr/source/localbe/localsinglestratum.cxx233
-rw-r--r--configmgr/source/localbe/localsinglestratum.hxx150
-rw-r--r--configmgr/source/localbe/localstratumbase.cxx256
-rw-r--r--configmgr/source/localbe/localstratumbase.hxx202
-rw-r--r--configmgr/source/localbe/makefile.mk61
-rw-r--r--configmgr/source/misc/anypair.cxx691
-rw-r--r--configmgr/source/misc/bootstrap.cxx717
-rw-r--r--configmgr/source/misc/bootstrapcontext.cxx417
-rw-r--r--configmgr/source/misc/bufferedfile.cxx133
-rw-r--r--configmgr/source/misc/configinteractionhandler.cxx115
-rw-r--r--configmgr/source/misc/configunoreg.cxx389
-rw-r--r--configmgr/source/misc/filehelper.cxx390
-rw-r--r--configmgr/source/misc/interactionrequest.cxx118
-rw-r--r--configmgr/source/misc/logger.cxx96
-rw-r--r--configmgr/source/misc/makefile.mk77
-rw-r--r--configmgr/source/misc/mergechange.cxx831
-rw-r--r--configmgr/source/misc/oslstream.cxx264
-rw-r--r--configmgr/source/misc/propertysethelper.cxx134
-rw-r--r--configmgr/source/misc/providerfactory.cxx244
-rw-r--r--configmgr/source/misc/providerfactory.hxx91
-rw-r--r--configmgr/source/misc/providerwrapper.cxx196
-rw-r--r--configmgr/source/misc/providerwrapper.hxx101
-rw-r--r--configmgr/source/misc/requestoptions.cxx107
-rw-r--r--configmgr/source/misc/serviceinfohelper.cxx192
-rw-r--r--configmgr/source/misc/simpleinteractionrequest.cxx100
-rw-r--r--configmgr/source/misc/strimpl.cxx63
-rw-r--r--configmgr/source/misc/tracer.cxx474
-rw-r--r--configmgr/source/platformbe/componentdefn.cxx93
-rw-r--r--configmgr/source/platformbe/exports.dxp3
-rw-r--r--configmgr/source/platformbe/makefile.mk74
-rw-r--r--configmgr/source/platformbe/sysmgr1.uno.xml49
-rw-r--r--configmgr/source/platformbe/systemintegrationmanager.cxx369
-rw-r--r--configmgr/source/platformbe/systemintegrationmanager.hxx161
-rw-r--r--configmgr/source/registry/cfgregistrykey.cxx1482
-rw-r--r--configmgr/source/registry/cfgregistrykey.hxx247
-rw-r--r--configmgr/source/registry/configregistry.cxx379
-rw-r--r--configmgr/source/registry/configregistry.hxx121
-rw-r--r--configmgr/source/registry/makefile.mk52
-rw-r--r--configmgr/source/tree/builddata.cxx1137
-rw-r--r--configmgr/source/tree/changes.cxx247
-rw-r--r--configmgr/source/tree/cmtree.cxx381
-rw-r--r--configmgr/source/tree/cmtreemodel.cxx374
-rw-r--r--configmgr/source/tree/localizedtreeactions.cxx543
-rw-r--r--configmgr/source/tree/makefile.mk70
-rw-r--r--configmgr/source/tree/mergehelper.cxx459
-rw-r--r--configmgr/source/tree/node.cxx538
-rw-r--r--configmgr/source/tree/nodeconverter.cxx213
-rw-r--r--configmgr/source/tree/nodevisitor.cxx107
-rw-r--r--configmgr/source/tree/subtree.hxx113
-rw-r--r--configmgr/source/tree/treeactions.cxx67
-rw-r--r--configmgr/source/tree/treechangefactory.cxx126
-rw-r--r--configmgr/source/tree/treefragment.cxx133
-rw-r--r--configmgr/source/tree/treenodefactory.cxx113
-rw-r--r--configmgr/source/tree/treesegment.cxx91
-rw-r--r--configmgr/source/tree/updatehelper.cxx625
-rw-r--r--configmgr/source/treecache/cacheaccess.cxx355
-rw-r--r--configmgr/source/treecache/cacheaccess.hxx160
-rw-r--r--configmgr/source/treecache/cachecontroller.cxx719
-rw-r--r--configmgr/source/treecache/cachecontroller.hxx341
-rw-r--r--configmgr/source/treecache/cachedata.cxx498
-rw-r--r--configmgr/source/treecache/cachedata.hxx179
-rw-r--r--configmgr/source/treecache/cachefactory.cxx78
-rw-r--r--configmgr/source/treecache/cacheline.cxx356
-rw-r--r--configmgr/source/treecache/cacheline.hxx140
-rw-r--r--configmgr/source/treecache/cachemulticaster.cxx147
-rw-r--r--configmgr/source/treecache/cachemulticaster.hxx91
-rw-r--r--configmgr/source/treecache/cachewritescheduler.cxx216
-rw-r--r--configmgr/source/treecache/cachewritescheduler.hxx128
-rw-r--r--configmgr/source/treecache/disposetimer.cxx305
-rw-r--r--configmgr/source/treecache/disposetimer.hxx172
-rw-r--r--configmgr/source/treecache/invalidatetree.cxx176
-rw-r--r--configmgr/source/treecache/makefile.mk62
-rw-r--r--configmgr/source/treecache/timestamp.cxx63
-rw-r--r--configmgr/source/treecache/timestamp.hxx128
-rw-r--r--configmgr/source/treecache/treemanager.cxx515
-rw-r--r--configmgr/source/treemgr/collectchanges.cxx244
-rw-r--r--configmgr/source/treemgr/collectchanges.hxx124
-rw-r--r--configmgr/source/treemgr/configdefaultprovider.cxx153
-rw-r--r--configmgr/source/treemgr/configexcept.cxx184
-rw-r--r--configmgr/source/treemgr/configgroup.cxx407
-rw-r--r--configmgr/source/treemgr/configpath.cxx1001
-rw-r--r--configmgr/source/treemgr/configset.cxx577
-rw-r--r--configmgr/source/treemgr/defaultproviderproxy.cxx94
-rw-r--r--configmgr/source/treemgr/defaultproviderproxy.hxx89
-rw-r--r--configmgr/source/treemgr/deferredview.cxx446
-rw-r--r--configmgr/source/treemgr/deferredview.hxx100
-rw-r--r--configmgr/source/treemgr/directview.cxx130
-rw-r--r--configmgr/source/treemgr/directview.hxx78
-rw-r--r--configmgr/source/treemgr/groupnodeimpl.hxx91
-rw-r--r--configmgr/source/treemgr/makefile.mk78
-rw-r--r--configmgr/source/treemgr/nodechange.cxx276
-rw-r--r--configmgr/source/treemgr/nodechangeimpl.cxx788
-rw-r--r--configmgr/source/treemgr/nodechangeimpl.hxx432
-rw-r--r--configmgr/source/treemgr/nodechangeinfo.cxx224
-rw-r--r--configmgr/source/treemgr/nodefactory.cxx136
-rw-r--r--configmgr/source/treemgr/nodefactory.hxx67
-rw-r--r--configmgr/source/treemgr/nodeimpl.cxx140
-rw-r--r--configmgr/source/treemgr/nodeimpl.hxx92
-rw-r--r--configmgr/source/treemgr/nodeimplobj.cxx1165
-rw-r--r--configmgr/source/treemgr/nodeimplobj.hxx201
-rw-r--r--configmgr/source/treemgr/noderef.cxx920
-rw-r--r--configmgr/source/treemgr/readonlyview.cxx108
-rw-r--r--configmgr/source/treemgr/readonlyview.hxx74
-rw-r--r--configmgr/source/treemgr/roottree.cxx174
-rw-r--r--configmgr/source/treemgr/roottreeimpl.hxx70
-rw-r--r--configmgr/source/treemgr/setnodeimpl.cxx997
-rw-r--r--configmgr/source/treemgr/setnodeimpl.hxx309
-rw-r--r--configmgr/source/treemgr/template.cxx127
-rw-r--r--configmgr/source/treemgr/templateimpl.cxx364
-rw-r--r--configmgr/source/treemgr/templateimpl.hxx175
-rw-r--r--configmgr/source/treemgr/treeimpl.cxx1373
-rw-r--r--configmgr/source/treemgr/valuemembernode.cxx336
-rw-r--r--configmgr/source/treemgr/valuemembernode.hxx117
-rw-r--r--configmgr/source/treemgr/valuenodeimpl.hxx72
-rw-r--r--configmgr/source/treemgr/viewaccess.cxx59
-rw-r--r--configmgr/source/treemgr/viewaccess.hxx231
-rw-r--r--configmgr/source/treemgr/viewfactory.hxx56
-rw-r--r--configmgr/source/treemgr/viewnode.cxx108
-rw-r--r--configmgr/source/treemgr/viewnode.hxx203
-rw-r--r--configmgr/source/treemgr/viewstrategy.cxx623
-rw-r--r--configmgr/source/treemgr/viewstrategy.hxx231
-rw-r--r--configmgr/source/xml/basicparser.cxx536
-rw-r--r--configmgr/source/xml/basicparser.hxx178
-rw-r--r--configmgr/source/xml/elementformatter.cxx324
-rw-r--r--configmgr/source/xml/elementformatter.hxx118
-rw-r--r--configmgr/source/xml/elementinfo.hxx119
-rw-r--r--configmgr/source/xml/elementparser.cxx585
-rw-r--r--configmgr/source/xml/elementparser.hxx125
-rw-r--r--configmgr/source/xml/layerparser.cxx371
-rw-r--r--configmgr/source/xml/layerparser.hxx119
-rw-r--r--configmgr/source/xml/layerwriter.cxx544
-rw-r--r--configmgr/source/xml/layerwriter.hxx169
-rw-r--r--configmgr/source/xml/makefile.mk70
-rw-r--r--configmgr/source/xml/matchlocale.cxx387
-rw-r--r--configmgr/source/xml/parsersvc.cxx385
-rw-r--r--configmgr/source/xml/parsersvc.hxx117
-rw-r--r--configmgr/source/xml/schemaparser.cxx409
-rw-r--r--configmgr/source/xml/schemaparser.hxx135
-rw-r--r--configmgr/source/xml/simpletypehelper.cxx57
-rw-r--r--configmgr/source/xml/typeconverter.cxx354
-rw-r--r--configmgr/source/xml/valueconverter.cxx504
-rw-r--r--configmgr/source/xml/valueformatter.cxx498
-rw-r--r--configmgr/source/xml/valueformatter.hxx84
-rw-r--r--configmgr/source/xml/writersvc.cxx261
-rw-r--r--configmgr/source/xml/writersvc.hxx124
-rw-r--r--configmgr/source/xml/xmlstrings.cxx140
-rw-r--r--configmgr/source/xml/xmlstrings.hxx134
-rw-r--r--configmgr/util/cfgmgr.mxp.map4
-rw-r--r--configmgr/util/configmgr.map8
-rw-r--r--configmgr/util/configmgr2.uno.xml582
-rw-r--r--configmgr/util/configmgrl.map8
-rw-r--r--configmgr/util/exports.dxp3
-rw-r--r--configmgr/util/makefile.mk80
-rw-r--r--configmgr/version.mk50
-rw-r--r--configmgr/workben/apitest/cfgadduser.cxx358
-rw-r--r--configmgr/workben/apitest/cfgadmin.cxx520
-rw-r--r--configmgr/workben/apitest/cfgapi.cxx868
-rw-r--r--configmgr/workben/apitest/cfgapi_timetest.cxx960
-rw-r--r--configmgr/workben/apitest/cfgregistry.cxx172
-rw-r--r--configmgr/workben/apitest/cfgupdate.cxx435
-rw-r--r--configmgr/workben/apitest/makefile.mk128
-rw-r--r--configmgr/workben/apitest/sregistry8
-rw-r--r--configmgr/workben/local_io/cfgfile.cxx97
-rw-r--r--configmgr/workben/local_io/cfglocal.cxx623
-rw-r--r--configmgr/workben/local_io/com.sun.star.office.Setup.xml29
-rw-r--r--configmgr/workben/local_io/filetest.cxx93
-rw-r--r--configmgr/workben/local_io/makefile.mk114
-rw-r--r--configmgr/workben/local_io/org.openoffice.test.xml70
-rw-r--r--configmgr/workben/local_io/simpletest.cxx761
-rw-r--r--configmgr/workben/local_io/xmlexport.cxx239
-rw-r--r--configmgr/workben/local_io/xmlimport.cxx472
-rw-r--r--configmgr/workben/logger/exports.dxp3
-rw-r--r--configmgr/workben/logger/loggerdfn.cxx154
-rw-r--r--configmgr/workben/logger/makefile.mk73
-rw-r--r--configmgr/workben/logger/simplelogger.cxx177
-rw-r--r--configmgr/workben/logger/simplelogger.hxx86
-rw-r--r--configmgr/workben/memory/logmechanism.hxx105
-rw-r--r--configmgr/workben/memory/main.cxx80
-rw-r--r--configmgr/workben/memory/makefile.mk259
-rw-r--r--configmgr/workben/memory/memorymeasure.hxx228
-rw-r--r--configmgr/workben/memory/memorytests.cxx1244
-rw-r--r--configmgr/workben/memory/testmodules.cxx87
-rw-r--r--configmgr/workben/memory/testmodules.hxx41
-rw-r--r--configmgr/workben/memory/treeload.cxx84
-rw-r--r--configmgr/workben/memory/treeload.hxx41
429 files changed, 108172 insertions, 0 deletions
diff --git a/configmgr/inc/makefile.mk b/configmgr/inc/makefile.mk
new file mode 100644
index 000000000000..5637340c04c4
--- /dev/null
+++ b/configmgr/inc/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.3 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..
+
+PRJNAME=configmgr
+TARGET=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/configmgr/inc/pch/precompiled_configmgr.cxx b/configmgr/inc/pch/precompiled_configmgr.cxx
new file mode 100644
index 000000000000..577f45114612
--- /dev/null
+++ b/configmgr/inc/pch/precompiled_configmgr.cxx
@@ -0,0 +1,32 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: precompiled_configmgr.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_configmgr.hxx"
+
diff --git a/configmgr/inc/pch/precompiled_configmgr.hxx b/configmgr/inc/pch/precompiled_configmgr.hxx
new file mode 100644
index 000000000000..5cc0d7719f23
--- /dev/null
+++ b/configmgr/inc/pch/precompiled_configmgr.hxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: precompiled_configmgr.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): Generated on 2006-09-01 17:49:35.077252
+
+#ifdef PRECOMPILED_HEADERS
+
+//---MARKER---
+#include "sal/config.h"
+#include "sal/types.h"
+
+#include "com/sun/star/beans/IllegalTypeException.hpp"
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "com/sun/star/beans/Property.hpp"
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/beans/PropertyExistException.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/beans/PropertyVetoException.hpp"
+#include "com/sun/star/beans/UnknownPropertyException.hpp"
+#include "com/sun/star/beans/XExactName.hpp"
+#include "com/sun/star/beans/XHierarchicalPropertySet.hpp"
+#include "com/sun/star/beans/XMultiHierarchicalPropertySet.hpp"
+#include "com/sun/star/beans/XMultiPropertySet.hpp"
+#include "com/sun/star/beans/XMultiPropertyStates.hpp"
+#include "com/sun/star/beans/XPropertiesChangeListener.hpp"
+#include "com/sun/star/beans/XProperty.hpp"
+#include "com/sun/star/beans/XPropertyChangeListener.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/beans/XPropertySetInfo.hpp"
+#include "com/sun/star/beans/XPropertyState.hpp"
+#include "com/sun/star/beans/XPropertyWithState.hpp"
+#include "com/sun/star/beans/XVetoableChangeListener.hpp"
+#include "com/sun/star/configuration/CannotLoadConfigurationException.hpp"
+#include "com/sun/star/configuration/InstallationIncompleteException.hpp"
+#include "com/sun/star/configuration/InvalidBootstrapFileException.hpp"
+#include "com/sun/star/configuration/MissingBootstrapFileException.hpp"
+#include "com/sun/star/configuration/XTemplateContainer.hpp"
+#include "com/sun/star/configuration/XTemplateInstance.hpp"
+#include "com/sun/star/configuration/backend/AuthenticationFailedException.hpp"
+#include "com/sun/star/configuration/backend/BackendAccessException.hpp"
+#include "com/sun/star/configuration/backend/BackendSetupException.hpp"
+#include "com/sun/star/configuration/backend/CannotConnectException.hpp"
+#include "com/sun/star/configuration/backend/ComponentChangeEvent.hpp"
+#include "com/sun/star/configuration/backend/ConnectionLostException.hpp"
+#include "com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp"
+#include "com/sun/star/configuration/backend/InvalidAuthenticationMechanismException.hpp"
+#include "com/sun/star/configuration/backend/MalformedDataException.hpp"
+#include "com/sun/star/configuration/backend/MergeRecoveryRequest.hpp"
+#include "com/sun/star/configuration/backend/NodeAttribute.hpp"
+#include "com/sun/star/configuration/backend/PropertyInfo.hpp"
+#include "com/sun/star/configuration/backend/SchemaAttribute.hpp"
+#include "com/sun/star/configuration/backend/StratumCreationException.hpp"
+#include "com/sun/star/configuration/backend/TemplateIdentifier.hpp"
+#include "com/sun/star/configuration/backend/XBackend.hpp"
+#include "com/sun/star/configuration/backend/XBackendChangesListener.hpp"
+#include "com/sun/star/configuration/backend/XBackendChangesNotifier.hpp"
+#include "com/sun/star/configuration/backend/XBackendEntities.hpp"
+#include "com/sun/star/configuration/backend/XCompositeLayer.hpp"
+#include "com/sun/star/configuration/backend/XLayer.hpp"
+#include "com/sun/star/configuration/backend/XLayerContentDescriber.hpp"
+#include "com/sun/star/configuration/backend/XLayerHandler.hpp"
+#include "com/sun/star/configuration/backend/XLayerImporter.hpp"
+#include "com/sun/star/configuration/backend/XMultiLayerStratum.hpp"
+#include "com/sun/star/configuration/backend/XSchema.hpp"
+#include "com/sun/star/configuration/backend/XSchemaHandler.hpp"
+#include "com/sun/star/configuration/backend/XSchemaSupplier.hpp"
+#include "com/sun/star/configuration/backend/XSingleLayerStratum.hpp"
+#include "com/sun/star/configuration/backend/XUpdatableLayer.hpp"
+#include "com/sun/star/configuration/backend/XUpdateHandler.hpp"
+#include "com/sun/star/configuration/backend/XVersionedSchemaSupplier.hpp"
+#include "com/sun/star/container/ElementExistException.hpp"
+#include "com/sun/star/container/NoSuchElementException.hpp"
+#include "com/sun/star/container/XChild.hpp"
+#include "com/sun/star/container/XContainer.hpp"
+#include "com/sun/star/container/XContainerListener.hpp"
+#include "com/sun/star/container/XContentEnumerationAccess.hpp"
+#include "com/sun/star/container/XEnumeration.hpp"
+#include "com/sun/star/container/XHierarchicalName.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/container/XNameContainer.hpp"
+#include "com/sun/star/container/XNameReplace.hpp"
+#include "com/sun/star/container/XNamed.hpp"
+#include "com/sun/star/io/BufferSizeExceededException.hpp"
+#include "com/sun/star/io/IOException.hpp"
+#include "com/sun/star/io/UnexpectedEOFException.hpp"
+#include "com/sun/star/io/WrongFormatException.hpp"
+#include "com/sun/star/io/XActiveDataControl.hpp"
+#include "com/sun/star/io/XActiveDataSink.hpp"
+#include "com/sun/star/io/XActiveDataSource.hpp"
+#include "com/sun/star/io/XDataExporter.hpp"
+#include "com/sun/star/io/XDataImporter.hpp"
+#include "com/sun/star/io/XDataInputStream.hpp"
+#include "com/sun/star/io/XDataOutputStream.hpp"
+#include "com/sun/star/io/XDataTransferEventListener.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/io/XOutputStream.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/IllegalAccessException.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/Locale.hpp"
+#include "com/sun/star/lang/NoSupportException.hpp"
+#include "com/sun/star/lang/NullPointerException.hpp"
+#include "com/sun/star/lang/ServiceNotRegisteredException.hpp"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/lang/XLocalizable.hpp"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleComponentFactory.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/lang/XTypeProvider.hpp"
+#include "com/sun/star/lang/XUnoTunnel.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/registry/XSimpleRegistry.hpp"
+#include "com/sun/star/script/FailReason.hpp"
+#include "com/sun/star/script/XTypeConverter.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/task/XInteractionDisapprove.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "com/sun/star/task/XInteractionRequest.hpp"
+#include "com/sun/star/task/XInteractionRetry.hpp"
+#include "com/sun/star/task/XJob.hpp"
+#include "com/sun/star/uno/Any.h"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.h"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.h"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/Type.hxx"
+#include "com/sun/star/uno/TypeClass.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XCurrentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/XChangesBatch.hpp"
+#include "com/sun/star/util/XChangesListener.hpp"
+#include "com/sun/star/util/XChangesNotifier.hpp"
+#include "com/sun/star/util/XFlushable.hpp"
+#include "com/sun/star/util/XRefreshable.hpp"
+#include "com/sun/star/util/XStringEscape.hpp"
+#include "com/sun/star/util/XTimeStamped.hpp"
+#include "com/sun/star/util/logging/LogLevel.hpp"
+#include "com/sun/star/util/logging/XLogger.hpp"
+#include "com/sun/star/xml/sax/InputSource.hpp"
+#include "com/sun/star/xml/sax/SAXException.hpp"
+#include "com/sun/star/xml/sax/SAXParseException.hpp"
+#include "com/sun/star/xml/sax/XAttributeList.hpp"
+#include "com/sun/star/xml/sax/XDocumentHandler.hpp"
+#include "com/sun/star/xml/sax/XExtendedDocumentHandler.hpp"
+#include "com/sun/star/xml/sax/XParser.hpp"
+
+#include "comphelper/processfactory.hxx"
+#include "comphelper/propertycontainer.hxx"
+#include "comphelper/sequence.hxx"
+#include "comphelper/stl_types.hxx"
+
+#include "cppuhelper/bootstrap.hxx"
+#include "cppuhelper/component_context.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/interfacecontainer.hxx"
+#include "cppuhelper/propshlp.hxx"
+#include "cppuhelper/queryinterface.hxx"
+#include "cppuhelper/servicefactory.hxx"
+#include "cppuhelper/typeprovider.hxx"
+#include "cppuhelper/weak.hxx"
+
+#include "osl/conditn.hxx"
+#include "osl/diagnose.h"
+#include "osl/file.h"
+#include "osl/file.hxx"
+#include "osl/interlck.h"
+#include "osl/module.hxx"
+#include "osl/mutex.hxx"
+#include "osl/process.h"
+#include "osl/thread.h"
+#include "osl/time.h"
+
+#include "rtl/alloc.h"
+#include "rtl/bootstrap.h"
+#include "rtl/bootstrap.hxx"
+#include "rtl/logfile.hxx"
+#include "rtl/process.h"
+#include "rtl/ref.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/string.h"
+#include "rtl/string.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+
+#include "sal/main.h"
+
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "sys/timeb.h"
+
+#include "typelib/typedescription.hxx"
+
+#include "uno/any2.h"
+#include "uno/current_context.hxx"
+
+
+
+#include "vos/conditn.hxx"
+#include "vos/pipe.hxx"
+#include "vos/ref.hxx"
+#include "vos/refernce.hxx"
+#include "vos/socket.hxx"
+#include "vos/thread.hxx"
+#include "vos/timer.hxx"
+//---MARKER---
+
+#endif
diff --git a/configmgr/makefile.pmk b/configmgr/makefile.pmk
new file mode 100644
index 000000000000..0ef67b43696b
--- /dev/null
+++ b/configmgr/makefile.pmk
@@ -0,0 +1,32 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: $
+#
+# $Revision: $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+VISIBILITY_HIDDEN = TRUE
diff --git a/configmgr/prj/build.lst b/configmgr/prj/build.lst
new file mode 100644
index 000000000000..a3d93b598abe
--- /dev/null
+++ b/configmgr/prj/build.lst
@@ -0,0 +1,18 @@
+cg configmgr : BOOST:boost offapi comphelper cppuhelper salhelper tools vos NULL
+cg configmgr usr1 - all cg_mkout NULL
+cg configmgr\inc nmake - all cg_inc NULL
+cg configmgr\source\misc nmake - all cg_misc cg_inc NULL
+cg configmgr\source\data nmake - all cg_data cg_inc NULL
+cg configmgr\source\tree nmake - all cg_tree cg_inc NULL
+cg configmgr\source\treecache nmake - all cg_trcache cg_inc NULL
+cg configmgr\source\xml nmake - all cg_xml cg_inc NULL
+cg configmgr\source\backend nmake - all cg_backend cg_inc NULL
+cg configmgr\source\backendhelper nmake - all cg_backendhelper cg_inc NULL
+cg configmgr\source\api nmake - all cg_api cg_inc NULL
+cg configmgr\source\api2 nmake - all cg_api2 cg_inc NULL
+cg configmgr\source\treemgr nmake - all cg_treemgr cg_inc NULL
+cg configmgr\source\registry nmake - all cg_reg cg_inc NULL
+cg configmgr\source\platformbe nmake - all cg_platformbe cg_inc NULL
+cg configmgr\util nmake - all cg_util cg_platformbe cg_api cg_api2 cg_misc cg_reg cg_trcache cg_data cg_tree cg_treemgr cg_xml cg_backend cg_localbe NULL
+cg configmgr\source\localbe nmake - all cg_localbe cg_inc NULL
+
diff --git a/configmgr/prj/d.lst b/configmgr/prj/d.lst
new file mode 100644
index 000000000000..3f4a1d35a121
--- /dev/null
+++ b/configmgr/prj/d.lst
@@ -0,0 +1,10 @@
+mkdir: %_DEST%\inc%_EXT%\configmgr
+..\%__SRC%\lib\behelper.uno.so %_DEST%\lib%_EXT%\behelper.uno.so
+..\%__SRC%\lib\configmgr*.uno.so %_DEST%\lib%_EXT%\configmgr*.uno.so
+..\%__SRC%\lib\sysmgr*.uno.so %_DEST%\lib%_EXT%\sysmgr*.uno.so
+..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+..\%__SRC%\bin\behelper*.dll %_DEST%\bin%_EXT%\behelper*.dll
+..\%__SRC%\bin\configmg*.dll %_DEST%\bin%_EXT%\configmg*.dll
+..\%__SRC%\bin\sysmgr*.dll %_DEST%\bin%_EXT%\sysmgr*.dll
+
+..\%__SRC%\misc\configmgr2.uno.xml %_DEST%\xml%_EXT%\configmgr2.uno.xml
diff --git a/configmgr/qa/unit/common.hxx b/configmgr/qa/unit/common.hxx
new file mode 100644
index 000000000000..d53d52d55ad7
--- /dev/null
+++ b/configmgr/qa/unit/common.hxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: common.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "sal/config.h"
+#include <cstdlib>
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/beans/XPropertyState.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/container/XNameReplace.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/util/XChangesBatch.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "cppuhelper/component_context.hxx"
+#include "cppuhelper/servicefactory.hxx"
+#include "cppunit/simpleheader.hxx"
+#include "osl/file.hxx"
+#include "osl/thread.h"
+#include "osl/process.h"
+#include "rtl/string.h"
+#include "rtl/bootstrap.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+namespace css = com::sun::star;
+
+#define CATCH_FAIL(msg) \
+ catch (const css::uno::Exception &e) { \
+ t_print ("msg '%s'\n", rtl::OUStringToOString (e.Message, RTL_TEXTENCODING_UTF8).getStr()); \
+ CPPUNIT_FAIL( msg ); \
+ throw; \
+ }
+
+class Magic
+{
+ rtl::OUString maTempDir;
+ public:
+ Magic();
+ ~Magic();
+};
+
+class Test: public CppUnit::TestFixture {
+ Magic *mpMagic;
+public:
+ // init
+ virtual void setUp();
+ virtual void tearDown();
+
+ // helpers
+ void normalizePathKey (rtl::OString &rPath, rtl::OString &rKey);
+ css::uno::Reference< css::uno::XInterface > createView(const sal_Char *pNodepath, bool bUpdate);
+ css::uno::Any getKey (const sal_Char *pPath, rtl::OUString aName);
+ css::uno::Any getKey (const sal_Char *pPath, const sal_Char *pName)
+ { return getKey (pPath, rtl::OUString::createFromAscii (pName)); }
+ void setKey (const sal_Char *pPath, rtl::OUString aName, css::uno::Any a);
+ void resetKey (const sal_Char *pPath, rtl::OUString aName);
+
+ // tests
+ void keyFetch();
+ void keySet();
+ void keyReset();
+ void readCommands();
+ void threadTests();
+ void recursiveTests();
+ void eventTests();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(keyFetch);
+ CPPUNIT_TEST(keySet);
+ CPPUNIT_TEST(keyReset);
+ CPPUNIT_TEST(readCommands);
+ CPPUNIT_TEST(threadTests);
+ CPPUNIT_TEST(recursiveTests);
+ CPPUNIT_TEST(eventTests);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ css::uno::Reference< css::uno::XComponentContext > mxContext;
+ css::uno::Reference< css::lang::XMultiServiceFactory > mxProvider;
+};
+
+void disposeComponent (const css::uno::Reference<css::uno::XInterface> &xComp);
diff --git a/configmgr/qa/unit/configmgrrc b/configmgr/qa/unit/configmgrrc
new file mode 100644
index 000000000000..b162e77c2e00
--- /dev/null
+++ b/configmgr/qa/unit/configmgrrc
@@ -0,0 +1,22 @@
+[Bootstrap]
+CFG_ServerType=uno
+BootstrapFile=$ORIGIN/bootstraprc
+VersionFile=$ORIGIN/versionrc
+UnoFile=$ORIGIN/unorc
+BaseInstallation=${$BootstrapFile:BaseInstallation}
+UserInstallation=${$BootstrapFile:UserInstallation}
+CFG_SchemaVersion=${$VersionFile:buildid}
+CFG_SchemaDataUrl=$BaseInstallation/schema
+CFG_DefaultLayerUrls=$BaseInstallation
+CFG_CacheDisposeDelay=900
+CFG_CacheDisposeInterval=60
+CFG_CacheWriteInterval=2
+CFG_UserLayerUrl=$UserInstallation
+CFG_CacheUrl=$BaseInstallation/cache
+CFG_DefaultLayerUrl=$BaseInstallation
+CFG_BackendService=com.sun.star.comp.configuration.backend.MultiStratumBackend
+CFG_SchemaSupplier=com.sun.star.comp.configuration.backend.LocalSchemaSupplier
+CFG_LocalDataSvc=com.sun.star.comp.configuration.backend.LocalStratum
+CFG_LocalModuleDataSvc=com.sun.star.comp.configuration.backend.LocalMultiStratum
+# CFG_Strata=${CFG_LocalDataSvc}:$CFG_DefaultLayerUrl;?com.sun.star.comp.configuration.backend.SystemIntegration:;${CFG_LocalDataSvc}:$CFG_UserLayerUrl
+CFG_Strata=${CFG_LocalDataSvc}:$CFG_DefaultLayerUrl;${CFG_LocalDataSvc}:$CFG_UserLayerUrl
diff --git a/configmgr/qa/unit/data/org/openoffice/Setup.xcu b/configmgr/qa/unit/data/org/openoffice/Setup.xcu
new file mode 100644
index 000000000000..eae7bece66bb
--- /dev/null
+++ b/configmgr/qa/unit/data/org/openoffice/Setup.xcu
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Setup.xcu,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************ -->
+<!DOCTYPE oor:component-data SYSTEM "../../../component-update.dtd">
+<oor:component-data oor:name="Setup" oor:package="org.openoffice" xmlns:oor="http://openoffice.org/2001/registry" xmlns:install="http://openoffice.org/2004/installation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <node oor:name="L10N">
+ <prop oor:name="ooLocale" oor:type="xs:string">
+ <value>en-US</value>
+ </prop>
+ </node>
+ <node oor:name="Test">
+ <prop oor:name="ABoolean" oor:type="xs:boolean">
+ <value>true</value>
+ </prop>
+ <prop oor:name="AString" oor:type="xs:string">
+ <value>Foo</value>
+ </prop>
+ </node>
+</oor:component-data>
diff --git a/configmgr/qa/unit/data/org/openoffice/UI/GenericCommands.xcu b/configmgr/qa/unit/data/org/openoffice/UI/GenericCommands.xcu
new file mode 100644
index 000000000000..f066fb0b96dc
--- /dev/null
+++ b/configmgr/qa/unit/data/org/openoffice/UI/GenericCommands.xcu
@@ -0,0 +1,5072 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: GenericCommands.xcu,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************ -->
+<!DOCTYPE oor:component-data SYSTEM "../../../../../component-update.dtd">
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oor:name="GenericCommands" oor:package="org.openoffice.UI">
+ <node oor:name="UserInterface">
+ <node oor:name="Commands">
+ <node oor:name="dotuno:WebHtml" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Preview in Web Browser</value>
+ </prop>
+ </node>
+ <node oor:name="dotuno:NewPresentation" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">New Presentation</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkGalleryFloater" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fontwork Gallery</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fontwork Shape</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkSameLetterHeights" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fontwork Same Letter Heights</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkAlignmentFloater" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fontwork Alignment</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkCharacterSpacingFloater" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fontwork Character Spacing</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Basic Shapes</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Symbol Shapes</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Block Arrows</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowcharts</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CalloutShapes" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Callouts</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Stars</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.rectangle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rectangle</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.round-rectangle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rectangle, Rounded</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.quadrat" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Square</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.round-quadrat" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Square, Rounded</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.circle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.ellipse" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ellipse</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.circle-pie" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle Pie</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.isosceles-triangle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Isosceles Triangle</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.right-triangle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Right Triangle</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.trapezoid" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Trapezoid</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.diamond" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Diamond</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.parallelogram" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Parallelogram</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.pentagon" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Regular Pentagon</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.hexagon" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Hexagon</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.octagon" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Octagon</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.cross" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Cross</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.ring" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ring</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.block-arc" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Block Arc</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.can" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Cylinder</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.cube" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Cube</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.paper" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Folded Corner</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicShapes.frame" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Frame</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.smiley" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Smiley Face</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.sun" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Sun</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.moon" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Moon</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.lightning" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Lightning Bolt</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.heart" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Heart</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.flower" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flower</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.cloud" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Cloud</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.forbidden" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">"Prohibited" Symbol</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.puzzle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Puzzle</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.bracket-pair" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Double Bracket</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.left-bracket" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Left Bracket</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.right-bracket" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Right Bracket</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.brace-pair" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Double Brace</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.left-brace" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Left Brace</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.right-brace" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Right Brace</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.quad-bevel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Square Bevel</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.octagon-bevel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Octagon Bevel</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SymbolShapes.diamond-bevel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Diamond Bevel</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.left-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Left Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.right-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Right Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.up-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Up Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.down-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Down Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.left-right-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Left and Right Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.up-down-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Up and Down Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.up-right-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Up and Right Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.up-right-down-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Up, Right and Down Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.quad-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">4-way Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.corner-right-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Corner Right Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.split-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Split Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.striped-right-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Striped Right Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.notched-right-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Notched Right Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.pentagon-right" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Pentagon</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.chevron" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Chevron</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.right-arrow-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Right Arrow Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.left-arrow-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Left Arrow Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.up-arrow-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Up Arrow Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.down-arrow-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Down Arrow Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.left-right-arrow-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Left and Right Arrow Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.up-down-arrow-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Up and Down Arrow Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.up-right-arrow-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Up and Right Arrow Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.quad-arrow-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">4-way Arrow Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.circular-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circular Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.split-round-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Right or Left Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ArrowShapes.s-sharped-arrow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">S-shaped Arrow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-process" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Process</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-alternate-process" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Alternate Process</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-decision" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Decision</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-data" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Data</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-predefined-process" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Predefined Process</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-internal-storage" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Internal Storage</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-document" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Document</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-multidocument" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Multidocument</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-terminator" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Terminator</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-preparation" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Preparation</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-manual-input" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Manual Input</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-manual-operation" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Manual Operation</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-connector" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Connector</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-off-page-connector" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Off-page Connector</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-card" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Card</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-punched-tape" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Punched Tape</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-summing-junction" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Summing Junction</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-or" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Or</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-collate" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Collate</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-sort" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Sort</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-extract" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Extract</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-merge" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Merge</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-stored-data" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Stored Data</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-delay" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Delay</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-sequential-access" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Sequential Access</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-magnetic-disk" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Magnetic Disc</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-direct-access-storage" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Direct Access Storage</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FlowChartShapes.flowchart-display" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flowchart: Display</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CalloutShapes.rectangular-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rectangular Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CalloutShapes.round-rectangular-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rounded Rectangular Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CalloutShapes.round-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Round Callout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CalloutShapes.cloud-callout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Cloud</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CalloutShapes.line-callout-1" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Callout 1</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CalloutShapes.line-callout-2" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Callout 2</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CalloutShapes.line-callout-3" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Callout 3</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.bang" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Explosion</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.star4" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">4-Point Star</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.star5" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">5-Point Star</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.star6" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">6-Point Star</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.star8" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">8-Point Star</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.star12" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">12-Point Star</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.star24" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">24-Point Star</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.concave-star6" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">6-Point Star, concave</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.vertical-scroll" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Vertical Scroll</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.horizontal-scroll" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Horizontal Scroll</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.signet" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Signet</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StarShapes.doorplate" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Doorplate</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-plain-text" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Plain Text</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-wave" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Wave</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-inflate" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Inflate</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-stop" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Stop</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-curve-up" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Curve Up</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-curve-down" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Curve Down</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-triangle-up" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Triangle Up</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-triangle-down" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Triangle Down</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-fade-right" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fade Right</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-fade-left" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fade Left</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-fade-up" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fade Up</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-fade-down" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fade Down</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-slant-up" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Slant Up</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-slant-down" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Slant Down</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-fade-up-and-right" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fade Up and Right</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-fade-up-and-left" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fade Up and Left</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-chevron-up" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Chevron Up</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-chevron-down" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Chevron Down</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-arch-up-curve" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arch Up (Curve)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-arch-down-curve" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arch Down (Curve)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-arch-left-curve" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arch Left (Curve)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-arch-right-curve" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arch Right (Curve)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-circle-curve" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle (Curve)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-open-circle-curve" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Open Circle (Curve)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-arch-up-pour" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arch Up (Pour)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-arch-down-pour" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arch Down (Pour)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-arch-left-pour" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arch Left (Pour)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-arch-right-pour" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arch Right (Pour)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-circle-pour" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle (Pour)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontworkShapeType.fontwork-open-circle-pour" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Open Circle (Pour)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:UndoAction" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Can't Undo</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrabControlFocus" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Control Focus</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ScrollBar" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Scrollbar</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Zoom" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Zoom...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SpinButton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Spin Button</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToScrollBar" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Scrollbar</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToSpinButton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Spin Button</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToNavigationBar" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Navigation Bar</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ToggleBreakPoint" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Breakpoint On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Text" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LaunchStarImage" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Start Image Editor</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AddWatch" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Enable Watch</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CharFontName" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Font Name</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChooseMacro" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Macro</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Italic" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Italic</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Bold" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Bold</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ModuleDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Module</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Shadowed" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Shadow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ObjectCatalog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Object Catalog</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineFont" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Outline</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Strikeout" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Strikethrough</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HelpOnHelp" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Help on Help</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Underline" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Underline</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HelpIndex" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">%PRODUCTNAME ~Help</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontHeight" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Font Size</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtendedHelp" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">What's ~This?</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ActiveHelp" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Extended Tips</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Color" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Font Color</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HelpTip" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Tips</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MatchGroup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Find Parenthesis</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicIDEAppear" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Edit Macros</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LibSelector" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Current Library</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LeftPara" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Align Left</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>3</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RightPara" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Align Right</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>3</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CenterPara" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Centered</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>3</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SendFax" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Send Default Fax</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:JustifyPara" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Justified</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HelpChooseFile" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Choose Help File</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SpacePara1" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Spacing: 1</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SpacePara15" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Spacing : 1.5</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SpacePara2" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Spacing : 2</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StatusGetPosition" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Position</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StatusGetTitle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Current Basic Module</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ManageBreakPoints" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Manage Breakpoints</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TransformDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Position and Si~ze...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafLuminance" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Brightness</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafContrast" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Contrast</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomToolBox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafRed" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Red</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomPlus" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom In</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafGreen" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Green</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomIn" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom Out</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomMinus" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom Out</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafBlue" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Blue</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OptionsTreeDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Options...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Zoom100Percent" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom 100%</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafGamma" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Gamma</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomPage" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom Page</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafTransparence" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Transparency</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomOptimal" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Optimal</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafInvert" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Invert</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Line" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafMode" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Graphics mode</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Line_Diagonal" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line (45°)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Rect" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rectangle</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Rect_Rounded" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rectangle, Rounded</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Ellipse" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ellipse</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BibliographyComponent" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Bibliography Database</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Pie" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ellipse Pie</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierEliminatePoints" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Eliminate Points</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DatasourceAdministration" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Data Sources...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GrafAttrCrop" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Crop</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:NewDoc" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">New Document From Template</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Arc" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arc</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Open" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Open...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CircleCut" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle Segment</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SaveAs" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Save ~As...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CloseDoc" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Close</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Print" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Print...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierFill" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Curve, Filled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Save" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Save</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierInsert" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Insert Points</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierDelete" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Delete Points</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierMove" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Move Points</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Reload" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Reload</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierClose" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Close Bézier</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:PrintDefault" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Print File Directly</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierSmooth" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Smooth Transition</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ToggleObjectBezierMode" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Poi~nts</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertAnnotation" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Not~e</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierCutLine" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Split Curve</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SelectObject" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ToggleObjectRotateMode" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Rotate</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ObjectAlignLeft" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Left</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AlignCenter" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Centered</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ObjectAlignRight" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Right</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AlignUp" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Top</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AlignMiddle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">C~enter</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AlignDown" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Bottom</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:VerticalText" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Vertical Text</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:VerticalCaption" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Vertical Callouts</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TextdirectionLeftToRight" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text direction from left to right</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TextdirectionTopToBottom" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text direction from top to bottom</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertObjectChart" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Chart...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DefaultBullet" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Bullets On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormatArea" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">A~rea...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormatLine" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">L~ine...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChangeCaseToUpper" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Uppercase</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChooseControls" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Insert Controls</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChangeCaseToLower" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Lowercase</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChangeCaseToHalfWidth" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">H~alf-width</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertDoc" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~File...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertPushbutton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Button</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChangeCaseToFullWidth" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Full-width</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DefaultNumbering" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Numbering On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierConvert" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Convert to Curve</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Stop" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Stop Loading</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Radiobutton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Option Button</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChangeCaseToHiragana" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Hiragana</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierEdge" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Corner Point</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Checkbox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Check Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChangeCaseToKatakana" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Katakana</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SetDocumentProperties" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Propert~ies...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BezierSymmetric" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Symmetric Transition</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineUp" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Move Up</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AddDirect" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~New</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineDown" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Move Down</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SaveAsTemplate" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Save...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineLeft" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Promote</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DesignerDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">St~yles and Formatting</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineRight" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Demote</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Organizer" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Organize...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineFormat" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Formatting On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineCollapseAll" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">First Level</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineBullet" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Bullets and Numbering...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:EditDoc" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Edit File</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertImageControl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Image Control</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BrowseView" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Web Layout</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ProgressBar" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Progress Bar</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:PlugInsActive" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">P~lug-in</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HFixedLine" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Horizontal Line</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FileDocument" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">File Document</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:VFixedLine" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Vertical Line</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChoosePolygon" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Symbol Selection</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ShowBrowser" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Display Properties</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FillStyle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Area Style / Filling</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoPilotAddressDataSource" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">AutoPilot: Address Data Source</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FillColor" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fill Color</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StyleApply" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Apply Style</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AddDateField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Date Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertTimeField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Time Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StyleNewByExample" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">New Style from Selection</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:XLineStyle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Style</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertNumericField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Numeric Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StyleUpdateByExample" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Update Style</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LineDash" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Dash/Dot</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertCurrencyField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Currency Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LineWidth" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Width</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertFormattedField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Formatted Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:XLineColor" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Color</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertPatternField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Pattern Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertFileControl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">File Selection</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertTreeControl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Tree Control</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ShowPropBrowser" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Properties</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertObject" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~OLE Object...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertObjectFloatingFrame" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Float~ing Frame</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:EnterGroup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Enter Group</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LeaveGroup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">E~xit group</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HideDetail" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Hide Details</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomPageWidth" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom Page Width</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ShowDetail" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Show Details</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomObjects" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Object Zoom</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ParaLeftToRight" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Left-To-Right</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>3</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Group" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Group...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ParaRightToLeft" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Right-To-Left</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>3</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Ungroup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Ungroup...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BackgroundColor" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Background Color</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BackgroundPatternController" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Background Pattern</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OpenHyperlinkOnCursor" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Open Hyperlink</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OpenSmartTagMenuOnCursor" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Open Smart Tag Menu</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StyleCatalog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Catalog...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertImage" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Insert from Image Editor</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SetBorderStyle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Borders</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertMath" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Formula...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertFixedText" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Label field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ObjectMenue" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ob~ject</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Groupbox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Group Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OpenXMLFilterSettings" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~XML Filter Settings...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertEdit" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HangulHanjaConversion" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Hangul/Hanja Conversion...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ChineseConversion" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Chinese translation...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertListbox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">List Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Combobox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Combo Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Spinbutton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Spin Button</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HScrollbar" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Horizontal Scroll Bar</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:VScrollbar" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Vertical Scroll Bar</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Preview" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Preview</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:URLButton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">URL Button</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ModifiedStatus" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Document Modified</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SelectMode" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:IsLoading" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Load Document</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TestMode" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Test Mode On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LineStyle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Style</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FrameLineColor" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Line Color (of the border)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OpenTemplate" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Edit...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OpenUrl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Load URL</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertSpreadsheet" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Sp~readsheet</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertMode" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Insert Mode</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Size" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Size</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StateTableCell" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Cell</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoPilotMenu" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Wizards</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineCollapse" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Hide Subpoints</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineExpandAll" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">All Levels</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OutlineExpand" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Show Subpoints</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:NewWindow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~New Window</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ClearOutline" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Remove</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HelplinesMove" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Guides When Moving</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CloseWin" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Close Window</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GridUse" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Snap to Grid</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertTextFrame" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Insert Text Frame</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FullScreen" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">F~ull Screen</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertGraphic" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~From File...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoFormat" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Auto~Format...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SpellDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Spellcheck...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertDraw" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Show Draw Functions</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:NewFrameSet" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">New FrameSet</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Thesaurus" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Thesaurus...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DrawText" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DrawCaption" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Callouts</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontWork" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">F~ontwork</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SaveAsUrl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Save Document As URL</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ObjectForwardOne" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Forward One</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ObjectBackOne" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Back One</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:EditFrameSet" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Edit FrameSet</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SplitHorizontal" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Split Frame Horizontally</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SplitVertical" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Split Frame Vertically</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SplitParentHorizontal" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Split FrameSet Horizontally</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SplitParentVertical" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Split FrameSet Vertically</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ModifyFrame" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Frame Properties</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DeleteFrame" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Delete Frame</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SetObjectToBackground" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">To Background</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SetObjectToForeground" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">To Foreground</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertLabels" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Insert Labels</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertBusinessCard" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Insert business cards</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertPlugin" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Plug-in...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BringToFront" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Bring to Front</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertApplet" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Applet...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SendToBack" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Send to Back</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SourceView" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">HT~ML Source</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertSound" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Sound...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertVideo" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Video...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HyperlinkDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Hyperlink</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Merge" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Merge</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Substract" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Subtract</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SuperScript" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Superscript</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Intersect" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">I~ntersect</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SubScript" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Subscript</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FontDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">C~haracter...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DistributeSelection" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Distribution...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ParagraphDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">P~aragraph...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FillShadow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Shadow</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LineEndStyle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Arrow Style</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Redo" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Can't Restore</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Undo" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Can't Undo</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormatPaintbrush" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Format Paintbrush</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Repeat" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Repeat</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ClearHistory" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Delete History</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Cut" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Cu~t</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Copy" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Copy</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Paste" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Paste</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Delete" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Delete C~ontents...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TwainSelect" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Select Source...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TwainTransfer" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Request...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Select" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select ~All</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ContourDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Edit Contour...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SelectAll" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select ~All</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoDown" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Move Down</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoUp" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Move Up</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoLeft" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Move Left</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoRight" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Move Right</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoDownBlock" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Page Down</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoUpBlock" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Page Up</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BmpMask" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Eyedropper</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoLeftBlock" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Page Left</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FrameSpacing" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">FrameSet Spacing</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoToEndOfData" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">To File End</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoToStart" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">To File Begin</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoToStartOfRow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">To Document Begin</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertHyperlink" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Hyperlink Bar</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoToEndOfRow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">To Document End</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Navigator" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Navigator</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RestoreEditingView" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Restore Editing View</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicBreak" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Interrupt Macro</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TextFitToSize" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Fit to Frame</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ImageMapDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">ImageMap</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoDownSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Down</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoUpSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Up</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoLeftSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Left</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoRightSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Right</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoDownBlockSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Page Down</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoUpBlockSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Page Up</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Rect_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rectangle, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Rect_Rounded_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rounded Rectangle, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoLeftBlockSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select Page Left</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Square" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Square</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Square_Rounded" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rounded Square</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OnlineRegistrationDlg" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Registration...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoToStartSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select to File Begin</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Square_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Square, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Square_Rounded_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Rounded Square, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoToEndOfDataSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select to File End</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Ellipse_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ellipse, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoToStartOfRowSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select to Document Begin</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Circle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GoToEndOfRowSel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Select to Document End</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Circle_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Pie_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ellipse Pie, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CirclePie" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle Pie</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CirclePie_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle Pie, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CircleArc" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle Arc</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CircleCut_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Circle Segment, Unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:EllipseCut" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ellipse Segment</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:EllipseCut_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Ellipse Segment, unfilled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Polygon_Diagonal" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Polygon (45°), Filled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Polygon_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Polygon</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Polygon_Diagonal_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Polygon (45°)</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Bezier_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Curve</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomNext" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom Next</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ZoomPrevious" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Zoom Previous</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GridVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Display Grid</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Flash" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Flash</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ToolsMacroEdit" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Edit Macros</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InternetDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Internet Options</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ColorControl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Color Bar</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoCorrectDlg" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~AutoCorrect...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoPilotPresentations" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">AutoPilot: Presentation</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoPilotAgenda" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">AutoPilot: Agenda</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoPilotFax" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">AutoPilot: Fax</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoPilotLetter" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">AutoPilot: Letter</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:VersionDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Versions...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoPilotMemo" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">AutoPilot: Memo</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CompareDocuments" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Co~mpare Document...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MergeDocuments" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Merge Document...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SwEditOptions" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text Document Options</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SdEditOptions" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Presentation Options</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ScEditOptions" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Spreadsheet Options</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SmEditOptions" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Formula Options</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SchEditOptions" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Chart Options</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SimEditOptions" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Image Options</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FrameName" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Name</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FrameContent" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Contents</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GetColorTable" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Color Palette</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExportTo" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Expor~t...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SdGraphicOptions" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Presentation Graphic Options</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:NavigationBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Navigation Bar Visible</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormatGroup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Group</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormatUngroup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Ungroup</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SetDefault" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Default Formatting</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DecrementIndent" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Decrease Indent</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:IncrementIndent" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Increase Indent</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>7</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Freeline" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Freeform Line, Filled</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Freeline_Unfilled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Freeform Line</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Text_Marquee" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text Animation</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterToolbox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Filter</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterInvert" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Invert</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterSmooth" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Smooth</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterSharpen" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Sharpen</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterRemoveNoise" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Remove Noise</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterSobel" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Charcoal Sketch</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterMosaic" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Mosaic</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterRelief" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Relief</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterPoster" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Posterize</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterPopart" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Pop Art</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterSepia" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Aging</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GraphicFilterSolarize" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Solarization</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SpellOnline" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~AutoSpellcheck</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HideSpellMark" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Do Not Mark Errors</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AddressBookSource" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Address Book Source...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RubyDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">As~ian phonetic guide...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:InsertSymbol" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">S~pecial Character...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ViewDataSourceBrowser" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Data Sources</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MenuBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Menu On/Off</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MacroRecorder" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Record Macro</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StopRecording" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Stop Recording</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SendMailDocAsPDF" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">E-mail as P~DF...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExportToPDF" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Export as P~DF...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConfigureDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Customize...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExportDirectToPDF" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Export Directly as PDF</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ObjectBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Object Bar</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConfigureToolboxVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Customi~ze...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ToolBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Main ~Toolbar</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FunctionBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Function Bar</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ShowImeStatusWindow" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Input M~ethod Status</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OptionBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Optio~n Bar</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HelpSupport" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Support</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:StatusBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Status ~Bar</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MacroBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Macro Toolbar On/Off</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonTaskBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Presentation</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SaveConfiguration" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Save configuration</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TaskBarVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value/>
+ </prop>
+ </node>
+ <node oor:name=".uno:LoadConfiguration" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Load Configuration</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LoadBasic" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Insert BASIC Source</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SaveBasicAs" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Save BASIC</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExportDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Export Dialog</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CompileBasic" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Compile</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RunBasic" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Run BASIC</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicStepInto" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Step Into</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicStepOver" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Step Over</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicStop" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Stop Macro</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MacroDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">%PRODUCTNAME ~Basic...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MacroOrganizer?TabId:short=1" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Organize ~Dialogs...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ScriptOrganizer" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Organize Macros</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RunMacro" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">R~un Macro...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Gallery" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Gallery</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SearchDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Find &amp; Replace...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:HelperDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Help ~Agent</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:BasicStepOut" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Step Out</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Config" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Controls</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MoreControls" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">More Controls</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormDesignTools" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Form Design</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Pushbutton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Push Button</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RadioButton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Option Button</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CheckBox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Check Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Label" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Label Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:GroupBox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Group Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Edit" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ListBox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">List Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ComboBox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Combo Box</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Grid" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Table Control</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Imagebutton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Image Button</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FileControl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">File Selection</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ControlProperties" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Con~trol...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormProperties" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">For~m...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TabDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Activation Order...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FirstRecord" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">First Record</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:NextRecord" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Next Record</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:PrevRecord" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Previous Record</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:LastRecord" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Last Record</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:NewRecord" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">New Record</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DeleteRecord" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Delete Record</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AbsoluteRecord" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Absolute Record</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AddField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Add Field...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RecText" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Record</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RecFromText" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Text -&gt; Record</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RecTotal" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Total No. of Records</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RecSave" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Save Record</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SwitchControlDesignMode" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Design Mode On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SwitchXFormsDesignMode" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Design Mode On/Off</value>
+ <value xml:lang="ar">إظهار/إخÙاء وضع التصميم</value>
+ <value xml:lang="no">Design Mode On/Off</value>
+ <value xml:lang="ca">Mode de disseny activat/desactivat</value>
+ <value xml:lang="zh-TW">啟動或關閉設計模å¼</value>
+ <value xml:lang="cs">Režim návrhu zap/vyp</value>
+ <value xml:lang="da">Udkasttilstand til/fra</value>
+ <value xml:lang="el">Κατάσταση ÏƒÏ‡ÎµÎ´Î¹Î±ÏƒÎ¼Î¿Ï Îαι/Όχι</value>
+ <value xml:lang="es">Modo Diseño</value>
+ <value xml:lang="fi">Suunnittelutila käytössä / poissa käytöstä</value>
+ <value xml:lang="fr">(Dés)activer le mode Conception</value>
+ <value xml:lang="he">‮מצב עיצוב מופעל/מופסק‬</value>
+ <value xml:lang="it">Mostra/nascondi Modo bozza</value>
+ <value xml:lang="ja">デザインモード オン/オフ</value>
+ <value xml:lang="ko">ë””ìžì¸ 모드 ì ìš©/ì ìš© 안함</value>
+ <value xml:lang="nl">Ontwerpmodus aan/uit</value>
+ <value xml:lang="pl">Włącz/Wyłącz tryb projektu</value>
+ <value xml:lang="pt-BR">Ativar/Desativar Modo Esboço</value>
+ <value xml:lang="ru">Визуальное проектирование формы</value>
+ <value xml:lang="sk">Režim návrhu zap/vyp</value>
+ <value xml:lang="sv">Utkastläge på/av</value>
+ <value xml:lang="th">โหมดออà¸à¹à¸šà¸š มี/ไม่มี</value>
+ <value xml:lang="tr">Tasarım kipini aç/kapat</value>
+ <value xml:lang="hi">डिसैन पà¥à¤°à¤•à¤¾à¤° शà¥à¤°à¥‚/बंद</value>
+ <value xml:lang="zh-CN">å¯åŠ¨æˆ–关闭设计模å¼</value>
+ <value xml:lang="pt">Modo Esboço</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RecUndo" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Undo: Data entry</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Repaint" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Redraw</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ShowFmExplorer" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Form Navigator...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ShowDataNavigator" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Data Navigator...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Window3D" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~3D Effects</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Quit" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">E~xit</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:About" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">A~bout %PRODUCTNAME</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:PrinterSetup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">P~rinter Settings...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SaveAll" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Sa~ve All</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Context" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Current Context</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CurrentTime" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Current Time</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CurrentDate" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Current Date</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:VersionVisible" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Version Visible</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ShowItemBrowser" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Item Browser On/Off</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DateField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Date Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:TimeField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Time Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:NumericField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Numerical Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CurrencyField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Currency Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:PrintPreview" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Pa~ge Preview</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:PatternField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Pattern Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OpenReadOnly" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Open in Design Mode</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ImageControl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Image Control</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RemoveFilterSort" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Remove Filter/Sort</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Sortup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Sort Ascending</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SortDown" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Sort Descending</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SendMail" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Document as ~E-mail...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:OrderCrit" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Sort...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FilterCrit" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Standard Filter...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoFilter" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">AutoFilter</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CountAll" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Records</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SbaNativeSql" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Run SQL command directly</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:SbaExecuteSql" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Run Query</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AddTable" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Add Table...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormFiltered" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Apply Filter</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Refresh" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Refresh</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RecSearch" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Find Record...</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:UseWizards" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Wizards On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormattedField" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Formatted Field</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormFilter" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Form-Based Filters</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormFilterExit" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Close</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormFilterExecute" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Apply Form-Based Filter</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:FormFilterNavigator" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Filter Navigation</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToEdit" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Text Box</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToButton" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Button</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToFixed" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Label Field</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToList" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with List Box</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToCheckBox" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Check Box</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToRadio" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Radio Button</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToGroup" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Group Box</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToCombo" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Combo Box</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToImageBtn" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Image Button</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToFileControl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with File Selection</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToDate" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Date Field</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToTime" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Time Field</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToNumeric" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Numerical Field</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToCurrency" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Currency Field</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToPattern" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Pattern Field</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToImageControl" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Image Control</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ConvertToFormatted" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Replace with Formatted Field</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ViewFormAsGrid" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Data source as Table</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:RemoveFilter" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Remove Filter</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AutoControlFocus" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Automatic Control Focus</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:DSBrowserExplorer" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Explorer On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionToggle" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Extrusion On/Off</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionTiltDown" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Tilt Down</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionTiltUp" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Tilt Up</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionTiltLeft" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Tilt Left</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionTiltRight" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Tilt Right</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionDirectionFloater" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Direction</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionLightingFloater" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Lighting</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionSurfaceFloater" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Surface</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Extrusion3DColor" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">3D Color</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionDepth" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Extrusion</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionDepthDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Extrusion Depth</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ExtrusionDepthFloater" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Depth</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ShowToolbar" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Toolbars</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:AvailableToolbars" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Toolbars</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:NavigationBar" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Navigation Bar</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:ToggleBreakPointEnabled" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Breakpoint Enabled/Disabled</value>
+ </prop>
+ </node>
+ <node oor:name="service:com.sun.star.deployment.ui.PackageManagerDialog" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">~Extension Manager...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:Signature" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Digital Signatu~res...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:MacroSignature" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Digital Signature...</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignLeft" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Left</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignHorizontalCenter" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Centered</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignRight" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Right</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignTop" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Top</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignVerticalCenter" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Center</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignBottom" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Bottom</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignJustified" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Justified</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignHorizontalDefault" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Default</value>
+ </prop>
+ </node>
+ <node oor:name=".uno:CommonAlignVerticalDefault" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Default</value>
+ </prop>
+ </node>
+ <node oor:name="dotuno:RecentFileList" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="x-no-translate"></value><value xml:lang="en-US">Recent Doc~uments</value>
+ </prop>
+ </node>
+ </node>
+ </node>
+</oor:component-data>
diff --git a/configmgr/qa/unit/export.map b/configmgr/qa/unit/export.map
new file mode 100644
index 000000000000..4ca70fa85463
--- /dev/null
+++ b/configmgr/qa/unit/export.map
@@ -0,0 +1,7 @@
+UDK_3.0 {
+ global:
+ registerAllTestFunction;
+
+ local:
+ *;
+};
diff --git a/configmgr/qa/unit/makefile.mk b/configmgr/qa/unit/makefile.mk
new file mode 100644
index 000000000000..a6a79ebdd0ca
--- /dev/null
+++ b/configmgr/qa/unit/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.3 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ := ..$/..
+PRJNAME := configmgr
+TARGET := qa_unit
+
+ENABLE_EXCEPTIONS := TRUE
+
+.INCLUDE: settings.mk
+
+DLLPRE = # no leading "lib" on .so files
+
+SHL1TARGET = $(TARGET)
+SHL1OBJS = $(SLO)$/performance.obj $(SLO)$/threading.obj $(SLO)$/ubootstrap.obj
+SHL1STDLIBS = $(CPPULIB) $(CPPUHELPERLIB) $(CPPUNITLIB) $(SALLIB)
+SHL1VERSIONMAP = export.map
+SHL1IMPLIB = i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(SHL1OBJS)
+
+.INCLUDE: target.mk
+
+ALLTAR: test
+
+$(MISC)$/$(TARGET).rdb .ERRREMOVE:
+ $(COPY) $(SOLARBINDIR)$/types.rdb $@
+ $(REGCOMP) -register -r $@ -c $(subst,$/,/ $(DLLDEST)$/configmgr2.uno$(DLLPOST))
+ $(REGCOMP) -register -r $@ -c $(subst,$/,/ $(SOLARLIBDIR)/sax.uno$(DLLPOST))
+ $(REGCOMP) -register -r $@ -c $(subst,$/,/ $(SOLARLIBDIR)/stocservices.uno$(DLLPOST))
+ $(REGCOMP) -register -r $@ -c $(subst,$/,/ $(SOLARLIBDIR)/streams.uno$(DLLPOST))
+
+test .PHONY: $(SHL1TARGETN) $(MISC)$/$(TARGET).rdb
+ $(AUGMENT_LIBRARY_PATH) testshl2 $(SHL1TARGETN) -forward "$(MISC)$/$(TARGET).rdb#$(PWD)$/$(MISC)$/$(TARGET).registry"
diff --git a/configmgr/qa/unit/performance.cxx b/configmgr/qa/unit/performance.cxx
new file mode 100644
index 000000000000..a1e338bf16be
--- /dev/null
+++ b/configmgr/qa/unit/performance.cxx
@@ -0,0 +1,271 @@
+// To debug me use:
+// $ export ENVCFGFLAGS='-me -ti -tw -tp -td'
+
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: performance.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "common.hxx"
+
+void Test::setUp()
+{
+ mpMagic = new Magic();
+
+ char const * f = getForwardString();
+ rtl::OUString args(
+ f, rtl_str_getLength(f), osl_getThreadTextEncoding());
+ //TODO: handle conversion failure
+ sal_Int32 i = args.indexOf('#');
+ if (i < 0)
+ std::abort();
+
+ rtl::OUString rdb(args.copy(0, i));
+ rtl::OUString regpath(args.copy(i + 1));
+ rtl::OUString regurl;
+ if (osl::FileBase::getFileURLFromSystemPath(regpath, regurl) !=
+ osl::FileBase::E_None)
+ std::abort();
+
+ css::uno::Reference< css::beans::XPropertySet > factory(
+ cppu::createRegistryServiceFactory(rdb), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::uno::XComponentContext > context(
+ factory->getPropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext"))),
+ css::uno::UNO_QUERY_THROW);
+ cppu::ContextEntry_Init entry(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "/modules/com.sun.star.configuration/bootstrap/Strata")),
+ css::uno::makeAny(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.configuration.backend.LocalStratum:"))
+ + regurl));
+ mxContext = cppu::createComponentContext(&entry, 1, context);
+
+ CPPUNIT_ASSERT_MESSAGE ("component context is valid", mxContext.is());
+
+ try {
+ mxProvider = css::uno::Reference< css::lang::XMultiServiceFactory >(
+ (css::uno::Reference< css::lang::XMultiComponentFactory >(
+ mxContext->getServiceManager(), css::uno::UNO_QUERY_THROW)->
+ createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationProvider")),
+ mxContext)),
+ css::uno::UNO_QUERY_THROW);
+
+ } catch (css::uno::Exception&e) {
+ CPPUNIT_FAIL( "exception creating provider" );
+ throw;
+ }
+}
+
+css::uno::Reference< css::uno::XInterface >
+Test::createView(const sal_Char *pNodepath, bool bUpdate)
+{
+ rtl::OUString aNodePath = rtl::OUString::createFromAscii(pNodepath);
+ static const rtl::OUString kInfoViewService(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")) ;
+ static const rtl::OUString kUpdateViewService(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationUpdateAccess")) ;
+ static const rtl::OUString kNodepath(RTL_CONSTASCII_USTRINGPARAM("nodepath")) ;
+ static const rtl::OUString kAsync(RTL_CONSTASCII_USTRINGPARAM("EnableAsync")) ;
+
+ const rtl::OUString & kViewService = bUpdate ? kUpdateViewService : kInfoViewService;
+ css::uno::Sequence< css::uno::Any > aViewArgs(2);
+ aViewArgs[0] <<= css::beans::NamedValue( kNodepath, css::uno::makeAny(aNodePath) );
+ aViewArgs[1] <<= css::beans::NamedValue( kAsync, css::uno::makeAny(sal_False) );
+
+ css::uno::Reference< css::uno::XInterface > xView(
+ mxProvider->createInstanceWithArguments( kViewService, aViewArgs ) );
+ return xView;
+}
+
+void disposeComponent (const css::uno::Reference<css::uno::XInterface> &xComp)
+{
+ css::uno::Reference< css::lang::XComponent >(
+ xComp, css::uno::UNO_QUERY_THROW)->dispose();
+}
+
+void Test::tearDown()
+{
+ disposeComponent (mxProvider);
+ disposeComponent (mxContext);
+
+ delete mpMagic;
+}
+
+void Test::normalizePathKey (rtl::OString &rPath, rtl::OString &rKey)
+{
+ sal_Int32 idx = rKey.lastIndexOf("/");
+ if (idx > 0) {
+ rPath += "/";
+ rPath += rKey.copy (0, idx);
+ rKey = rKey.copy (idx + 1);
+// t_print ("write to '%s' '%s'\n", (const sal_Char *)rPath,
+// (const sal_Char *)rKey);
+ }
+}
+
+css::uno::Any Test::getKey (const sal_Char *pPath, rtl::OUString aName)
+{
+ css::uno::Reference< css::container::XHierarchicalNameAccess > xNameAccess(
+ createView(pPath, false), css::uno::UNO_QUERY_THROW);
+ css::uno::Any aVal;
+ aVal = xNameAccess->getByHierarchicalName (aName);
+ disposeComponent (xNameAccess);
+ return aVal;
+}
+
+void Test::setKey (const sal_Char *pPath, rtl::OUString aName, css::uno::Any a)
+{
+ css::uno::Reference< css::util::XChangesBatch > xAppView;
+
+ xAppView = css::uno::Reference< css::util::XChangesBatch > (
+ createView(pPath, true), css::uno::UNO_QUERY_THROW );
+ css::uno::Reference< css::container::XNameReplace > xSettings(xAppView, css::uno::UNO_QUERY_THROW);
+ rtl::OUString aStr;
+
+ // set key
+ xSettings->replaceByName(aName, a);
+ xAppView->commitChanges();
+
+ disposeComponent(xAppView);
+}
+
+void Test::resetKey (const sal_Char *pPath, rtl::OUString aName)
+{
+ css::uno::Reference< css::util::XChangesBatch > xAppView;
+
+ // reset to default
+ xAppView = css::uno::Reference< css::util::XChangesBatch > ( createView(pPath, true), css::uno::UNO_QUERY_THROW );
+ css::uno::Reference< css::container::XNameReplace > xSettings(xAppView, css::uno::UNO_QUERY_THROW);
+
+ css::uno::Reference< css::beans::XPropertyState > xSettingsState(xSettings, css::uno::UNO_QUERY);
+ xSettingsState->setPropertyToDefault(aName);
+ xAppView->commitChanges();
+
+ disposeComponent(xAppView);
+}
+
+void Test::keyFetch()
+{
+ try {
+ rtl::OUString aStr;
+ if (!(getKey ("/org.openoffice.Setup", "L10N/ooLocale") >>= aStr))
+ CPPUNIT_FAIL("to fetch key");
+ if (!(getKey ("/org.openoffice.Setup", "Test/AString") >>= aStr))
+ CPPUNIT_FAIL("to fetch key");
+ } CATCH_FAIL ("fetching key")
+}
+
+void Test::keySet()
+{
+ try {
+ setKey ("/org.openoffice.Setup/Test",
+ rtl::OUString::createFromAscii("AString"),
+ css::uno::makeAny (rtl::OUString::createFromAscii("baa")));
+
+ // check value
+ rtl::OUString aStr;
+ if (!(getKey ("/org.openoffice.Setup/Test", "AString") >>= aStr))
+ CPPUNIT_FAIL("to fetch key");
+
+ CPPUNIT_ASSERT_MESSAGE ("check set value valid", aStr.equalsAscii("baa"));
+ } CATCH_FAIL ("exception setting keys" )
+}
+
+void Test::keyReset()
+{
+ try {
+ resetKey ("/org.openoffice.Setup/Test",
+ rtl::OUString::createFromAscii("AString"));
+
+ // check value
+ rtl::OUString aStr;
+ if (!(getKey ("/org.openoffice.Setup/Test", "AString") >>= aStr))
+ CPPUNIT_FAIL("to fetch key");
+
+ CPPUNIT_ASSERT_MESSAGE ("check default value valid",
+ aStr == rtl::OUString::createFromAscii("Foo"));
+ } CATCH_FAIL ("exception setting keys" )
+}
+
+// This simulates the framework UI description code paths
+void Test::readCommands()
+{
+ rtl::OUString aPropUILabel( RTL_CONSTASCII_USTRINGPARAM( "Label" ));
+ rtl::OUString aPropUIContextLabel( RTL_CONSTASCII_USTRINGPARAM( "ContextLabel" ));
+ rtl::OUString aPropProperties( RTL_CONSTASCII_USTRINGPARAM( "Properties" ));
+
+ try {
+ css::uno::Reference< css::container::XNameAccess > xNameAccess (
+ createView("/org.openoffice.UI.GenericCommands/UserInterface/Commands", false),
+ css::uno::UNO_QUERY_THROW);
+
+ CPPUNIT_ASSERT_MESSAGE ("fetched UI generic commands", xNameAccess.is());
+
+ css::uno::Any a;
+ css::uno::Sequence< rtl::OUString > aNameSeq = xNameAccess->getElementNames();
+
+ CPPUNIT_ASSERT_MESSAGE ("right element / sequence", aNameSeq.getLength() == 696);
+ sal_uInt32 end, start = osl_getGlobalTimer();
+ for ( sal_Int32 j = 0; j < 8; j++ )
+ {
+ for ( sal_Int32 i = 0; i < aNameSeq.getLength(); i++ )
+ {
+ try
+ {
+ {
+ css::uno::Reference< css::container::XNameAccess > xChildNameAccess;
+ // This is the slow bit ! ...
+ // Creating the @#$@#$ing XNameAccess object [ 650 times ]
+ // which we then use to 'getByName' etc.
+ a = xNameAccess->getByName( aNameSeq[i] );
+ if ( a >>= xChildNameAccess )
+ {
+ a = xChildNameAccess->getByName( aPropUILabel );
+ a = xChildNameAccess->getByName( aPropUIContextLabel );
+ a = xChildNameAccess->getByName( aPropProperties );
+ }
+ }
+ } CATCH_FAIL( "fetching keys" );
+ }
+ }
+ end = osl_getGlobalTimer();
+ t_print ("Reading elements took %d ms\n", (int)(end-start));
+ disposeComponent (xNameAccess);
+ } CATCH_FAIL( "accessing commands" );
+}
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(Test, "alltests");
+
+NOADDITIONAL;
diff --git a/configmgr/qa/unit/schema/org/openoffice/Setup.xcs b/configmgr/qa/unit/schema/org/openoffice/Setup.xcs
new file mode 100644
index 000000000000..f126025b8821
--- /dev/null
+++ b/configmgr/qa/unit/schema/org/openoffice/Setup.xcs
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Setup.xcs,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************ -->
+<!DOCTYPE oor:component-schema SYSTEM "../../../component-schema.dtd">
+<oor:component-schema xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oor:name="Setup" oor:package="org.openoffice" xml:lang="en-US">
+ <info>
+ <author>mmeeks</author>
+ <desc >Setup prefs (for configmgr) and unit test schema bits.</desc>
+ </info>
+ <component>
+ <group oor:name="L10N">
+ <info>
+ <author>PB</author>
+ <desc>Specifies the installation locales.</desc>
+ </info>
+ <prop oor:name="ooLocale" oor:type="xs:string">
+ <info>
+ <author>PB</author>
+ <desc>Indicates the Office language selected by the user.</desc>
+ <label>Locale</label>
+ </info>
+ <value/>
+ </prop>
+ </group>
+ <group oor:name="Test">
+ <info>
+ <author>mmeeks</author>
+ <desc>Misc test pieces</desc>
+ </info>
+ <prop oor:name="ABoolean" oor:type="xs:boolean">
+ <info>
+ <author>mmeeks</author>
+ <desc>A boolean</desc>
+ <label>Boolean</label>
+ </info>
+ <value>false</value>
+ </prop>
+ <prop oor:name="AString" oor:type="xs:string">
+ <info>
+ <author>mmeeks</author>
+ <desc>A string</desc>
+ <label>String</label>
+ </info>
+ <value>Foo</value>
+ </prop>
+ </group>
+ </component>
+</oor:component-schema>
diff --git a/configmgr/qa/unit/schema/org/openoffice/UI/Commands.xcs b/configmgr/qa/unit/schema/org/openoffice/UI/Commands.xcs
new file mode 100644
index 000000000000..b4f1d6675891
--- /dev/null
+++ b/configmgr/qa/unit/schema/org/openoffice/UI/Commands.xcs
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Commands.xcs,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************ -->
+<!DOCTYPE oor:component-schema SYSTEM "../../../../../component-schema.dtd">
+<oor:component-schema xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oor:name="Commands" oor:package="org.openoffice.UI" xml:lang="en-US"> <info>
+ <author>CD</author>
+ <desc >Contains general information about ~ and rules, and about actions based on office commands.</desc>
+ </info>
+ <templates>
+ <group oor:name="LabelType">
+ <info>
+ <desc>Provides a mapping between commands and their textual representation on the user interface.</desc>
+ </info>
+ <prop oor:name="Label" oor:type="xs:string" oor:localized="true">
+ <info>
+ <desc>A localized text that describes the command or identifier. Can be used as a label inside a menu or as short tool tip help.</desc>
+ </info>
+ </prop>
+ <prop oor:name="ContextLabel" oor:type="xs:string" oor:localized="true">
+ <info>
+ <desc>A localized text that describes the identifier of a command in a structured menu. </desc>
+ </info>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <info>
+ <desc>
+ Additional information about a single command.
+ Bit 0 = Command has an image.
+ Bit 1 = Image must be mirrored (CTL/vertical text).
+ Bit 2 = Image must be rotated (CTL/vertical text).
+ </desc>
+ </info>
+ <value>0</value>
+ </prop>
+ </group>
+ </templates>
+ <component/>
+</oor:component-schema>
diff --git a/configmgr/qa/unit/schema/org/openoffice/UI/GenericCommands.xcs b/configmgr/qa/unit/schema/org/openoffice/UI/GenericCommands.xcs
new file mode 100644
index 000000000000..39edfdce8f9a
--- /dev/null
+++ b/configmgr/qa/unit/schema/org/openoffice/UI/GenericCommands.xcs
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--***********************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: GenericCommands.xcs,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************ -->
+<!DOCTYPE oor:component-schema SYSTEM "../../../../../component-schema.dtd">
+<oor:component-schema xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oor:name="GenericCommands" oor:package="org.openoffice.UI" xml:lang="en-US">
+ <info>
+ <author>CD</author>
+ <desc >Contains general information about ~ and rules, and about actions based on office commands.</desc>
+ </info>
+ <import oor:component="org.openoffice.UI.Commands"/>
+ <uses oor:component="org.openoffice.UI.Commands"/>
+ <templates/>
+ <component>
+ <group oor:name="UserInterface">
+ <info>
+ <desc>Contains user interface data for Office commands and identifiers that are used by the user interface."</desc>
+ </info>
+ <set oor:name="Commands" oor:node-type="LabelType" oor:component="org.openoffice.UI.Commands">
+ <info>
+ <desc>Contains label text for Office commands and identifiers that are used by the user interface."</desc>
+ </info>
+ </set>
+ </group>
+ </component>
+</oor:component-schema>
diff --git a/configmgr/qa/unit/threading.cxx b/configmgr/qa/unit/threading.cxx
new file mode 100644
index 000000000000..1531e9f49138
--- /dev/null
+++ b/configmgr/qa/unit/threading.cxx
@@ -0,0 +1,262 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: threading.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "common.hxx"
+#include <osl/thread.hxx>
+#include <osl/conditn.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include "com/sun/star/beans/XPropertyChangeListener.hpp"
+
+class KeyTester : public osl::Thread
+{
+ osl::Condition *m_pCond;
+ protected:
+ rtl::OString m_aPath;
+ rtl::OString m_aKey;
+ Test *m_pTest;
+ public:
+ KeyTester (osl::Condition *pCond, Test *pTest,
+ const char *pPath, const char *pKey)
+ : m_pCond (pCond)
+ , m_aPath (pPath)
+ , m_aKey (pKey)
+ , m_pTest (pTest)
+ {
+ }
+ virtual ~KeyTester ()
+ {
+ }
+ virtual void run ()
+ {
+ testIteration();
+ while (!m_pCond->check())
+ testIteration();
+ }
+ virtual void testIteration()
+ {
+ css::uno::Any a = m_pTest->getKey (m_aPath, m_aKey);
+ CPPUNIT_ASSERT_MESSAGE ("no value", a.hasValue());
+ }
+};
+
+class KeyReader : public KeyTester
+{
+public:
+ KeyReader (osl::Condition *pCond, Test *pTest,
+ const char *pPath, const char *pKey)
+ : KeyTester (pCond, pTest, pPath, pKey)
+ {
+ // to ensure we have the right vtable when we hit 'run'
+ create();
+ }
+};
+
+class KeyWriter : public KeyTester
+{
+ int curOpt;
+ public:
+ KeyWriter (osl::Condition *pCond, Test *pTest,
+ const char *pPath, const char *pKey)
+ : KeyTester (pCond, pTest, pPath, pKey)
+ , curOpt(0)
+ {
+ m_pTest->normalizePathKey (m_aPath, m_aKey);
+ create();
+ }
+ virtual void testIteration ()
+ {
+ try {
+ static const char *options[] = { "fish", "chips", "kippers", "bloaters" };
+// fprintf (stderr, "set key %d\n",
+// (int) osl_getThreadIdentifier(NULL));
+ m_pTest->setKey (m_aPath, rtl::OUString::createFromAscii (m_aKey),
+ css::uno::makeAny (rtl::OUString::createFromAscii(options[(curOpt++ & 3)])));
+ } CATCH_FAIL ("setting keys")
+ }
+};
+
+void Test::threadTests()
+{
+ osl::Condition stop;
+ stop.reset();
+
+ struct {
+ const char *pPath;
+ const char *pKey;
+ } keyList[] = {
+ { "/org.openoffice.Setup", "Test/AString" },
+ { "/org.openoffice.Setup", "Test/AString" },
+ { "/org.openoffice.UI.GenericCommands", "UserInterface/Commands/dotuno:WebHtml/Label" },
+ { "/org.openoffice.UI.GenericCommands", "UserInterface/Commands/dotuno:NewPresentation/Label" },
+ { "/org.openoffice.UI.GenericCommands", "UserInterface/Commands/dotuno:RecentFileList/Label" },
+
+ { "/org.openoffice.Setup", "L10N/ooLocale" },
+ { "/org.openoffice.Setup", "Test/ABoolean" }
+ };
+ const int numReaders = sizeof (keyList) / sizeof (keyList[0]);
+ const int numWriters = (sizeof (keyList) / sizeof (keyList[0])) - 2;
+ KeyReader *pReaders[numReaders];
+ KeyWriter *pWriters[numReaders];
+
+ int i;
+ try {
+ for (i = 0; i < numReaders; i++) {
+ css::uno::Any a = getKey (keyList[i].pPath, keyList[i].pKey);
+ CPPUNIT_ASSERT_MESSAGE ("check key", a.hasValue());
+ }
+
+ // a few readers
+ for (i = 0; i < numReaders; i++)
+ pReaders[i] = new KeyReader (&stop, this, keyList[i].pPath,
+ keyList[i].pKey);
+ // a few writers
+ for (i = 0; i < numWriters; i++)
+ pWriters[i] = new KeyWriter (&stop, this, keyList[i].pPath,
+ keyList[i].pKey);
+
+ // Threads are running ...
+ const int numIters = 5;
+ for (int j = 0; j < numIters; j++) {
+ for (i = 0; i < numReaders; i++)
+ {
+ try {
+ rtl::OString aPath (keyList[i].pPath);
+ rtl::OString aKey (keyList[i].pKey);
+ normalizePathKey (aPath, aKey);
+ resetKey (aPath, rtl::OUString::createFromAscii (aKey));
+ osl::Thread::yield();
+ } CATCH_FAIL ("resetting keys");
+ }
+ }
+ stop.set();
+
+ for (i = 0; i < numReaders; i++) {
+ pReaders[i]->join();
+ delete pReaders[i];
+ }
+ for (i = 0; i < numWriters; i++) {
+ pWriters[i]->join();
+ delete pWriters[i];
+ }
+
+ } CATCH_FAIL ("checking keys exist")
+}
+
+class RecursiveListener : public cppu::WeakImplHelper1< css::beans::XPropertyChangeListener >
+{
+public:
+ sal_Int32 m_nRecurse;
+ css::uno::Reference< css::beans::XPropertySet > mxPropSet;
+ protected:
+ Test *m_pTest;
+ rtl::OString m_pPath;
+ rtl::OString m_pKey;
+ public:
+ RecursiveListener (Test *pTest, int nCount,
+ const char *pPath, const char *pKey)
+ : m_nRecurse (nCount)
+ , m_pTest (pTest)
+ , m_pPath (pPath)
+ , m_pKey (pKey)
+ {
+ mxPropSet = css::uno::Reference< css::beans::XPropertySet > (
+ pTest->createView (pPath, true), css::uno::UNO_QUERY_THROW );
+
+ CPPUNIT_ASSERT_MESSAGE ("is prop set", mxPropSet.is());
+ mxPropSet->addPropertyChangeListener (rtl::OUString::createFromAscii (m_pKey),
+ css::uno::Reference<css::beans::XPropertyChangeListener>(this));
+ }
+ virtual ~RecursiveListener()
+ {
+ disposeComponent (mxPropSet);
+ }
+
+ virtual void SAL_CALL acquire() throw() { cppu::WeakImplHelper1< css::beans::XPropertyChangeListener >::acquire(); }
+ virtual void SAL_CALL release() throw() { cppu::WeakImplHelper1< css::beans::XPropertyChangeListener >::acquire(); }
+ // XPropertyChangeListener
+ virtual void SAL_CALL propertyChange( const ::css::beans::PropertyChangeEvent& ) throw (::css::uno::RuntimeException)
+ {
+ if (m_nRecurse-- > 0)
+ runTest();
+ }
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::css::lang::EventObject& ) throw (::css::uno::RuntimeException)
+ {
+ }
+ virtual void runTest()
+ {
+ m_pTest->setKey (m_pPath, rtl::OUString::createFromAscii (m_pKey),
+ css::uno::makeAny(
+ rtl::OUString::valueOf (m_nRecurse) ) );
+ }
+};
+
+class CrossThreadListener : public RecursiveListener
+{
+ public:
+ CrossThreadListener (Test *pTest, int nCount,
+ const char *pPath, const char *pKey)
+ : RecursiveListener (pTest, nCount, pPath, pKey)
+ {
+ }
+ virtual ~CrossThreadListener()
+ {
+ }
+ virtual void runTest()
+ {
+ osl::Condition stopAfterOne;
+ stopAfterOne.set();
+ KeyWriter aWriter (&stopAfterOne, m_pTest, m_pPath, m_pKey);
+ aWriter.join();
+
+ rtl::OString aPath (m_pPath), aKey (m_pKey);
+ m_pTest->normalizePathKey (aPath, aKey);
+ m_pTest->resetKey (aPath, rtl::OUString::createFromAscii (aKey));
+ }
+};
+
+void Test::recursiveTests()
+{
+ RecursiveListener *pList = new RecursiveListener(this, 100,
+ "/org.openoffice.UI.GenericCommands/UserInterface/Commands/dotuno:WebHtml",
+ "Label");
+ css::uno::Reference< css::beans::XPropertyChangeListener > xListener(pList);
+ pList->runTest();
+}
+
+void Test::eventTests()
+{
+ CrossThreadListener *pList = new CrossThreadListener(this, 10,
+ "/org.openoffice.UI.GenericCommands/UserInterface/Commands/dotuno:WebHtml",
+ "Label");
+ css::uno::Reference< css::beans::XPropertyChangeListener > xListener(pList);
+ pList->runTest();
+}
+
diff --git a/configmgr/qa/unit/ubootstrap.cxx b/configmgr/qa/unit/ubootstrap.cxx
new file mode 100644
index 000000000000..8bd8d4316629
--- /dev/null
+++ b/configmgr/qa/unit/ubootstrap.cxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ubootstrap.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "common.hxx"
+#include <osl/file.hxx>
+
+// Do all those evil things to make the tests actually work ...
+Magic::Magic()
+{
+ rtl_uString *curWd = NULL;
+ osl_getProcessWorkingDir( &curWd );
+
+ rtl::OUString aKey;
+ rtl::OUString aValue( curWd );
+
+ // Unless you do this, obviously you don't want your paths to be correct
+ // or file access to work properly
+ aKey = rtl::OUString::createFromAscii( "BaseInstallation" );
+ rtl_bootstrap_set( aKey.pData, aValue.pData );
+ // Unless you do this, obviously you don't deserve to have anything work
+ aKey = rtl::OUString::createFromAscii( "CFG_INIFILE" );
+ aValue += rtl::OUString::createFromAscii( "/configmgrrc" );
+ rtl_bootstrap_set( aKey.pData, aValue.pData );
+
+ // FIXME: Create a safe /tmp directory - unfotunately that
+ // either requires dependencies we don't have, or some cut &
+ // paste action of unotools/source/ucbhelper/tempfile.cxx
+ if (osl::File::getTempDirURL(maTempDir) != osl::FileBase::E_None) {
+ t_print ("no tmp dir");
+ CPPUNIT_FAIL ("no tmp dir");
+ }
+ maTempDir += rtl::OUString::createFromAscii("/unittstconfig");
+ osl::FileBase::RC err = osl::Directory::create (maTempDir);
+
+ if (err != osl::FileBase::E_None) {
+ t_print ("tmp dir '%s' already exists\n",
+ rtl::OUStringToOString (maTempDir, RTL_TEXTENCODING_UTF8).getStr());
+ CPPUNIT_FAIL ("tmp user config dir already exists!");
+ }
+
+ aKey = rtl::OUString::createFromAscii( "UserInstallation" );
+ rtl_bootstrap_set( aKey.pData, maTempDir.pData );
+}
+
+void removeRecursive (const rtl::OUString& aPath)
+{
+ sal_Int32 nMask = FileStatusMask_Type | FileStatusMask_FileURL;
+
+// fprintf (stderr, "Remove recursive '%s'\n", rtl::OUStringToOString (aPath, RTL_TEXTENCODING_UTF8).getStr());
+
+ osl::DirectoryItem aItem;
+ osl::FileStatus aStatus( nMask );
+ osl::FileBase::RC nError;
+
+ nError = osl::DirectoryItem::get( aPath, aItem );
+ CPPUNIT_ASSERT_MESSAGE ("invalid path", nError == osl::FileBase::E_None);
+
+ nError = aItem.getFileStatus( aStatus );
+ CPPUNIT_ASSERT_MESSAGE ("invalid file", nError == osl::FileBase::E_None);
+
+ if (aStatus.getFileType() == osl::FileStatus::Regular ||
+ aStatus.getFileType() == osl::FileStatus::Link )
+ {
+ nError = osl::File::remove( aPath );
+// fprintf (stderr, "Remove file '%s'\n", rtl::OUStringToOString (aPath, RTL_TEXTENCODING_UTF8).getStr());
+ CPPUNIT_ASSERT_MESSAGE ("removing file", nError == osl::FileBase::E_None);
+ }
+ else if (aStatus.getFileType() == osl::FileStatus::Directory)
+ {
+ osl::Directory aDirectory (aPath);
+ nError = aDirectory.open();
+ CPPUNIT_ASSERT_MESSAGE ("opening dir", nError == osl::FileBase::E_None);
+
+ rtl::OUString name;
+
+ while (true) {
+ nError = aDirectory.getNextItem( aItem );
+ if ( nError != osl::FileBase::E_None )
+ break;
+ nError = aItem.getFileStatus( aStatus );
+ CPPUNIT_ASSERT_MESSAGE ("getting status", nError == osl::FileBase::E_None);
+ removeRecursive (aStatus.getFileURL());
+ }
+ aDirectory.close();
+
+ nError = osl::Directory::remove( aPath );
+// fprintf (stderr, "Remove dir '%s'\n", rtl::OUStringToOString (aPath, RTL_TEXTENCODING_UTF8).getStr());
+
+ CPPUNIT_ASSERT_MESSAGE ("removing directory", nError == osl::FileBase::E_None);
+ }
+}
+
+Magic::~Magic()
+{
+ removeRecursive (maTempDir);
+}
diff --git a/configmgr/qa/unoapi/cfgmgr2.sce b/configmgr/qa/unoapi/cfgmgr2.sce
new file mode 100644
index 000000000000..e7c4adcb6e34
--- /dev/null
+++ b/configmgr/qa/unoapi/cfgmgr2.sce
@@ -0,0 +1,34 @@
+-o cfgmgr2.LocalSchemaSupplier
+-o cfgmgr2.LocalSingleStratum
+-o cfgmgr2.MultiStratumBackend
+-o sysmgr1.SystemIntegration
+#i46913# -o cfgmgr2.BootstrapContext
+-o cfgmgr2.LayerUpdateMerger
+-o cfgmgr2.LayerWriter
+-o cfgmgr2.LocalDataImporter
+-o cfgmgr2.LocalHierarchyBrowser
+-o cfgmgr2.LocalSingleBackend
+-o cfgmgr2.MergeImporter
+-o cfgmgr2.OConfigurationRegistry
+-o cfgmgr2.OInnerGroupInfoAccess
+-o cfgmgr2.OInnerGroupUpdateAccess
+-o cfgmgr2.OInnerSetInfoAccess
+#i46185# -o cfgmgr2.OInnerTreeSetUpdateAccess
+-o cfgmgr2.OInnerValueSetUpdateAccess
+-o cfgmgr2.ORootElementGroupInfoAccess
+-o cfgmgr2.ORootElementGroupUpdateAccess
+-o cfgmgr2.ORootElementSetInfoAccess
+#i46185# -o cfgmgr2.ORootElementTreeSetUpdateAccess
+-o cfgmgr2.ORootElementValueSetUpdateAccess
+-o cfgmgr2.OSetElementGroupInfoAccess
+-o cfgmgr2.OSetElementGroupUpdateAccess
+-o cfgmgr2.OSetElementSetInfoAccess
+#i46185# -o cfgmgr2.OSetElementTreeSetUpdateAccess
+#i84221# -o cfgmgr2.OSetElementValueSetUpdateAccess
+-o cfgmgr2.SchemaParser
+-o cfgmgr2.SingleBackendAdapter
+-o cfgmgr2.ConfigurationProviderWrapper
+#i87744# -o cfgmgr2.LayerParser
+-o cfgmgr2.CopyImporter
+-o cfgmgr2.AdministrationProvider
+-o cfgmgr2.ConfigurationProvider
diff --git a/configmgr/qa/unoapi/knownissues.xcl b/configmgr/qa/unoapi/knownissues.xcl
new file mode 100644
index 000000000000..d8956a6e8d85
--- /dev/null
+++ b/configmgr/qa/unoapi/knownissues.xcl
@@ -0,0 +1,55 @@
+### i84222 ###
+cfgmgr2.LocalSingleBackend::com::sun::star::configuration::backend::XMultiLayerStratum
+
+### i23145 ###
+cfgmgr2.OSetElementGroupUpdateAccess::com::sun::star::container::XChild
+
+### i38211 ###
+cfgmgr2.ConfigurationProvider::com::sun::star::lang::XComponent
+
+### i46185 ###
+cfgmgr2.OInnerTreeSetUpdateAccess::com::sun::star::container::XNameContainer
+cfgmgr2.OSetElementTreeSetUpdateAccess::com::sun::star::container::XNameContainer
+cfgmgr2.ORootElementTreeSetUpdateAccess::com::sun::star::container::XNameContainer
+# -> test is disbaled in cfgmgr2.sce
+
+### i46913 ###
+cfgmgr2.BootstrapContext::com::sun::star::uno::XComponentContext
+# -> test is disbaled in cfgmgr2.sce
+
+### i83881 ###
+cfgmgr2.OInnerValueSetUpdateAccess::com::sun::star::container::XNameReplace
+
+### i65847 ###
+cfgmgr2.OInnerTreeSetUpdateAccess::com::sun::star::beans::XPropertyWithState
+# -> test is disbaled in cfgmgr2.sce
+
+### i68673 ###
+cfgmgr2.ORootElementTreeSetUpdateAccess::com::sun::star::beans::XPropertyWithState
+# -> test is disbaled in cfgmgr2.sce
+
+### i79114 ###
+sysmgr1.SystemIntegration::com::sun::star::configuration::backend::XBackend
+
+### i83880 ###
+cfgmgr2.ORootElementValueSetUpdateAccess::com::sun::star::container::XNameReplace
+
+### i84221 ###
+cfgmgr2.OSetElementValueSetUpdateAccess
+
+### i87744 ###
+cfgmgr2.LayerParser
+# -> test is disbaled in cfgmgr2.sce
+
+### i88358 ###
+cfgmgr2.OInnerValueSetUpdateAccess::com::sun::star::container::XHierarchicalNameAccess
+cfgmgr2.OInnerValueSetUpdateAccess::com::sun::star::beans::XExactName
+
+### i88360 ###
+cfgmgr2.ORootElementValueSetUpdateAccess::com::sun::star::util::XChangesBatch
+
+### i89412 ###
+cfgmgr2.OInnerValueSetUpdateAccess::com::sun::star::container::XElementAccess
+
+### i89413 ###
+cfgmgr2.ORootElementValueSetUpdateAccess::com::sun::star::container::XHierarchicalNameAccess
diff --git a/configmgr/qa/unoapi/makefile.mk b/configmgr/qa/unoapi/makefile.mk
new file mode 100644
index 000000000000..6be9331b2cc4
--- /dev/null
+++ b/configmgr/qa/unoapi/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.7 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=configmgr
+TARGET=qa_unoapi
+
+.INCLUDE: settings.mk
+
+.INCLUDE: target.mk
+
+ALLTAR : UNOAPI_TEST
+
+UNOAPI_TEST:
+ +$(SOLARENV)$/bin$/checkapi -sce cfgmgr2.sce -xcl knownissues.xcl -tdoc $(PWD)$/testdocuments
+ @echo =======================================================================
+ @echo In case of problems with sysmgr1.SystemIntegration make sure that you
+ @echo =======================================================================
+ @echo built and registered qadevOOo/testsdocs/backend/org/openoffice/JavaSystemBackend
+ @echo =======================================================================
diff --git a/configmgr/source/api/confevents.cxx b/configmgr/source/api/confevents.cxx
new file mode 100644
index 000000000000..12428a197e6d
--- /dev/null
+++ b/configmgr/source/api/confevents.cxx
@@ -0,0 +1,305 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: confevents.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include "confevents.hxx"
+#include "configexcept.hxx"
+#include "treechangelist.hxx"
+#include <osl/diagnose.h>
+namespace configmgr
+{
+ /////////////////////////////////////////////////////////////////////////
+ ConfigChangeBroadcastHelper::ConfigChangeBroadcastHelper()
+ {
+ }
+
+ ConfigChangeBroadcastHelper::~ConfigChangeBroadcastHelper()
+ {
+ OSL_ENSURE(m_aListeners.begin() == m_aListeners.end(), "Remaining listeners found - forgot to dispose ?");
+ OSL_ENSURE(m_aPathMap.empty(), "Spurious mappings found");
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ void ConfigChangeBroadcastHelper::dispose(TreeManager * pSource)
+ {
+ disposing(pSource);
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ void ConfigChangeBroadcastHelper::addListener(configuration::AbsolutePath const& aName, rtl::Reference<INodeListener> const& pHandler)
+ {
+ add(aName, pHandler);
+ }
+
+ void ConfigChangeBroadcastHelper::removeListener(rtl::Reference<INodeListener> const& pHandler)
+ {
+ remove(pHandler);
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ void ConfigChangeBroadcastHelper::broadcast(TreeChangeList const& anUpdate, sal_Bool bError, TreeManager * pSource)
+ {
+ dispatch(anUpdate, bError, pSource);
+ }
+
+/////////////////////////////////////////////////////////////////////////
+void ConfigChangeBroadcastHelper::add(configuration::AbsolutePath const& aName, rtl::Reference<INodeListener> const& pListener)
+{
+ osl::MutexGuard aGuard(m_aListeners.mutex);
+
+ internal::BroadcastImplHelper<internal::NodeListenerInfo>::Interfaces::iterator aAdded = m_aListeners.addListener(internal::NodeListenerInfo(pListener));
+ aAdded->addPath(aName);
+ m_aPathMap.insert(PathMap::value_type(aName,aAdded));
+}
+
+/////////////////////////////////////////////////////////////////////////
+void ConfigChangeBroadcastHelper::remove(rtl::Reference<INodeListener> const& pListener)
+{
+ osl::MutexGuard aGuard(m_aListeners.mutex);
+
+ internal::BroadcastImplHelper<internal::NodeListenerInfo>::Interfaces::const_iterator const iter = m_aListeners.find(pListener);
+ if (iter != m_aListeners.end())
+ {
+ internal::NodeListenerInfo::Pathes const& pathes = iter->pathList();
+
+ // first clear the Path Map
+ for(internal::NodeListenerInfo::Pathes::iterator itPath = pathes.begin(); itPath != pathes.end(); ++itPath)
+ {
+ std::pair<PathMap::iterator, PathMap::iterator> aRange = m_aPathMap.equal_range(*itPath);
+ while (aRange.first != aRange.second)
+ {
+ PathMap::iterator cur = aRange.first++;
+ if (cur->second == iter)
+ m_aPathMap.erase(cur);
+ }
+ }
+
+ // the remove the broadcast helper entry
+ m_aListeners.removeListener(pListener);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////
+// This should actually be available from the TreeChangeList
+/////////////////////////////////////////////////////////////////////////
+
+static Change const* resolvePath(Change const& rChange, configuration::RelativePath& aRelativePath, RemoveNode const*& pRemoveNode)
+{
+ std::vector<configuration::Path::Component>::const_reverse_iterator aIter;
+
+ OSL_ASSERT(pRemoveNode == NULL);
+ pRemoveNode = NULL;
+
+ Change const* pChange = &rChange;
+ pRemoveNode = dynamic_cast<RemoveNode const*>(pChange);
+
+ std::vector<configuration::Path::Component>::const_reverse_iterator const aEnd(aRelativePath.end());
+
+ for( aIter = aRelativePath.begin();
+ aIter != aEnd;
+ ++aIter)
+ {
+ OSL_ASSERT( pChange != NULL );
+
+ pChange = pChange->getSubChange(aIter->getName());
+
+ if (pChange == NULL) break;
+
+ OSL_ASSERT(pRemoveNode == NULL);
+ OSL_ASSERT(aIter->getName() == pChange->getNodeName());
+
+ pRemoveNode = dynamic_cast<RemoveNode const*>(pChange);
+ }
+
+ if (pRemoveNode)
+ {
+ aRelativePath = configuration::RelativePath( configuration::Path::Rep(aRelativePath.begin(),aIter) );
+ OSL_ASSERT( aRelativePath.getLocalName().getName() == pRemoveNode->getNodeName());
+ }
+ else
+ OSL_ASSERT( pChange == 0 || configuration::matches(aRelativePath, configuration::RelativePath( configuration::Path::Rep(aRelativePath.begin(),aIter) )) );
+
+ return pChange;
+}
+
+/////////////////////////////////////////////////////////////////////////
+void ConfigChangeBroadcastHelper::dispatchInner
+(
+ rtl::Reference<INodeListener> const& pTarget,
+ configuration::AbsolutePath const& _aTargetPath,
+ Change const& rBaseChange,
+ configuration::AbsolutePath const& _aChangeLocation,
+ sal_Bool , //_bError,
+ TreeManager * pSource
+)
+{
+ try
+ {
+ OSL_ASSERT(pTarget.is());
+ OSL_ASSERT( configuration::Path::hasPrefix( _aTargetPath, _aChangeLocation ) );
+
+ configuration::RelativePath aLocalPath = configuration::Path::stripPrefix( _aTargetPath, _aChangeLocation );
+
+ RemoveNode const* pRemoved = 0;
+ Change const* pTargetChange = resolvePath(rBaseChange, aLocalPath, pRemoved );
+
+ OSL_ASSERT( !pTargetChange || matches(_aChangeLocation.compose(aLocalPath),_aTargetPath) );
+
+ if (pRemoved)
+ pTarget->nodeDeleted(_aChangeLocation.compose(aLocalPath), pSource);
+
+ else if (pTargetChange)
+ pTarget->nodeChanged(*pTargetChange, _aTargetPath, pSource);
+
+ }
+ catch (configuration::InvalidName& )
+ {
+ OSL_ENSURE(false,"ConfigChangeBroadcastHelper: Could not dispatch notification: context path mismatch");
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////
+void ConfigChangeBroadcastHelper::dispatchOuter
+(
+ rtl::Reference<INodeListener> const& pTarget,
+ configuration::AbsolutePath const& _aTargetPath,
+ Change const& rBaseChange,
+ configuration::AbsolutePath const& _aChangeLocation,
+ sal_Bool , //_bError,
+ TreeManager * pSource
+)
+{
+ { (void)_aTargetPath; }
+ OSL_ASSERT(pTarget.is());
+ OSL_ASSERT( configuration::Path::hasPrefix( _aChangeLocation, _aTargetPath) );
+
+ pTarget->nodeChanged(rBaseChange, _aChangeLocation, pSource);
+}
+
+/////////////////////////////////////////////////////////////////////////
+void ConfigChangeBroadcastHelper::dispatch(TreeChangeList const& rList_, sal_Bool _bError, TreeManager * pSource)
+{
+ dispatch(rList_.root, rList_.getRootNodePath(),_bError, pSource);
+}
+
+/////////////////////////////////////////////////////////////////////////
+namespace
+{
+ struct DispatchTarget
+ {
+ DispatchTarget(rtl::Reference<INodeListener> _pTarget, configuration::AbsolutePath const* _pDispatchPath)
+ : pTarget(_pTarget), pDispatchPath( _pDispatchPath) {}
+
+ rtl::Reference<INodeListener> pTarget;
+ configuration::AbsolutePath const* pDispatchPath;
+ };
+}
+/////////////////////////////////////////////////////////////////////////
+void ConfigChangeBroadcastHelper::dispatch
+(
+ Change const& rBaseChange,
+ configuration::AbsolutePath const& _aChangeLocation,
+ sal_Bool _bError,
+ TreeManager * pSource
+)
+{
+ OSL_ENSURE(!_aChangeLocation.isRoot(),"Cannot dispatch changes directly to the root node");
+
+ // listeners registered under multiple sub-pathes will be called multiple times !
+
+ // Collect the targets
+ osl::ClearableMutexGuard aGuard(m_aListeners.mutex);
+
+ // Dispatch listeners to ancestors of the change root
+ std::vector<DispatchTarget> aOuterTargets;
+ if (_aChangeLocation.getDepth() > 1)
+ {
+ configuration::AbsolutePath const aModulePath( configuration::Path::Rep(*_aChangeLocation.begin()) );
+
+ PathMap::const_iterator itOuter = m_aPathMap.lower_bound( aModulePath );
+ PathMap::const_iterator const endOuter = m_aPathMap.upper_bound(_aChangeLocation.getParentPath());
+
+ // TODO: Both loops are so similar - they should be a single function
+ while (itOuter != endOuter)
+ {
+ OSL_ASSERT( m_aListeners.find(itOuter->second->get()) != m_aListeners.end() );
+
+ // check whether this should be dispatched at all
+ if ( configuration::Path::hasPrefix(_aChangeLocation,itOuter->first) )
+ {
+ aOuterTargets.push_back( DispatchTarget(itOuter->second->get(), &itOuter->first) );
+ }
+ ++itOuter;
+ }
+ }
+
+ // Dispatch listeners to descendants of the change root
+ std::vector<DispatchTarget> aInnerTargets;
+ {
+ PathMap::const_iterator itInner = m_aPathMap.lower_bound(_aChangeLocation);
+
+ while( itInner != m_aPathMap.end() && configuration::Path::hasPrefix(itInner->first,_aChangeLocation) )
+ {
+ OSL_ASSERT( m_aListeners.find(itInner->second->get()) != m_aListeners.end() );
+
+ aInnerTargets.push_back( DispatchTarget(itInner->second->get(), &itInner->first) );
+
+ ++itInner;
+ }
+ }
+
+ aGuard.clear();
+
+ {for (std::vector<DispatchTarget>::const_iterator it = aOuterTargets.begin(); it != aOuterTargets.end(); ++it){
+ this->dispatchOuter(it->pTarget, *it->pDispatchPath, rBaseChange, _aChangeLocation, _bError, pSource);
+ }}
+ {for (std::vector<DispatchTarget>::const_iterator it = aInnerTargets.begin(); it != aInnerTargets.end(); ++it){
+ this->dispatchInner(it->pTarget, *it->pDispatchPath, rBaseChange, _aChangeLocation, _bError, pSource);
+ }}
+}
+
+/////////////////////////////////////////////////////////////////////////
+void ConfigChangeBroadcastHelper::disposing(TreeManager * pSource)
+{
+ osl::ClearableMutexGuard aGuard(m_aListeners.mutex);
+ m_aPathMap.clear();
+
+ aGuard.clear();
+ m_aListeners.disposing(pSource);
+}
+
+} // namespace
+
+
+
diff --git a/configmgr/source/api/confsvccomponent.cxx b/configmgr/source/api/confsvccomponent.cxx
new file mode 100644
index 000000000000..b0de4998cbf6
--- /dev/null
+++ b/configmgr/source/api/confsvccomponent.cxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: confsvccomponent.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "confsvccomponent.hxx"
+#include "datalock.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <cppuhelper/typeprovider.hxx>
+#include <osl/mutex.hxx>
+#include "utility.hxx"
+
+#include <map>
+
+namespace configmgr {
+
+
+ ServiceComponentImpl::ServiceComponentImpl(ServiceImplementationInfo const* aInfo)
+ : ::cppu::WeakComponentImplHelper1< lang::XServiceInfo >(UnoApiLock::getLock())
+ , m_info(aInfo)
+ {
+ }
+
+ void ServiceComponentImpl::disposing()
+ {
+ ::cppu::WeakComponentImplHelper1< lang::XServiceInfo >::disposing();
+ }
+ void ServiceComponentImpl::checkAlive() throw (uno::RuntimeException)
+ {
+ checkAlive("Object was disposed");
+ }
+ void ServiceComponentImpl::checkAlive(rtl::OUString const& sMessage) throw (uno::RuntimeException)
+ {
+ if (rBHelper.bDisposed)
+ throw lang::DisposedException(sMessage, *this);
+ }
+
+ // XTypeProvider
+ uno::Sequence<sal_Int8> ServiceComponentImpl::getStaticImplementationId(ServiceImplementationInfo const* pServiceInfo)
+ throw(uno::RuntimeException)
+ {
+ static osl::Mutex aMapMutex;
+ static std::map<ServiceImplementationInfo const*, ::cppu::OImplementationId> aIdMap;
+
+ osl::MutexGuard aMapGuard(aMapMutex);
+ return aIdMap[pServiceInfo].getImplementationId();
+ }
+
+ uno::Sequence<sal_Int8> SAL_CALL ServiceComponentImpl::getImplementationId()
+ throw(uno::RuntimeException)
+ {
+ return getStaticImplementationId(m_info);
+ }
+
+ // XServiceInfo
+ rtl::OUString SAL_CALL ServiceComponentImpl::getImplementationName( ) throw(uno::RuntimeException)
+ {
+ return ServiceInfoHelper(m_info).getImplementationName();
+ }
+
+ sal_Bool SAL_CALL ServiceComponentImpl::supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException)
+ {
+ return ServiceInfoHelper(m_info).supportsService( ServiceName );
+ }
+
+ uno::Sequence< rtl::OUString > SAL_CALL ServiceComponentImpl::getSupportedServiceNames( ) throw(uno::RuntimeException)
+ {
+ return ServiceInfoHelper(m_info).getSupportedServiceNames( );
+ }
+
+ //ServiceComponentImpl::
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api/makefile.mk b/configmgr/source/api/makefile.mk
new file mode 100644
index 000000000000..3d601f5b99eb
--- /dev/null
+++ b/configmgr/source/api/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source$/inc
+PRJNAME=configmgr
+TARGET=api
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/confevents.obj \
+ $(SLO)$/confsvccomponent.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/api2/accessimpl.cxx b/configmgr/source/api2/accessimpl.cxx
new file mode 100644
index 000000000000..c7bd325c7b0d
--- /dev/null
+++ b/configmgr/source/api2/accessimpl.cxx
@@ -0,0 +1,807 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: accessimpl.cxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+
+#include "accessimpl.hxx"
+#include "apinodeaccess.hxx"
+#include "valueref.hxx"
+#include "anynoderef.hxx"
+#include "noderef.hxx"
+#include "configset.hxx"
+#include "confignotifier.hxx"
+#include "propertyinfohelper.hxx"
+#include "treeiterators.hxx"
+#include "attributes.hxx"
+#include "apitypes.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/beans/PropertyVetoException.hpp>
+#include <osl/diagnose.h>
+#include <rtl/logfile.hxx>
+
+#define RTL_LOGFILE_OU2A(rtlOUString) (::rtl::OString((rtlOUString).getStr(), (rtlOUString).getLength(), RTL_TEXTENCODING_ASCII_US).getStr())
+
+namespace configmgr
+{
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------------
+ namespace lang = css::lang;
+ namespace util = css::util;
+
+//-----------------------------------------------------------------------------------
+// Constructors
+//-----------------------------------------------------------------------------------
+
+// Interface methods
+//-----------------------------------------------------------------------------------
+
+
+// XHierarchicalName
+//------------------------------------------------------------------------------------------------------------------
+rtl::OUString implGetHierarchicalName( NodeAccess& rNode ) throw(uno::RuntimeException)
+{
+ // RTL_LOGFILE_CONTEXT(aLog, "Configmgr::API::implGetHierarchicalName()");
+
+ rtl::OUString sRet;
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree( lock.getTree());
+
+ configuration::AbsolutePath const aFullPath = aTree->getAbsolutePath(lock.getNode());
+ sRet = aFullPath.toString();
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return sRet;
+}
+
+//------------------------------------------------------------------------------------------------------------------
+rtl::OUString implComposeHierarchicalName(NodeGroupInfoAccess& rNode, const rtl::OUString& sRelativeName )
+ throw(css::lang::IllegalArgumentException, lang::NoSupportException, uno::RuntimeException)
+{
+ rtl::OUString sRet;
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+ configuration::NodeRef aNode( lock.getNode() );
+ rtl::Reference< configuration::Tree > aTree( lock.getTree() );
+
+ configuration::RelativePath const aAddedPath = configuration::validateRelativePath(sRelativeName, aTree, aNode);
+
+ // TODO: add (relative) name validation based on node type - may then need provider lock
+ configuration::AbsolutePath const aFullPath = aTree->getAbsolutePath(aNode).compose(aAddedPath);
+
+ sRet = aFullPath.toString();
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(1);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+
+ return sRet;
+}
+
+//------------------------------------------------------------------------------------------------------------------
+rtl::OUString implComposeHierarchicalName(NodeSetInfoAccess& rNode, const rtl::OUString& sElementName )
+ throw(css::lang::IllegalArgumentException, lang::NoSupportException, uno::RuntimeException)
+{
+ rtl::OUString sRet;
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+ configuration::NodeRef aNode( lock.getNode() );
+ rtl::Reference< configuration::Tree > aTree( lock.getTree() );
+
+ configuration::Path::Component const aAddedName = configuration::validateElementPathComponent(sElementName, aTree, aNode);
+
+ // TODO: add (relative) name validation based on node type - may then need provider lock
+ configuration::AbsolutePath const aFullPath = aTree->getAbsolutePath(aNode).compose(aAddedName);
+
+ sRet = aFullPath.toString();
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(1);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+
+ return sRet;
+}
+
+//------------------------------------------------------------------------------------------------------------------
+
+// XElementAccess, base class of XNameAccess (and XHierarchicalNameAccess ? )
+//-----------------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------------
+// for group nodes
+uno::Type implGetElementType(NodeGroupInfoAccess& rNode) throw(uno::RuntimeException)
+{
+ rNode.checkAlive();
+ // group nodes have a mix of types
+ // TODO(?): Discover single common type
+ return ::getCppuType( static_cast< uno::Any const*>(0) );
+}
+
+// for set nodes
+uno::Type implGetElementType(NodeSetInfoAccess& rNode) throw(uno::RuntimeException)
+{
+ uno::Type aRet;
+ try
+ {
+ GuardedNodeData<NodeSetInfoAccess> lock( rNode );
+
+ aRet = rNode.getElementInfo()->getInstanceType();
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ return aRet;
+}
+
+//-----------------------------------------------------------------------------------
+// for group nodes
+sal_Bool implHasElements(NodeGroupInfoAccess& rNode) throw(uno::RuntimeException)
+{
+ // rNode.checkAlive();
+// return true; // group nodes always have children
+
+// Better: cater for the case where we are reaching the depth limit
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode ); // no provider lock needed
+
+ rtl::Reference< configuration::Tree > aThisTree( lock.getTree() );
+ configuration::NodeRef aThisNode( lock.getNode() );
+ OSL_ASSERT( !aThisTree->hasElements(aThisNode) );
+ return aThisTree->hasChildren(aThisNode);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ // unreachable, but still there to make compiler happy
+ OSL_ASSERT(!"Unreachable code");
+ return false;
+}
+
+// for set nodes
+sal_Bool implHasElements(NodeSetInfoAccess& rNode) throw(uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode ); // provider lock needed
+
+ rtl::Reference< configuration::Tree > aThisTree( lock.getTree() );
+ configuration::NodeRef aThisNode( lock.getNode() );
+ OSL_ASSERT( !aThisTree->hasChildren(aThisNode) );
+ return aThisTree->hasElements(aThisNode);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ // unreachable, but still there to make compiler happy
+ OSL_ASSERT(!"Unreachable code");
+ return false;
+}
+
+// XExactName
+//-----------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------------------------------------------
+namespace internal
+{
+ struct SearchExactName : private configuration::NodeVisitor
+ {
+ protected:
+ // warning: order dependency
+ configuration::RelativePath aSearchPath;
+ std::vector<configuration::Path::Component>::reverse_iterator pSearchComponent;
+ public:
+ explicit
+ SearchExactName(const configuration::RelativePath& aLookFor)
+ : aSearchPath(aLookFor)
+ , pSearchComponent(aSearchPath.begin_mutate())
+ {}
+
+ bool complete() { return aSearchPath.end_mutate() == pSearchComponent; }
+
+ bool search(configuration::NodeRef const& aNode, rtl::Reference< configuration::Tree > const& aTree);
+
+ configuration::RelativePath const& getBestMatch() const { return aSearchPath; }
+
+ private:
+ bool findMatch(configuration::NodeRef& aNode, rtl::Reference< configuration::Tree > & aTree);
+ virtual Result handle(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const&); // NodeVisitor
+ virtual Result handle(rtl::Reference< configuration::Tree > const& aTree, configuration::ValueRef const&); // NodeVisitor
+ };
+//..................................................................................................................
+ bool SearchExactName::findMatch(configuration::NodeRef& aNode, rtl::Reference< configuration::Tree > & aTree)
+ {
+ OSL_ASSERT( !complete() );
+
+ if ( !aNode.isValid() ) return false;
+
+ // exact match ?
+ if (!configuration::hasChildOrElement(aTree,aNode,*pSearchComponent))
+ {
+ if (aTree->dispatchToChildren(aNode,*this) == CONTINUE) // not found there
+ return false;
+ }
+ OSL_ASSERT(configuration::hasChildOrElement(aTree,aNode,*pSearchComponent));
+
+ if (! configuration::findInnerChildOrAvailableElement(aTree,aNode,pSearchComponent->getName()) )
+ aNode = configuration::NodeRef(); // will stop recursion (value or unloaded element found)
+ ++pSearchComponent;
+
+ return true;
+ }
+ //..................................................................................................................
+ // helper
+ static configuration::Path::Component getExtendedNodeName(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode, rtl::OUString const& aSimpleNodeName)
+ {
+ OSL_PRECOND( !configuration::isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires valid tree" );
+ OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match tree" );
+
+ if (aTree->isRootNode(aNode))
+ return aTree->getExtendedRootName();
+
+ else
+ return configuration::Path::wrapSimpleName(aSimpleNodeName);
+ }
+ //..................................................................................................................
+ configuration::NodeVisitor::Result SearchExactName::handle(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode)
+ {
+ OSL_ASSERT( aNode.isValid() );
+ OSL_ASSERT( !complete() );
+
+ // find inexact match (the first one, but the order is unspecified)
+ // TODO: Add support for node-type-specific element names
+ rtl::OUString aNodeName = aTree->getSimpleNodeName(aNode.getOffset());
+ rtl::OUString aSearchName = pSearchComponent->getName();
+ if (aNodeName.equalsIgnoreAsciiCase(aSearchName))
+ {
+ *pSearchComponent = getExtendedNodeName(aTree,aNode,aNodeName);
+ return DONE; // for this level
+ }
+ else
+ return CONTINUE;
+ }
+ //..................................................................................................................
+ configuration::NodeVisitor::Result SearchExactName::handle(rtl::Reference< configuration::Tree > const&, configuration::ValueRef const& aNode)
+ {
+ OSL_ASSERT( aNode.isValid() );
+ OSL_ASSERT( !complete() );
+
+ // find inexact match (the first one, but the order is unspecified)
+ // TODO: Add support for node-type-specific element names
+ rtl::OUString aNodeName = aNode.m_sNodeName;
+ OSL_ASSERT( configuration::isSimpleName(aNodeName) );
+
+ // value refs are group members and thus have to have simple names
+ if (aNodeName.equalsIgnoreAsciiCase(pSearchComponent->getName()))
+ {
+ *pSearchComponent = configuration::Path::wrapSimpleName(aNodeName);
+ return DONE; // for this level
+ }
+ else
+ return CONTINUE;
+ }
+//..................................................................................................................
+ bool SearchExactName::search(configuration::NodeRef const & aNode, rtl::Reference< configuration::Tree > const & aTree)
+ {
+ if (!aNode.isValid()) return false;
+
+ rtl::Reference< configuration::Tree > aSearchTree(aTree);
+ configuration::NodeRef aSearchNode(aNode);
+
+ while (!complete())
+ if (! findMatch(aSearchNode, aSearchTree))
+ break;
+
+ return complete();
+ }
+
+} // namespace internal
+
+//..................................................................................................................
+rtl::OUString implGetExactName(NodeGroupInfoAccess& rNode, const rtl::OUString& rApproximateName ) throw(uno::RuntimeException)
+{
+ // here we try to support both tree-fragment-local pathes and simple names (the latter ones are just an instance of the first)
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree(lock.getTree());
+ configuration::NodeRef aNode(lock.getNode());
+
+ configuration::RelativePath aApproximatePath = configuration::validateRelativePath(rApproximateName,aTree,aNode);
+
+ internal::SearchExactName aSearch(aApproximatePath);
+
+ aSearch.search(aNode, aTree);
+
+ OSL_ENSURE( aSearch.getBestMatch().getDepth() == aApproximatePath.getDepth(),
+ "Search for exact names changed number of path components !?");
+
+ return aSearch.getBestMatch().toString();
+ }
+ catch (configuration::InvalidName& )
+ {
+ OSL_TRACE("WARNING: Configuration::getExactName: query uses locally invalid Path");
+ return rApproximateName;
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ // unreachable, but still there to make compiler happy
+ OSL_ASSERT(!"Unreachable code");
+ return rApproximateName;
+}
+
+//..................................................................................................................
+rtl::OUString implGetExactName(NodeSetInfoAccess& rNode, const rtl::OUString& rApproximateName ) throw(uno::RuntimeException)
+{
+
+ // here we can support only local names
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree(lock.getTree());
+ configuration::NodeRef aNode(lock.getNode());
+
+ configuration::Path::Component aApproximateName = configuration::validateElementPathComponent(rApproximateName,aTree,aNode);
+
+ internal::SearchExactName aSearch(aApproximateName);
+
+ aSearch.search(aNode, aTree);
+
+ OSL_ENSURE( aSearch.getBestMatch().getDepth() == 1,
+ "Search for exact names changed number of path components !?");
+
+ return aSearch.getBestMatch().getLocalName().getName();
+ }
+ catch (configuration::InvalidName& )
+ {
+ OSL_TRACE("WARNING: Configuration::getExactName: query uses locally invalid Path");
+ return rApproximateName;
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ // unreachable, but still there to make compiler happy
+ OSL_ASSERT(!"Unreachable code");
+ return rApproximateName;
+}
+
+// XProperty
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+beans::Property implGetAsProperty(NodeAccess& rNode)
+ throw(uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree( lock.getTree());
+ configuration::NodeRef aNode( lock.getNode());
+
+ rtl::OUString aName = aTree->getSimpleNodeName(aNode.getOffset());
+ node::Attributes aAttributes = aTree->getAttributes(aNode);
+ uno::Type aApiType = getUnoInterfaceType();
+
+ return helperMakeProperty( aName,aAttributes,aApiType, aTree->hasNodeDefault(aNode) );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ // unreachable, but still there to make some compilers happy
+ OSL_ASSERT(!"Unreachable code");
+ return beans::Property();
+}
+// XPropertySetInfo
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+uno::Sequence< css::beans::Property > implGetProperties( NodeAccess& rNode ) throw (uno::RuntimeException)
+{
+ CollectPropertyInfo aCollect;
+
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ lock.getTree()->dispatchToChildren(lock.getNode(), aCollect);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return makeSequence( aCollect.list() );
+}
+
+//-----------------------------------------------------------------------------------
+css::beans::Property implGetPropertyByName( NodeAccess& rNode, const rtl::OUString& aName )
+ throw (css::beans::UnknownPropertyException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildOrElementName(aName,aTree,aNode);
+
+ configuration::AnyNodeRef aChildNode = configuration::getChildOrElement(aTree,aNode, aChildName);
+
+ if (!aChildNode.isValid())
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Property not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get Property. Property '") );
+ sMessage += aName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' could not be found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw css::beans::UnknownPropertyException( sMessage, xContext );
+ }
+
+ node::Attributes aChildAttributes = aTree->getAttributes(aChildNode);
+ uno::Type aApiType = aChildNode.isNode() ? getUnoInterfaceType() : aTree->getUnoType(aChildNode.toValue());
+
+ return helperMakeProperty( aChildName,aChildAttributes,aApiType, aTree->hasNodeDefault(aChildNode) );
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw css::beans::UnknownPropertyException( e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ // unreachable, but still there to make some compilers happy
+ OSL_ASSERT(!"Unreachable code");
+ return css::beans::Property();
+}
+
+
+//-----------------------------------------------------------------------------------
+sal_Bool implHasPropertyByName( NodeAccess& rNode, const rtl::OUString& name ) throw (uno::RuntimeException)
+{
+ return implHasByName(rNode, name);
+}
+
+// XNameAccess
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// TODO: optimization - cache the node found (for subsequent getByName)
+// TODO: optimization - less locking for group nodes
+//-----------------------------------------------------------------------------------
+sal_Bool implHasByName(NodeAccess& rNode, const rtl::OUString& sName ) throw(uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::OUString aChildName(sName);
+
+ return configuration::hasChildOrElement(lock.getTree(), lock.getNode(), aChildName);
+ }
+#if OSL_DEBUG_LEVEL > 0
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ OSL_ENSURE(false,"configmgr: BasicAccess::hasByName: Unexpected exception <InvalidName>");
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+#endif
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ // unreachable, but still there to make compiler happy
+ OSL_ASSERT(!"Unreachable code");
+ return false;
+}
+
+//-----------------------------------------------------------------------------------
+uno::Any implGetByName(NodeAccess& rNode, const rtl::OUString& sName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree( lock.getTree() );
+ configuration::NodeRef aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildOrElementName(sName,aTree,aNode);
+
+ configuration::AnyNodeRef aChildNode = configuration::getChildOrElement(aTree,aNode, aChildName);
+ if (!aChildNode.isValid())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Child Element '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw com::sun::star::container::NoSuchElementException( sMessage, xContext );
+ }
+ OSL_ASSERT(aNode.isValid());
+
+ return configapi::makeElement( rNode.getFactory(), aTree, aChildNode );
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw com::sun::star::container::NoSuchElementException( e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ // unreachable, but still there to make some compilers happy
+ OSL_ASSERT(!"Unreachable code");
+ return uno::Any();
+}
+
+//-----------------------------------------------------------------------------------
+// TODO: optimization - less locking for group nodes
+//-----------------------------------------------------------------------------------
+uno::Sequence< rtl::OUString > implGetElementNames( NodeAccess& rNode ) throw( uno::RuntimeException)
+{
+ CollectNodeNames aCollect;
+
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ lock.getTree()->dispatchToChildren(lock.getNode(), aCollect);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return makeSequence( aCollect.list() );
+}
+
+// XHierarchicalNameAccess
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// TO DO: optimization - cache the node found for subsequent getByHierarchicalName()
+//-----------------------------------------------------------------------------------
+sal_Bool implHasByHierarchicalName(NodeAccess& rNode, const rtl::OUString& sHierarchicalName ) throw(uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree( lock.getTree() );
+ configuration::NodeRef aNode( lock.getNode() );
+
+ configuration::RelativePath aRelPath = configuration::validateAndReducePath( sHierarchicalName, aTree, aNode );
+
+ return configuration::getDeepDescendant(aTree, aNode, aRelPath).isValid();
+ }
+ catch (configuration::InvalidName& )
+ {
+ OSL_TRACE("WARNING: Configuration::hasByHierarchicalName: query uses locally invalid Path");
+ return false;
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ // unreachable, but still there to make some compilers happy
+ OSL_ASSERT(!"Unreachable code");
+ return false;
+}
+
+//-----------------------------------------------------------------------------------
+uno::Any implGetByHierarchicalName(NodeAccess& rNode, const rtl::OUString& sHierarchicalName )
+ throw(css::container::NoSuchElementException, uno::RuntimeException)
+{
+ // rtl::OUString aTmpStr(implGetHierarchicalName(rNode));
+ // RTL_LOGFILE_CONTEXT_TRACE2(aLog, "Node: %s HierachicalName: %s",RTL_LOGFILE_OU2A(aTmpStr), RTL_LOGFILE_OU2A(sHierarchicalName));
+
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree( lock.getTree() );
+ configuration::NodeRef aNode( lock.getNode() );
+
+ configuration::RelativePath aRelPath = configuration::validateAndReducePath( sHierarchicalName, aTree, aNode );
+
+ configuration::AnyNodeRef aNestedNode = configuration::getDeepDescendant( aTree, aNode, aRelPath );
+ if (!aNestedNode.isValid())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Descendant Element '") );
+ sMessage += aRelPath.toString();
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in Node ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw com::sun::star::container::NoSuchElementException( sMessage, xContext );
+ }
+
+ OSL_ASSERT(aNode.isValid());
+ return configapi::makeElement( rNode.getFactory(), aTree, aNestedNode );
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw com::sun::star::container::NoSuchElementException( e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ // unreachable, but still there to make some compilers happy
+ OSL_ASSERT(!"Unreachable code");
+ return uno::Any();
+}
+
+// XPropertyWithState
+//---------------------------------------------------------------------
+css::beans::PropertyState implGetStateAsProperty(NodeAccess& rNode)
+ throw (uno::RuntimeException)
+{
+ css::beans::PropertyState aRet = css::beans::PropertyState_AMBIGUOUS_VALUE;
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ if ( lock.getTree()->isNodeDefault( lock.getNode() ) )
+ aRet = css::beans::PropertyState_DEFAULT_VALUE;
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ return aRet;
+}
+
+uno::Reference< uno::XInterface > implGetDefaultAsProperty(NodeAccess& )
+ throw (css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ // not really supported
+
+ /* possible, but nor really useful:
+ GuardedNodeAccess lock( rNode );
+ if (implGetStateAsProperty(rNode) == PropertyState_DEFAULT_VALUE)
+ return rNode.getUnoInstance();
+ */
+
+ return uno::Reference< uno::XInterface >();
+}
+
+
+// set-specific Interfaces
+//-----------------------------------------------------------------------------------
+
+
+// XTemplateContainer
+//-----------------------------------------------------------------------------------
+rtl::OUString SAL_CALL implGetElementTemplateName(NodeSetInfoAccess& rNode)
+ throw(uno::RuntimeException)
+{
+ GuardedNodeData<NodeSetInfoAccess> lock(rNode);
+ return rNode.getElementInfo()->getPathString();
+}
+
+//-----------------------------------------------------------------------------------
+ } // namespace configapi
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/accessimpl.hxx b/configmgr/source/api2/accessimpl.hxx
new file mode 100644
index 000000000000..251e0c73000a
--- /dev/null
+++ b/configmgr/source/api2/accessimpl.hxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: accessimpl.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_BASEACCESSIMPL_HXX_
+#define CONFIGMGR_API_BASEACCESSIMPL_HXX_
+
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/configuration/XTemplateInstance.hpp>
+#include <com/sun/star/configuration/XTemplateContainer.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XProperty.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/XPropertyWithState.hpp>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+
+ /* implementations of the interfaces supported by a (parent) node
+ within the configuration tree.
+ (read-only operation)
+ */
+ namespace configapi
+ {
+ class NodeAccess;
+ class NodeSetInfoAccess;
+ class NodeGroupInfoAccess;
+
+ // XHierarchicalName
+ rtl::OUString implGetHierarchicalName(NodeAccess& rNode)
+ throw(uno::RuntimeException);
+
+ rtl::OUString implComposeHierarchicalName(NodeGroupInfoAccess& rNode, const rtl::OUString& aRelativeName )
+ throw(css::lang::IllegalArgumentException, css::lang::NoSupportException, uno::RuntimeException);
+
+ rtl::OUString implComposeHierarchicalName(NodeSetInfoAccess& rNode, const rtl::OUString& aRelativeName )
+ throw(css::lang::IllegalArgumentException, css::lang::NoSupportException, uno::RuntimeException);
+
+ // XElementAccess, base class of XNameAccess
+ uno::Type implGetElementType(NodeGroupInfoAccess& rNode)
+ throw(uno::RuntimeException);
+
+ uno::Type implGetElementType(NodeSetInfoAccess& rNode)
+ throw(uno::RuntimeException);
+
+ sal_Bool implHasElements(NodeGroupInfoAccess& rNode)
+ throw(uno::RuntimeException);
+
+ sal_Bool implHasElements(NodeSetInfoAccess& rNode)
+ throw(uno::RuntimeException);
+
+ // XNameAccess
+ uno::Any implGetByName(NodeAccess& rNode, const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ uno::Sequence< rtl::OUString > implGetElementNames(NodeAccess& rNode)
+ throw( uno::RuntimeException);
+
+ sal_Bool implHasByName(NodeAccess& rNode, const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XHierarchicalNameAccess
+ uno::Any implGetByHierarchicalName(NodeAccess& rNode, const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, uno::RuntimeException);
+
+ sal_Bool implHasByHierarchicalName(NodeAccess& rNode, const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XExactName
+ rtl::OUString implGetExactName(NodeGroupInfoAccess& rNode, const rtl::OUString& aApproximateName )
+ throw(uno::RuntimeException);
+
+ rtl::OUString implGetExactName(NodeSetInfoAccess& rNode, const rtl::OUString& aApproximateName )
+ throw(uno::RuntimeException);
+
+ // XProperty
+ css::beans::Property implGetAsProperty(NodeAccess& rNode)
+ throw(uno::RuntimeException);
+
+ // XPropertySetInfo
+ uno::Sequence< css::beans::Property > implGetProperties( NodeAccess& rNode )
+ throw (uno::RuntimeException);
+
+ css::beans::Property implGetPropertyByName( NodeAccess& rNode, const rtl::OUString& aName )
+ throw (css::beans::UnknownPropertyException, uno::RuntimeException);
+
+ sal_Bool implHasPropertyByName( NodeAccess& rNode, const rtl::OUString& name )
+ throw (uno::RuntimeException);
+
+
+ // XPropertyWithState
+ css::beans::PropertyState implGetStateAsProperty(NodeAccess& rNode)
+ throw (uno::RuntimeException);
+
+ uno::Reference< uno::XInterface > implGetDefaultAsProperty(NodeAccess& rNode)
+ throw (css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // set-specific interfaces
+
+ // XTemplateContainer
+ rtl::OUString SAL_CALL implGetElementTemplateName(NodeSetInfoAccess& rNode)
+ throw(uno::RuntimeException);
+
+ }
+
+}
+#endif // CONFIGMGR_API_BASEACCESSIMPL_HXX_
+
+
diff --git a/configmgr/source/api2/apiaccessobj.cxx b/configmgr/source/api2/apiaccessobj.cxx
new file mode 100644
index 000000000000..ae78333c8ef9
--- /dev/null
+++ b/configmgr/source/api2/apiaccessobj.cxx
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apiaccessobj.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "apiaccessobj.hxx"
+
+#include "apiserviceinfo.hxx"
+#include "confsvccomponent.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//========================================================================
+//= service infos
+//========================================================================
+/*
+const AsciiServiceName c_aUserContainerServices[] =
+{
+ "com.sun.star.configuration.UserAdministration",
+ "com.sun.star.configuration.ConfigurationContainer",
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ "com.sun.star.configuration.ConfigurationAccess",
+ NULL
+};
+const AsciiServiceName c_aContainerServices[] =
+{
+ "com.sun.star.configuration.ConfigurationContainer",
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ "com.sun.star.configuration.ConfigurationAccess",
+ NULL
+};
+const AsciiServiceName c_aUpdateServices[] =
+{
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ "com.sun.star.configuration.ConfigurationAccess",
+ NULL
+};
+
+const AsciiServiceName c_aAccessServices[] =
+{
+ "com.sun.star.configuration.ConfigurationAccess",
+ NULL
+};
+
+const AsciiServiceName c_aNoServices[] =
+{
+ NULL
+};
+//-----------------------------------------------------------------------------
+
+ServiceInfo const aInnerGroupInfoSI =
+{
+ "com.sun.star.configuration.configmgr.OInnerGroupInfoAccess",
+ c_aNoServices
+};
+ServiceInfo const aInnerGroupUpdateSI =
+{
+ "com.sun.star.configuration.configmgr.OInnerGroupUpdateAccess",
+ c_aNoServices
+};
+ServiceInfo const aInnerSetInfoSI =
+{
+ "com.sun.star.configuration.configmgr.OInnerSetInfoAccess",
+ c_aNoServices
+};
+ServiceInfo const aInnerTreeSetSI =
+{
+ "com.sun.star.configuration.configmgr.OInnerTreeSetUpdateAccess",
+ c_aNoServices
+};
+ServiceInfo const aInnerValueSetSI =
+{
+ "com.sun.star.configuration.configmgr.OInnerValueSetUpdateAccess",
+ c_aNoServices
+};
+//-----------------------------------------------------------------------------
+
+ServiceInfo const aSetElementGroupInfoSI =
+{
+ "com.sun.star.configuration.configmgr.OSetElementGroupInfoAccess",
+ c_aAccessServices
+};
+ServiceInfo const aSetElementGroupUpdateSI =
+{
+ "com.sun.star.configuration.configmgr.OSetElementGroupUpdateAccess",
+ c_aUpdateServices
+};
+ServiceInfo const aSetElementSetInfoSI =
+{
+ "com.sun.star.configuration.configmgr.OSetElementSetInfoAccess",
+ c_aAccessServices
+};
+ServiceInfo const aSetElementTreeSetSI =
+{
+ "com.sun.star.configuration.configmgr.OSetElementTreeSetUpdateAccess",
+ c_aContainerServices
+};
+ServiceInfo const aSetElementValueSetSI =
+{
+ "com.sun.star.configuration.configmgr.OSetElementValueSetUpdateAccess",
+ c_aContainerServices
+};
+//-----------------------------------------------------------------------------
+
+ServiceInfo const aRootElementGroupInfoSI =
+{
+ "com.sun.star.configuration.configmgr.ORootElementGroupInfoAccess",
+ c_aAccessServices
+};
+ServiceInfo const aRootElementGroupUpdateSI =
+{
+ "com.sun.star.configuration.configmgr.ORootElementGroupUpdateAccess",
+ c_aUpdateServices
+};
+ServiceInfo const aRootElementSetInfoSI =
+{
+ "com.sun.star.configuration.configmgr.ORootElementSetInfoAccess",
+ c_aAccessServices
+};
+ServiceInfo const aRootElementTreeSetUpdateSI =
+{
+ "com.sun.star.configuration.configmgr.ORootElementTreeSetUpdateAccess",
+ c_aContainerServices
+};
+ServiceInfo const aRootElementValueSetUpdateSI =
+{
+ "com.sun.star.configuration.configmgr.ORootElementValueSetUpdateAccess",
+ c_aContainerServices
+};
+//-----------------------------------------------------------------------------
+
+ServiceInfo const aRootElementReadAccessSI =
+{
+ "com.sun.star.configuration.configmgr.ORootElementReadAccess",
+ c_aAccessServices
+};
+ServiceInfo const aRootElementUpdateAccessSI =
+{
+ "com.sun.star.configuration.configmgr.ORootElementUpdateAccess",
+ c_aUpdateServices
+};
+ServiceInfo const aRootElementAdminAccessSI =
+{
+ "com.sun.star.configuration.configmgr.ORootElementUserAdminAccess",
+ c_aUserContainerServices
+};*/
+
+//========================================================================
+//= service info static members
+//========================================================================
+
+//-----------------------------------------------------------------------------
+// Inner Elements
+//-----------------------------------------------------------------------------
+
+template <>
+ServiceImplementationInfo const *
+const OInnerElement<NodeGroupInfoAccess>::s_pServiceInfo = &aInnerGroupInfoSI;
+
+template <>
+ServiceImplementationInfo const *
+const OInnerElement<NodeGroupAccess>::s_pServiceInfo = &aInnerGroupUpdateSI;
+
+template <>
+ServiceImplementationInfo const *
+const OInnerElement<NodeSetInfoAccess>::s_pServiceInfo = &aInnerSetInfoSI;
+
+template <>
+ServiceImplementationInfo const *
+const OInnerElement<NodeTreeSetAccess>::s_pServiceInfo = &aInnerTreeSetSI;
+
+template <>
+ServiceImplementationInfo const *
+const OInnerElement<NodeValueSetAccess>::s_pServiceInfo = &aInnerValueSetSI;
+
+
+//-----------------------------------------------------------------------------
+// Set Elements
+//-----------------------------------------------------------------------------
+
+template <>
+ServiceImplementationInfo const *
+const OSetElement<NodeGroupInfoAccess>::s_pServiceInfo = &aSetElementGroupInfoSI;
+
+template <>
+ServiceImplementationInfo const *
+const OSetElement<NodeGroupAccess>::s_pServiceInfo = &aSetElementGroupUpdateSI;
+
+template <>
+ServiceImplementationInfo const *
+const OSetElement<NodeSetInfoAccess>::s_pServiceInfo = &aSetElementSetInfoSI;
+
+template <>
+ServiceImplementationInfo const *
+const OSetElement<NodeTreeSetAccess>::s_pServiceInfo = &aSetElementTreeSetSI;
+
+template <>
+ServiceImplementationInfo const *
+const OSetElement<NodeValueSetAccess>::s_pServiceInfo = &aSetElementValueSetSI;
+
+//-----------------------------------------------------------------------------
+// Root Elements
+//-----------------------------------------------------------------------------
+
+template <>
+ServiceImplementationInfo const *
+const OReadRootElement<NodeGroupInfoAccess>::s_pServiceInfo = &aRootElementGroupInfoSI;
+
+template <>
+ServiceImplementationInfo const *
+const OUpdateRootElement<NodeGroupAccess>::s_pServiceInfo = &aRootElementGroupUpdateSI;
+
+template <>
+ServiceImplementationInfo const *
+const OReadRootElement<NodeSetInfoAccess>::s_pServiceInfo = &aRootElementSetInfoSI;
+
+template <>
+ServiceImplementationInfo const *
+const OUpdateRootElement<NodeTreeSetAccess>::s_pServiceInfo = &aRootElementTreeSetUpdateSI;
+
+template <>
+ServiceImplementationInfo const *
+const OUpdateRootElement<NodeValueSetAccess>::s_pServiceInfo = &aRootElementValueSetUpdateSI;
+
+
+
+//========================================================================
+//= Instantiations
+//========================================================================
+/*
+//-----------------------------------------------------------------------------
+// Inner Elements
+//-----------------------------------------------------------------------------
+
+template class OInnerElement<NodeGroupInfoAccess>; // OInnerGroupInfoAccess
+template class OInnerElement<NodeGroupAccess>; // OInnerGroupUpdateAccess
+template class OInnerElement<NodeSetInfoAccess>; // OInnerSetInfoAccess
+template class OInnerElement<NodeTreeSetAccess>; // OInnerTreeSetUpdateAccess
+template class OInnerElement<NodeValueSetAccess>; // OInnerValueSetUpdateAccess
+
+//-----------------------------------------------------------------------------
+// Set Elements
+//-----------------------------------------------------------------------------
+template class OSetElement<NodeGroupInfoAccess>; // OSetElementGroupInfoAccess
+template class OSetElement<NodeGroupAccess>; // OSetElementGroupUpdateAccess
+template class OSetElement<NodeSetInfoAccess>; // OSetElementSetInfoAccess
+template class OSetElement<NodeTreeSetAccess>; // OSetElementTreeSetUpdateAccess
+template class OSetElement<NodeValueSetAccess>; // OSetElementValueSetUpdateAccess
+
+//-----------------------------------------------------------------------------
+// Root Elements
+//-----------------------------------------------------------------------------
+
+template class OReadRootElement<NodeGroupInfoAccess>; // ORootElementGroupInfoAccess
+template class OUpdateRootElement<NodeGroupAccess>; // ORootElementGroupUpdateAccess
+template class OReadRootElement<NodeSetInfoAccess>; // ORootElementSetInfoAccess
+template class OUpdateRootElement<NodeTreeSetAccess>; // ORootElementTreeSetUpdateAccess
+template class OUpdateRootElement<NodeValueSetAccess>; // ORootElementValueSetUpdateAccess
+*/
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/api2/apiaccessobj.hxx b/configmgr/source/api2/apiaccessobj.hxx
new file mode 100644
index 000000000000..2536dc5b7318
--- /dev/null
+++ b/configmgr/source/api2/apiaccessobj.hxx
@@ -0,0 +1,148 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apiaccessobj.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_ACCESSOBJECTS_HXX_
+#define CONFIGMGR_API_ACCESSOBJECTS_HXX_
+
+#include "apitreeaccess.hxx"
+#include "apinodeaccess.hxx"
+#include "apinodeupdate.hxx"
+
+#include "apitreeimplobj.hxx"
+#include "noderef.hxx"
+
+#include "apiserviceinfo.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+// Inner Elements
+//-----------------------------------------------------------------------------
+
+ template <class NodeClass>
+ class OInnerElement : public InnerElement, public NodeClass
+ {
+ static ServiceImplementationInfo const*const s_pServiceInfo;
+
+ uno::XInterface* m_pUnoThis;
+ ApiTreeImpl& m_rTree;
+ configuration::NodeRef m_aNode;
+ public:
+ inline OInnerElement(uno::XInterface* pUnoThis,ApiTreeImpl& rTree, configuration::NodeRef const& aNode);
+ inline ~OInnerElement();
+
+ virtual inline configuration::NodeRef doGetNode() const;
+ virtual inline ApiTreeImpl& getApiTree() const;
+
+ virtual inline uno::XInterface* doGetUnoInstance() const;
+ virtual inline ServiceImplementationInfo const* doGetServiceInfo() const;
+
+ static inline ServiceImplementationInfo const* getStaticServiceInfo();
+ };
+
+//-----------------------------------------------------------------------------
+// Set Elements
+//-----------------------------------------------------------------------------
+
+ template <class NodeClass>
+ class OSetElement : public SetElement, public NodeClass
+ {
+ static ServiceImplementationInfo const*const s_pServiceInfo;
+
+ mutable ApiTreeImpl m_aTree;
+ public:
+ OSetElement(uno::XInterface* pUnoThis, rtl::Reference< configuration::Tree > const& aTree, ApiProvider& rProvider, ApiTreeImpl* pParentTree = 0)
+ : m_aTree(pUnoThis, rProvider,aTree,pParentTree)
+ {}
+
+ virtual inline configuration::NodeRef doGetNode() const;
+ virtual inline ApiTreeImpl& getApiTree() const;
+
+ virtual inline uno::XInterface* doGetUnoInstance() const;
+ virtual inline ServiceImplementationInfo const* doGetServiceInfo() const;
+
+ static inline ServiceImplementationInfo const* getStaticServiceInfo();
+ };
+
+//-----------------------------------------------------------------------------
+// Root Elements
+//-----------------------------------------------------------------------------
+
+ template <class NodeClass>
+ class OReadRootElement : public RootElement, public NodeClass
+ {
+ static ServiceImplementationInfo const*const s_pServiceInfo;
+ mutable ApiRootTreeImpl m_aRootTree;
+ public:
+ OReadRootElement(uno::XInterface* pUnoThis, ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions >const& _xOptions)
+ : m_aRootTree(pUnoThis, rProvider,aTree, _xOptions)
+ {}
+
+ virtual inline configuration::NodeRef doGetNode() const;
+ virtual inline ApiTreeImpl& getApiTree() const;
+ virtual inline ApiRootTreeImpl& getRootTree();
+
+ virtual inline uno::XInterface* doGetUnoInstance() const;
+ virtual inline ServiceImplementationInfo const* doGetServiceInfo() const;
+
+ static inline ServiceImplementationInfo const* getStaticServiceInfo();
+ };
+ //-------------------------------------------------------------------------
+
+ template <class NodeClass>
+ class OUpdateRootElement : public UpdateRootElement, public NodeClass
+ {
+ static ServiceImplementationInfo const*const s_pServiceInfo;
+
+ mutable ApiRootTreeImpl m_aRootTree;
+ public:
+ OUpdateRootElement(uno::XInterface* pUnoThis, ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions >const& _xOptions)
+ : m_aRootTree(pUnoThis, rProvider,aTree,_xOptions)
+ {}
+
+ virtual inline configuration::NodeRef doGetNode() const;
+ virtual inline ApiTreeImpl& getApiTree() const;
+ virtual inline ApiRootTreeImpl& getRootTree();
+
+ virtual inline uno::XInterface* doGetUnoInstance() const;
+ virtual inline ServiceImplementationInfo const* doGetServiceInfo() const;
+
+ static inline ServiceImplementationInfo const* getStaticServiceInfo();
+ };
+ }
+}
+//-----------------------------------------------------------------------------
+#include "apiaccessobj.inl"
+//-----------------------------------------------------------------------------
+
+#endif // CONFIGMGR_API_ACCESSOBJECTS_HXX_
diff --git a/configmgr/source/api2/apiaccessobj.inl b/configmgr/source/api2/apiaccessobj.inl
new file mode 100644
index 000000000000..c2237c2a966e
--- /dev/null
+++ b/configmgr/source/api2/apiaccessobj.inl
@@ -0,0 +1,263 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apiaccessobj.inl,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+
+//========================================================================
+//= member functions
+//========================================================================
+
+//-----------------------------------------------------------------------------
+// Inner Elements
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+OInnerElement<NodeClass>::OInnerElement(uno::XInterface* pUnoThis,ApiTreeImpl& rTree, configuration::NodeRef const& aNode)
+: m_pUnoThis(pUnoThis)
+, m_rTree(rTree)
+, m_aNode(aNode)
+{
+ m_rTree.setNodeInstance(aNode,pUnoThis);
+ m_rTree.getUnoInstance()->acquire();
+}
+
+template <class NodeClass>
+OInnerElement<NodeClass>::~OInnerElement()
+{
+ m_rTree.getUnoInstance()->release();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+configuration::NodeRef OInnerElement<NodeClass>::doGetNode() const
+{
+ return m_aNode;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ApiTreeImpl& OInnerElement<NodeClass>::getApiTree() const
+{
+ return m_rTree;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+uno::XInterface* OInnerElement<NodeClass>::doGetUnoInstance() const
+{
+ return m_pUnoThis;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ServiceImplementationInfo const* OInnerElement<NodeClass>::doGetServiceInfo() const
+{
+ return s_pServiceInfo;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ServiceImplementationInfo const* OInnerElement<NodeClass>::getStaticServiceInfo()
+{
+ return s_pServiceInfo;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Set Elements
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+configuration::NodeRef OSetElement<NodeClass>::doGetNode() const
+{
+ return m_aTree.getTree()->getRootNode();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ApiTreeImpl& OSetElement<NodeClass>::getApiTree() const
+{
+ return m_aTree;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+uno::XInterface* OSetElement<NodeClass>::doGetUnoInstance() const
+{
+ return m_aTree.getUnoInstance();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ServiceImplementationInfo const* OSetElement<NodeClass>::doGetServiceInfo() const
+{
+ return s_pServiceInfo;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ServiceImplementationInfo const* OSetElement<NodeClass>::getStaticServiceInfo()
+{
+ return s_pServiceInfo;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Read-only Root Elements
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+configuration::NodeRef OReadRootElement<NodeClass>::doGetNode() const
+{
+ return m_aRootTree.getApiTree().getTree()->getRootNode();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ApiTreeImpl& OReadRootElement<NodeClass>::getApiTree() const
+{
+ return m_aRootTree.getApiTree();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ApiRootTreeImpl& OReadRootElement<NodeClass>::getRootTree()
+{
+ return m_aRootTree;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+uno::XInterface* OReadRootElement<NodeClass>::doGetUnoInstance() const
+{
+ return m_aRootTree.getApiTree().getUnoInstance();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ServiceImplementationInfo const* OReadRootElement<NodeClass>::doGetServiceInfo() const
+{
+ return s_pServiceInfo;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ServiceImplementationInfo const* OReadRootElement<NodeClass>::getStaticServiceInfo()
+{
+ return s_pServiceInfo;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Update Root Elements
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+configuration::NodeRef OUpdateRootElement<NodeClass>::doGetNode() const
+{
+ return m_aRootTree.getApiTree().getTree()->getRootNode();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ApiTreeImpl& OUpdateRootElement<NodeClass>::getApiTree() const
+{
+ return m_aRootTree.getApiTree();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ApiRootTreeImpl& OUpdateRootElement<NodeClass>::getRootTree()
+{
+ return m_aRootTree;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+uno::XInterface* OUpdateRootElement<NodeClass>::doGetUnoInstance() const
+{
+ return m_aRootTree.getApiTree().getUnoInstance();
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ServiceImplementationInfo const* OUpdateRootElement<NodeClass>::doGetServiceInfo() const
+{
+ return s_pServiceInfo;
+}
+//-----------------------------------------------------------------------------
+
+template <class NodeClass>
+ServiceImplementationInfo const* OUpdateRootElement<NodeClass>::getStaticServiceInfo()
+{
+ return s_pServiceInfo;
+}
+//-----------------------------------------------------------------------------
+
+//========================================================================
+//= Instantiations
+//========================================================================
+/*
+//-----------------------------------------------------------------------------
+// Inner Elements
+//-----------------------------------------------------------------------------
+
+template class OInnerElement<NodeGroupInfoAccess>; // OInnerGroupInfoAccess
+template class OInnerElement<NodeGroupAccess>; // OInnerGroupUpdateAccess
+template class OInnerElement<NodeSetInfoAccess>; // OInnerSetInfoAccess
+template class OInnerElement<NodeTreeSetAccess>; // OInnerTreeSetUpdateAccess
+template class OInnerElement<NodeValueSetAccess>; // OInnerValueSetUpdateAccess
+
+//-----------------------------------------------------------------------------
+// Set Elements
+//-----------------------------------------------------------------------------
+template class OSetElement<NodeGroupInfoAccess>; // OSetElementGroupInfoAccess
+template class OSetElement<NodeGroupAccess>; // OSetElementGroupUpdateAccess
+template class OSetElement<NodeSetInfoAccess>; // OSetElementSetInfoAccess
+template class OSetElement<NodeTreeSetAccess>; // OSetElementTreeSetUpdateAccess
+template class OSetElement<NodeValueSetAccess>; // OSetElementValueSetUpdateAccess
+
+//-----------------------------------------------------------------------------
+// Root Elements
+//-----------------------------------------------------------------------------
+
+template class OReadRootElement<NodeGroupInfoAccess>; // ORootElementGroupInfoAccess
+template class OUpdateRootElement<NodeGroupAccess>; // ORootElementGroupUpdateAccess
+template class OReadRootElement<NodeSetInfoAccess>; // ORootElementSetInfoAccess
+template class OUpdateRootElement<NodeTreeSetAccess>; // ORootElementTreeSetUpdateAccess
+template class OUpdateRootElement<NodeValueSetAccess>; // ORootElementValueSetUpdateAccess
+*/
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/api2/apifactory.cxx b/configmgr/source/api2/apifactory.cxx
new file mode 100644
index 000000000000..abbf068ee508
--- /dev/null
+++ b/configmgr/source/api2/apifactory.cxx
@@ -0,0 +1,338 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apifactory.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "apifactory.hxx"
+#include "objectregistry.hxx"
+
+#include "apitreeaccess.hxx"
+#include "apitreeimplobj.hxx"
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+
+#include "noderef.hxx"
+#include "anynoderef.hxx"
+
+#include "configexcept.hxx"
+#include "configset.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+ObjectRegistry::~ObjectRegistry()
+{
+ OSL_ENSURE(m_aMap.empty(),"WARNING: Configuration Object Map: Some Objects were not revoked correctly");
+}
+
+//-----------------------------------------------------------------------------
+
+Factory::Factory(rtl::Reference<ObjectRegistry> pRegistry)
+: m_pRegistry(pRegistry)
+, m_aTunnelID()
+{
+ OSL_ENSURE(pRegistry.is(), "ERROR: Factory requires a Object Registry");
+}
+//-----------------------------------------------------------------------------
+
+Factory::~Factory()
+{
+}
+//-----------------------------------------------------------------------------
+inline
+NodeElement* Factory::implFind(configuration::NodeID const& aNode)
+{
+ return m_pRegistry->findElement(aNode);
+}
+//-----------------------------------------------------------------------------
+inline
+void Factory::doRegisterElement(configuration::NodeID const& aNode, NodeElement* pElement)
+{
+ m_pRegistry->registerElement(aNode,pElement);
+}
+//-----------------------------------------------------------------------------
+inline
+void Factory::doRevokeElement(configuration::NodeID const& aNode, NodeElement* pElement)
+{
+ m_pRegistry->revokeElement(aNode,pElement);
+}
+//-----------------------------------------------------------------------------
+
+ApiTreeImpl& Factory::getImplementation(NodeElement& rElement)
+{
+ return rElement.getApiTree();
+}
+//-----------------------------------------------------------------------------
+
+inline
+rtl::Reference<configuration::Template> Factory::implGetSetElementTemplate(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode)
+{
+ rtl::Reference<configuration::Template> aRet;
+ if (configuration::isSetNode(aTree,aNode))
+ {
+ aRet = aTree->extractElementInfo(aNode);
+ }
+ else if (!configuration::isGroupNode(aTree,aNode))
+ {
+ OSL_ENSURE( !configuration::isStructuralNode(aTree,aNode), "ERROR: Configuration: unknown kind of object");
+ throw configuration::Exception("INTERNAL ERROR: Cannot create template - Unexpected node type");
+ }
+ return aRet;
+}
+//-----------------------------------------------------------------------------
+inline
+uno::Reference< uno::XInterface > Factory::implToUno(NodeElement* pElement)
+{
+ if ( pElement )
+ return uno::Reference< uno::XInterface >(pElement->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE);
+ else
+ return uno::Reference< uno::XInterface >();
+}
+//-----------------------------------------------------------------------------
+inline
+void Factory::implHaveNewElement(configuration::NodeID aNodeID, NodeElement* pElement)
+{
+ OSL_ENSURE(pElement ,"WARNING: New API object could not be created");
+
+ if (pElement)
+ {
+ doRegisterElement(aNodeID,pElement);
+ OSL_ENSURE(implFind(aNodeID) == pElement,"WARNING: New API object could not be registered with its factory");
+ }
+}
+//-----------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > Factory::makeUnoElement(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode)
+{
+ return implToUno(makeElement(aTree,aNode));
+}
+//-----------------------------------------------------------------------------
+NodeElement* Factory::makeElement(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode)
+{
+ OSL_PRECOND( !configuration::isEmpty(aTree.get()) == aNode.isValid(), "ERROR: Configuration: Making element from tree requires valid node");
+ if (configuration::isEmpty(aTree.get()))
+ return 0;
+
+ OSL_PRECOND( aNode.isValid() && aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
+ OSL_PRECOND( configuration::isStructuralNode(aTree,aNode), "ERROR: Configuration: Cannot make object for value node");
+
+ configuration::NodeID aNodeID(aTree,aNode);
+ NodeElement* pRet = findElement(aNodeID);
+ if (pRet == 0)
+ {
+ rtl::Reference<configuration::Template> aTemplate = implGetSetElementTemplate(aTree,aNode);
+
+ if (!aTree->isRootNode(aNode))
+ {
+ pRet = doCreateGroupMember(aTree,aNode,aTemplate.get());
+ }
+ else
+ {
+ rtl::Reference< configuration::ElementTree > aElementTree(dynamic_cast< configuration::ElementTree * >(aTree.get()));
+ if (aElementTree.is())
+ {
+ pRet = doCreateSetElement(aElementTree,aTemplate.get());
+ }
+ else
+ {
+ OSL_ENSURE(configuration::isEmpty(aTree->getContextTree()),"INTERNAL ERROR: Found tree (not a set element) with a parent tree.");
+ pRet = doCreateAccessRoot(aTree,aTemplate.get(), vos::ORef< OOptions >());
+ }
+ }
+ implHaveNewElement(aNodeID,pRet);
+ }
+ return pRet;
+}
+//-----------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > Factory::findUnoElement(configuration::NodeID const& aNodeID)
+{
+ return implToUno(findElement(aNodeID));
+}
+//-----------------------------------------------------------------------------
+NodeElement* Factory::findElement(configuration::NodeID const& aNodeID)
+{
+ NodeElement* pReturn = implFind(aNodeID);
+ if (pReturn) pReturn->getUnoInstance()->acquire();
+ return pReturn;
+}
+//-----------------------------------------------------------------------------
+
+void Factory::revokeElement(configuration::NodeID const& aNodeID)
+{
+ if (NodeElement* pElement = implFind(aNodeID))
+ doRevokeElement(aNodeID, pElement);
+}
+//-----------------------------------------------------------------------------
+
+TreeElement* Factory::makeAccessRoot(rtl::Reference< configuration::Tree > const& aTree, RequestOptions const& _aOptions)
+{
+ OSL_PRECOND( !configuration::isEmpty(aTree.get()) , "ERROR: Configuration: Making element from tree requires valid tree");
+ if (configuration::isEmpty(aTree.get())) return 0;
+
+ OSL_ENSURE(configuration::isEmpty(aTree->getContextTree()),"INTERNAL ERROR: Tree with parent tree should not be used for an access root");
+ OSL_ENSURE(dynamic_cast< configuration::ElementTree * >(aTree.get()) == 0, "INTERNAL ERROR: Element Tree should not be used for an access root");
+
+ configuration::NodeRef aRoot = aTree->getRootNode();
+ OSL_ENSURE(aRoot.isValid(),"INTERNAL ERROR: Tree has no root node");
+
+ OSL_PRECOND( configuration::isStructuralNode(aTree,aRoot), "ERROR: Configuration: Cannot make object for value node");
+
+ configuration::NodeID aNodeID(aTree,aRoot);
+ // must be a tree element if it is a tree root
+ TreeElement* pRet = static_cast<TreeElement*>(findElement(aNodeID));
+ if (0 == pRet)
+ {
+ rtl::Reference<configuration::Template> aTemplate = implGetSetElementTemplate(aTree,aRoot);
+ vos::ORef<OOptions> xOptions = new OOptions(_aOptions);
+ pRet = doCreateAccessRoot(aTree,aTemplate.get(), xOptions);
+ implHaveNewElement (aNodeID,pRet);
+ }
+ return pRet;
+}
+//-----------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > Factory::makeUnoSetElement(rtl::Reference< configuration::ElementTree > const& aElementTree)
+{
+ uno::Reference< uno::XInterface > aRet = implToUno(makeSetElement(aElementTree));
+ OSL_ENSURE( uno::Reference<lang::XUnoTunnel>::query(aRet).is(),"ERROR: API set element has no UnoTunnel");
+ OSL_ENSURE( uno::Reference<lang::XUnoTunnel>::query(aRet).is() &&
+ 0 != uno::Reference<lang::XUnoTunnel>::query(aRet)->getSomething(doGetElementTunnelID()),
+ "ERROR: API set element does not support the right tunnel ID");
+
+ return aRet;
+}
+//-----------------------------------------------------------------------------
+
+SetElement* Factory::makeSetElement(rtl::Reference< configuration::ElementTree > const& aElementTree)
+{
+ OSL_PRECOND( aElementTree.is() , "ERROR: Configuration: Making element from tree requires valid tree");
+ if (!aElementTree.is()) return 0;
+
+ rtl::Reference< configuration::Tree > aTree(aElementTree.get());
+ OSL_ENSURE(!configuration::isEmpty(aTree.get()),"INTERNAL ERROR: Element Tree has no Tree");
+
+ configuration::NodeRef aRoot = aTree->getRootNode();
+ OSL_ENSURE(aRoot.isValid(),"INTERNAL ERROR: Tree has no root node");
+
+ OSL_ENSURE( configuration::isStructuralNode(aTree,aRoot), "ERROR: Configuration: Cannot make object for value node");
+
+ configuration::NodeID aNodeID(aTree,aRoot);
+ // must be a set element if it wraps a ElementTree
+ SetElement* pRet = static_cast<SetElement*>( findElement(aNodeID) );
+ if (0 == pRet)
+ {
+ rtl::Reference<configuration::Template> aTemplate = implGetSetElementTemplate(aTree,aRoot);
+
+ pRet = doCreateSetElement(aElementTree,aTemplate.get());
+
+ implHaveNewElement(aNodeID,pRet);
+ }
+ return pRet;
+}
+//-----------------------------------------------------------------------------
+
+SetElement* Factory::findSetElement(rtl::Reference< configuration::ElementTree > const& aElement)
+{
+ OSL_PRECOND( aElement.is() , "ERROR: Configuration: Making element from tree requires valid tree");
+ if (!aElement.is()) return 0;
+
+ rtl::Reference< configuration::Tree > aTree(aElement.get());
+ OSL_ENSURE(!isEmpty(aTree.get()),"INTERNAL ERROR: Element Tree has no Tree");
+
+ configuration::NodeRef aRoot = aTree->getRootNode();
+ OSL_ENSURE(aRoot.isValid(),"INTERNAL ERROR: Tree has no root node");
+
+ configuration::NodeID aNodeID(aTree,aRoot);
+ // must be a set element if it wraps a ElementTree
+ SetElement* pRet = static_cast<SetElement*>( findElement(aNodeID) );
+
+ return pRet;
+}
+//-----------------------------------------------------------------------------
+
+SetElement* Factory::extractSetElement(uno::Any const& aElement)
+{
+ SetElement* pTunneledImpl = 0;
+
+ uno::Reference< lang::XUnoTunnel > xElementTunnel;
+ if ( aElement.hasValue() && (aElement >>= xElementTunnel) )
+ {
+ OSL_ASSERT( xElementTunnel.is() );
+
+ sal_Int64 nSomething = xElementTunnel->getSomething(doGetElementTunnelID());
+ if (0 != nSomething)
+ {
+ void* pVoid = reinterpret_cast<void*>(nSomething);
+ pTunneledImpl = static_cast<SetElement*>(pVoid);
+ }
+ }
+ return pTunneledImpl;
+}
+//-----------------------------------------------------------------------------
+
+bool Factory::tunnelSetElement(sal_Int64& nSomething, SetElement& rElement, uno::Sequence< sal_Int8 > const& aTunnelID)
+{
+ if (aTunnelID == doGetElementTunnelID())
+ {
+ void* pVoid = &rElement;
+ nSomething = reinterpret_cast<sal_Int64>(pVoid);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+
+ApiTreeImpl const* Factory::findDescendantTreeImpl(configuration::NodeID const& aNode, ApiTreeImpl const* pImpl)
+{
+ ApiTreeImpl* pRet = 0;
+ if (pImpl)
+ {
+ if ( NodeElement* pElement = pImpl->getFactory().implFind( aNode ) )
+ pRet = &pElement->getApiTree();
+ }
+ return pRet;
+}
+
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/api2/apifactory.hxx b/configmgr/source/api2/apifactory.hxx
new file mode 100644
index 000000000000..8769f1f2100b
--- /dev/null
+++ b/configmgr/source/api2/apifactory.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apifactory.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#define CONFIGMGR_API_FACTORY_HXX_
+
+#include "options.hxx"
+#include "utility.hxx"
+#include <boost/utility.hpp>
+#include <rtl/ref.hxx>
+#include <vos/ref.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+ class NodeID;
+ class NodeRef;
+ class ElementTree;
+ class Template;
+ class Tree;
+ }
+ namespace configapi
+ {
+ namespace uno = com::sun::star::uno;
+
+ class ApiTreeImpl;
+ class NodeElement;
+ class InnerElement;
+ class TreeElement;
+ class SetElement;
+ class RootElement;
+
+ // used to register objects
+ class ObjectRegistry;
+
+ // used to create UNO objects
+ class Factory : private boost::noncopyable
+ {
+ rtl::Reference<ObjectRegistry> m_pRegistry;
+ cppu::OImplementationId const m_aTunnelID;
+
+ private:
+ /// return the element _without_ acquiring it
+ NodeElement* implFind(configuration::NodeID const& aNode);
+
+ public:
+ Factory(rtl::Reference<ObjectRegistry> pRegistry);
+ virtual ~Factory();
+
+ uno::Reference< uno::XInterface > makeUnoElement(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode);
+ uno::Reference< uno::XInterface > findUnoElement(configuration::NodeID const& aNode);
+
+ uno::Reference< uno::XInterface > makeUnoSetElement(rtl::Reference< configuration::ElementTree > const& aTree);
+
+ NodeElement* makeElement(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode);
+ NodeElement* findElement(configuration::NodeID const& aNode);
+
+ TreeElement* makeAccessRoot(rtl::Reference< configuration::Tree > const& aTree, RequestOptions const& _aOptions);
+ SetElement* makeSetElement(rtl::Reference< configuration::ElementTree > const& aTree);
+
+ SetElement* findSetElement(rtl::Reference< configuration::ElementTree > const& aElement);
+
+ /// check for the existence of an element
+ sal_Bool hasElement(configuration::NodeID const& _rNode) { return NULL != implFind(_rNode); }
+
+ void revokeElement(configuration::NodeID const& aNode);
+
+ SetElement* extractSetElement(uno::Any const& aElement);
+ bool tunnelSetElement(sal_Int64& nSomething, SetElement& rElement, uno::Sequence< sal_Int8 > const& aTunnelID);
+ // registry operations
+
+ static ApiTreeImpl const* findDescendantTreeImpl(configuration::NodeID const& aNode, ApiTreeImpl const* pImpl);
+ protected:
+ void doRegisterElement(configuration::NodeID const& aNode, NodeElement* pElement);
+ void doRevokeElement(configuration::NodeID const& aNode, NodeElement* pElement);
+
+ uno::Sequence< sal_Int8 > doGetElementTunnelID() const { return m_aTunnelID.getImplementationId(); }
+
+ virtual NodeElement* doCreateGroupMember(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode, configuration::Template* pSetElementTemplate) = 0;
+ virtual TreeElement* doCreateAccessRoot(rtl::Reference< configuration::Tree > const& aTree, configuration::Template* pSetElementTemplate, vos::ORef< OOptions >const& _xOptions) = 0;
+ virtual SetElement* doCreateSetElement(rtl::Reference< configuration::ElementTree > const& aTree, configuration::Template* pSetElementTemplate) = 0;
+
+ static ApiTreeImpl& getImplementation(NodeElement& pElement);
+ private:
+ static rtl::Reference<configuration::Template> implGetSetElementTemplate(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode);
+ static uno::Reference< uno::XInterface > implToUno(NodeElement* pNode);
+ void implHaveNewElement(configuration::NodeID aNodeID, NodeElement* pNode);
+ };
+
+ }
+}
+
+#endif // CONFIGMGR_API_FACTORY_HXX_
diff --git a/configmgr/source/api2/apifactoryimpl.cxx b/configmgr/source/api2/apifactoryimpl.cxx
new file mode 100644
index 000000000000..41311f310dd4
--- /dev/null
+++ b/configmgr/source/api2/apifactoryimpl.cxx
@@ -0,0 +1,355 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apifactoryimpl.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "apifactoryimpl.hxx"
+
+#include "setobjects.hxx"
+#include "groupobjects.hxx"
+
+#include "configset.hxx"
+#include "configpath.hxx"
+#include "template.hxx"
+#include "noderef.hxx"
+#include "objectregistry.hxx"
+#include "attributes.hxx"
+
+namespace configmgr
+{
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+// class ReadOnlyObjectFactory
+//-----------------------------------------------------------------------------
+
+ReadOnlyObjectFactory::ReadOnlyObjectFactory(ApiProvider& rProvider,rtl::Reference<ObjectRegistry> pRegistry)
+: Factory(pRegistry)
+, m_rProvider(rProvider)
+{
+}
+//-----------------------------------------------------------------------------
+
+ReadOnlyObjectFactory::~ReadOnlyObjectFactory()
+{
+}
+//-----------------------------------------------------------------------------
+
+NodeElement* ReadOnlyObjectFactory::doCreateGroupMember(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode, configuration::Template* pSetElementTemplate)
+{
+ OSL_ENSURE(!configuration::isEmpty(aTree.get()), "ERROR: trying to create a group member without a tree");
+ OSL_ENSURE(aNode.isValid(), "ERROR: trying to create a group member without a node");
+ OSL_ENSURE(aTree->isValidNode(aNode.getOffset()), "ERROR: node does not match tree , while trying to create a group member");
+ OSL_ENSURE(!aTree->isRootNode(aNode), "ERROR: trying to create a group member on a root node");
+ if (aTree->isRootNode(aNode))
+ return 0;
+
+ NodeElement* pRootElement = makeElement(aTree,aTree->getRootNode());
+ OSL_ENSURE(pRootElement, "Could not create root element of tree - cannot create group member object");
+ if (!pRootElement)
+ return 0;
+
+ uno::Reference<uno::XInterface> aRootRelease(pRootElement->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE);
+ ApiTreeImpl& rRootContext = getImplementation(*pRootElement);
+
+ NodeElement * pResult = 0;
+ if (!pSetElementTemplate)
+ {
+ OInnerGroupInfo * pNewObject = new OInnerGroupInfo(rRootContext, aNode);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ OInnerSetInfo * pNewObject = new OInnerSetInfo(rRootContext, aNode);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+
+ return pResult;
+}
+//-----------------------------------------------------------------------------
+
+TreeElement* ReadOnlyObjectFactory::doCreateAccessRoot(rtl::Reference< configuration::Tree > const& aTree, configuration::Template* pSetElementTemplate, vos::ORef< OOptions >const& _xOptions)
+{
+ OSL_ENSURE(!configuration::isEmpty(aTree.get()), "ERROR: trying to create a root object without a tree");
+
+ TreeElement * pResult = 0;
+ if (!pSetElementTemplate)
+ {
+ ORootElementGroupInfo * pNewObject = new ORootElementGroupInfo(m_rProvider, aTree, _xOptions);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ ORootElementSetInfo * pNewObject = new ORootElementSetInfo(m_rProvider, aTree, _xOptions);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ return pResult;
+}
+
+//-----------------------------------------------------------------------------
+SetElement* ReadOnlyObjectFactory::doCreateSetElement(rtl::Reference< configuration::ElementTree > const& aElementTree, configuration::Template* pSetElementTemplate)
+{
+ OSL_ENSURE(aElementTree.is(), "ERROR: trying to create a set element object without a tree");
+
+ rtl::Reference< configuration::Tree > aTree( aElementTree.get() );
+ OSL_ENSURE(!configuration::isEmpty(aTree.get()), "ERROR: trying to create a set element object without a tree");
+
+ ApiTreeImpl * pParentContext = 0;
+ uno::Reference<uno::XInterface> aParentRelease;
+
+ rtl::Reference< configuration::Tree > aParentTree = aTree->getContextTree();
+ if (!configuration::isEmpty(aParentTree.get()))
+ {
+ //configuration::NodeRef aParentNode = aTree.getContextNode();
+ configuration::NodeRef aParentRoot = aParentTree->getRootNode();
+ if (NodeElement* pParentRootElement = makeElement(aParentTree,aParentRoot) )
+ {
+ aParentRelease = uno::Reference<uno::XInterface>(pParentRootElement->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE);
+ pParentContext = &getImplementation(*pParentRootElement);
+ }
+ }
+
+ SetElement * pResult = 0;
+ if (!pSetElementTemplate)
+ {
+ OSetElementGroupInfo * pNewObject = new OSetElementGroupInfo(aTree,m_rProvider,pParentContext);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ OSetElementSetInfo * pNewObject = new OSetElementSetInfo(aTree,m_rProvider,pParentContext);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ return pResult;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class UpdateObjectFactory
+//-----------------------------------------------------------------------------
+
+UpdateObjectFactory::UpdateObjectFactory(ApiProvider& rProvider,rtl::Reference<ObjectRegistry> pRegistry)
+: Factory(pRegistry)
+, m_rProvider(rProvider)
+{
+}
+//-----------------------------------------------------------------------------
+
+UpdateObjectFactory::~UpdateObjectFactory()
+{
+}
+//-----------------------------------------------------------------------------
+
+bool UpdateObjectFactory::implIsReadOnly(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode)
+{
+ OSL_ENSURE(!configuration::isEmpty(aTree.get()), "ERROR: trying to create an object without a tree");
+ OSL_ENSURE(aNode.isValid(), "ERROR: trying to create an object without a node");
+ OSL_ENSURE(aTree->isValidNode(aNode.getOffset()), "ERROR: node does not match tree , while trying to create an object");
+
+ return aTree->getAttributes(aNode).isReadonly();
+}
+//-----------------------------------------------------------------------------
+
+NodeElement* UpdateObjectFactory::doCreateGroupMember(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode, configuration::Template* pSetElementTemplate)
+{
+ OSL_ENSURE(!configuration::isEmpty(aTree.get()), "ERROR: trying to create a group member without a tree");
+ OSL_ENSURE(aNode.isValid(), "ERROR: trying to create a group member without a node");
+ OSL_ENSURE(aTree->isValidNode(aNode.getOffset()), "ERROR: node does not match tree , while trying to create a group");
+
+ NodeElement* pRootElement = makeElement(aTree,aTree->getRootNode());
+ OSL_ENSURE(pRootElement, "Could not create root element of tree - cannot create group member object");
+ if (!pRootElement)
+ return 0;
+
+ uno::Reference<uno::XInterface> aRootRelease(pRootElement->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE);
+ ApiTreeImpl& rRootContext = getImplementation(*pRootElement);
+
+ NodeElement * pResult = 0;
+
+ if (implIsReadOnly(aTree,aNode))
+ {
+ if (!pSetElementTemplate)
+ {
+ OInnerGroupInfo * pNewObject = new OInnerGroupInfo(rRootContext, aNode);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ OInnerSetInfo * pNewObject = new OInnerSetInfo(rRootContext, aNode);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ }
+ else
+ {
+ if (!pSetElementTemplate)
+ {
+ OInnerGroupUpdate * pNewObject = new OInnerGroupUpdate(rRootContext, aNode);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else if (pSetElementTemplate->isInstanceValue())
+ {
+ OInnerValueSetUpdate * pNewObject = new OInnerValueSetUpdate(rRootContext, aNode);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ OInnerTreeSetUpdate * pNewObject = new OInnerTreeSetUpdate(rRootContext, aNode);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ }
+
+ return pResult;
+}
+//-----------------------------------------------------------------------------
+
+TreeElement* UpdateObjectFactory::doCreateAccessRoot(rtl::Reference< configuration::Tree > const& aTree, configuration::Template* pSetElementTemplate, vos::ORef< OOptions >const& _xOptions)
+{
+ OSL_ENSURE(!configuration::isEmpty(aTree.get()), "ERROR: trying to create a root object without a tree");
+
+ TreeElement * pResult = 0;
+ if (implIsReadOnly(aTree,aTree->getRootNode()))
+ {
+ OSL_ENSURE(false, "WARNING: Trying to create an 'Update Access' on a read-only tree/node");
+ if (!pSetElementTemplate)
+ {
+ ORootElementGroupInfo * pNewObject = new ORootElementGroupInfo(m_rProvider, aTree, _xOptions);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ ORootElementSetInfo * pNewObject = new ORootElementSetInfo(m_rProvider, aTree, _xOptions);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ }
+ else
+ {
+ if (!pSetElementTemplate)
+ {
+ ORootElementGroupUpdate * pNewObject = new ORootElementGroupUpdate(m_rProvider, aTree, _xOptions);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else if (pSetElementTemplate->isInstanceValue())
+ {
+ ORootElementValueSetUpdate * pNewObject = new ORootElementValueSetUpdate(m_rProvider, aTree, _xOptions);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ ORootElementTreeSetUpdate * pNewObject = new ORootElementTreeSetUpdate(m_rProvider, aTree, _xOptions);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ }
+
+ return pResult;
+}
+
+//-----------------------------------------------------------------------------
+SetElement* UpdateObjectFactory::doCreateSetElement(rtl::Reference< configuration::ElementTree > const& aElementTree, configuration::Template* pSetElementTemplate)
+{
+ OSL_ENSURE(aElementTree.is(), "ERROR: trying to create a set element object without a tree");
+
+ rtl::Reference< configuration::Tree > aTree( aElementTree.get() );
+ OSL_ENSURE(!configuration::isEmpty(aTree.get()), "ERROR: trying to create a set element object without a tree");
+
+ ApiTreeImpl * pParentContext = 0;
+ uno::Reference<uno::XInterface> aParentRelease;
+
+ rtl::Reference< configuration::Tree > aParentTree = aTree->getContextTree();
+ if (!configuration::isEmpty(aParentTree.get()))
+ {
+ //configuration::NodeRef aParentNode = aTree.getContextNode();
+ configuration::NodeRef aParentRoot = aParentTree->getRootNode();
+ if (NodeElement* pParentRootElement = makeElement(aParentTree,aParentRoot) )
+ {
+ aParentRelease = uno::Reference<uno::XInterface>(pParentRootElement->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE);
+ pParentContext = &getImplementation(*pParentRootElement);
+ }
+ }
+
+ SetElement * pResult = 0;
+ if (implIsReadOnly(aTree,aTree->getRootNode()))
+ {
+ if (!pSetElementTemplate)
+ {
+ OSetElementGroupInfo * pNewObject = new OSetElementGroupInfo(aTree,m_rProvider,pParentContext);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ OSetElementSetInfo * pNewObject = new OSetElementSetInfo(aTree,m_rProvider,pParentContext);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ }
+ else
+ {
+ if (!pSetElementTemplate)
+ {
+ OSetElementGroupUpdate * pNewObject = new OSetElementGroupUpdate(aTree,m_rProvider,pParentContext);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else if (pSetElementTemplate->isInstanceValue())
+ {
+ OSetElementValueSetUpdate * pNewObject = new OSetElementValueSetUpdate(aTree,m_rProvider,pParentContext);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ else
+ {
+ OSetElementTreeSetUpdate * pNewObject = new OSetElementTreeSetUpdate(aTree,m_rProvider,pParentContext);
+ pNewObject->acquire();
+ pResult = &pNewObject->getElementClass();
+ }
+ }
+ return pResult;
+}
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/api2/apifactoryimpl.hxx b/configmgr/source/api2/apifactoryimpl.hxx
new file mode 100644
index 000000000000..50927893f50b
--- /dev/null
+++ b/configmgr/source/api2/apifactoryimpl.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apifactoryimpl.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_FACTORYIMPL_HXX_
+#define CONFIGMGR_API_FACTORYIMPL_HXX_
+
+#include "apifactory.hxx"
+
+namespace configmgr
+{
+ namespace configapi
+ {
+ class ApiProvider;
+ // used to create UNO objects
+ class ReadOnlyObjectFactory : public Factory
+ {
+ ApiProvider& m_rProvider;
+ public:
+ ReadOnlyObjectFactory(ApiProvider& rProvider,rtl::Reference<ObjectRegistry> pRegistry);
+ ~ReadOnlyObjectFactory();
+
+ virtual NodeElement* doCreateGroupMember(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode, configuration::Template* pSetElementTemplate);
+ virtual TreeElement* doCreateAccessRoot(rtl::Reference< configuration::Tree > const& aTree, configuration::Template* pSetElementTemplate, vos::ORef< OOptions >const& _xOptions);
+ virtual SetElement* doCreateSetElement(rtl::Reference< configuration::ElementTree > const& aTree, configuration::Template* pSetElementTemplate);
+ };
+ // used to create UNO objects
+ class UpdateObjectFactory : public Factory
+ {
+ ApiProvider& m_rProvider;
+ public:
+ UpdateObjectFactory(ApiProvider& rProvider,rtl::Reference<ObjectRegistry> pRegistry);
+ ~UpdateObjectFactory();
+
+ virtual NodeElement* doCreateGroupMember(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode, configuration::Template* pSetElementTemplate);
+ virtual TreeElement* doCreateAccessRoot(rtl::Reference< configuration::Tree > const& aTree, configuration::Template* pSetElementTemplate, vos::ORef< OOptions >const& _xOptions);
+ virtual SetElement* doCreateSetElement(rtl::Reference< configuration::ElementTree > const& aTree, configuration::Template* pSetElementTemplate);
+ private:
+ bool implIsReadOnly(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode);
+ };
+
+ }
+}
+
+#endif // CONFIGMGR_API_FACTORYIMPL_HXX_
diff --git a/configmgr/source/api2/apinodeaccess.cxx b/configmgr/source/api2/apinodeaccess.cxx
new file mode 100644
index 000000000000..da121c8137f6
--- /dev/null
+++ b/configmgr/source/api2/apinodeaccess.cxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apinodeaccess.cxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "apinodeaccess.hxx"
+
+#include "apitreeimplobj.hxx"
+#include "apifactory.hxx"
+
+#include "apitreeaccess.hxx"
+#include "noderef.hxx"
+
+#include "anynoderef.hxx"
+#include "valueref.hxx"
+
+#include "configset.hxx"
+#include "configpath.hxx"
+#include "confignotifier.hxx"
+
+namespace configmgr
+{
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+
+NodeAccess::~NodeAccess()
+{
+}
+//-----------------------------------------------------------------------------
+
+configuration::NodeRef NodeAccess::getNodeRef() const
+{
+ return doGetNode();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< configuration::Tree > NodeAccess::getTreeRef() const
+{
+ return getApiTree().getTree();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< configuration::Tree > NodeAccess::getTree() const
+{
+ return getApiTree().getTree();
+}
+//-----------------------------------------------------------------------------
+
+void NodeAccess::checkAlive() const
+{
+ getApiTree().checkAlive();
+}
+//-----------------------------------------------------------------------------
+
+void NodeAccess::disposeNode()
+{
+ getApiTree().disposeNode(getNodeRef(), getUnoInstance());
+}
+//-----------------------------------------------------------------------------
+
+
+Factory& NodeAccess::getFactory() const
+{
+ return getApiTree().getFactory();
+}
+//-----------------------------------------------------------------------------
+
+Notifier NodeAccess::getNotifier() const
+{
+ return getApiTree().getNotifier();
+}
+
+//-----------------------------------------------------------------------------
+
+uno::Any makeElement(configapi::Factory& rFactory, rtl::Reference< configuration::Tree > const& aTree, configuration::AnyNodeRef const& aNode)
+{
+ if (!configuration::isEmpty(aTree.get()) && aNode.isValid())
+ {
+ if (aNode.isNode())
+ {
+ configuration::NodeRef aInnerNode = aNode.toNode();
+
+ if (configuration::isStructuralNode(aTree,aInnerNode))
+ return uno::makeAny( rFactory.makeUnoElement(aTree,aInnerNode) );
+
+ else
+ return configuration::getSimpleElementValue(aTree,aInnerNode);
+ }
+ else
+ {
+ return configuration::getSimpleValue(aTree,aNode.toValue());
+ }
+ }
+
+ return uno::Any();
+}
+//-----------------------------------------------------------------------------
+
+uno::Any makeInnerElement(configapi::Factory& rFactory, rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode)
+{
+ if (!configuration::isEmpty(aTree.get()) && aNode.isValid())
+ {
+ OSL_ENSURE(configuration::isStructuralNode(aTree,aNode), "Trying to makeInnerElement for a simple value");
+
+ return uno::makeAny( rFactory.makeUnoElement(aTree,aNode) );
+ }
+
+ return uno::Any();
+}
+//-----------------------------------------------------------------------------
+
+uno::Any makeElement(configapi::Factory& rFactory, rtl::Reference< configuration::ElementTree > const& aTree)
+{
+ if (aTree.is())
+ {
+ return uno::makeAny( rFactory.makeUnoSetElement(aTree) );
+ }
+
+ return uno::Any();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< configuration::ElementTree > extractElementTree(configapi::Factory& rFactory, uno::Any const& aElement, rtl::Reference< configuration::Template > const& aTemplate )
+{
+ OSL_ENSURE(aTemplate.is(), "ERROR: Need a template to extract a matching set element");
+
+ if (SetElement* pSetElement = rFactory.extractSetElement(aElement))
+ {
+ rtl::Reference<configuration::Template> aFoundTemplate = pSetElement->getTemplateInfo();
+ if (aFoundTemplate.is())
+ {
+ if (aFoundTemplate != aTemplate)
+ throw configuration::TypeMismatch(aFoundTemplate->getPathString(), aTemplate->getPathString());
+
+ return pSetElement->getElementRef( );
+ }
+ }
+ return rtl::Reference< configuration::ElementTree >();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< configuration::Template > NodeSetInfoAccess::getElementInfo() const
+{
+ rtl::Reference<configuration::Template> aTemplate = getTree()->extractElementInfo(getNodeRef());
+
+ OSL_ENSURE(aTemplate.is(), "ERROR: Set must have an element template");
+
+ return aTemplate;
+}
+
+}
+}
diff --git a/configmgr/source/api2/apinodeaccess.hxx b/configmgr/source/api2/apinodeaccess.hxx
new file mode 100644
index 000000000000..c7684edc5400
--- /dev/null
+++ b/configmgr/source/api2/apinodeaccess.hxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apinodeaccess.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_NODEACCESS_HXX_
+#define CONFIGMGR_API_NODEACCESS_HXX_
+
+#include "sal/config.h"
+
+#include "boost/utility.hpp"
+
+#include "datalock.hxx"
+#include "utility.hxx"
+#include "noderef.hxx"
+
+namespace osl { class Mutex; }
+
+namespace configmgr
+{
+ namespace configuration
+ {
+ class AnyNodeRef;
+ class NodeRef;
+ class Tree;
+ }
+ namespace configapi
+ {
+ class Factory;
+ class Notifier;
+ class SetElement;
+
+ class ApiTreeImpl;
+
+ namespace uno = com::sun::star::uno;
+
+ // API object implementation wrappers
+ // these objects just provide the pieces needed to navigate and manipulate trees and nodes
+
+ // The common part of all nodes, provides all you need to read and listen
+ class NodeAccess : private boost::noncopyable
+ {
+ public:
+ virtual ~NodeAccess();
+
+ // model access
+ configuration::NodeRef getNodeRef() const;
+ rtl::Reference< configuration::Tree > getTreeRef() const;
+ rtl::Reference< configuration::Tree > getTree() const;
+
+ // self-locked methods for dispose handling
+ void checkAlive() const;
+ void disposeNode();
+
+ // api object handling
+ uno::XInterface* getUnoInstance() const
+ { return doGetUnoInstance(); }
+ Factory& getFactory() const;
+ Notifier getNotifier() const;
+
+ protected:
+ virtual configuration::NodeRef doGetNode() const = 0;
+ virtual uno::XInterface* doGetUnoInstance() const = 0;
+ virtual ApiTreeImpl& getApiTree() const = 0;
+ };
+
+ /** builds a Uno <type scope='com::sun::star::uno'>Any</type> representing node <var>aNode</var>.
+ <p> Uses the <type scope='configmgr::configapi'>Factory</type> provided
+ to create service implementations wrapping inner nodes</p>
+ <p> returns VOID if <var>aNode</var> is empty.</p>
+ */
+ uno::Any makeElement(configapi::Factory& rFactory, rtl::Reference< configuration::Tree > const& aTree, configuration::AnyNodeRef const& aNode);
+
+ /** builds a Uno <type scope='com::sun::star::uno'>Any</type> representing inner node <var>aNode</var>.
+ <p> Uses the <type scope='configmgr::configapi'>Factory</type> provided
+ to create service implementations wrapping inner nodes</p>
+ <p> returns VOID if <var>aNode</var> is empty.</p>
+ */
+ uno::Any makeInnerElement(configapi::Factory& rFactory, rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode);
+
+ /** builds a Uno <type scope='com::sun::star::uno'>Any</type> representing set element <var>aElement</var>.
+ <p> Uses the <type scope='configmgr::configapi'>Factory</type> provided
+ to create service implementations wrapping inner nodes</p>
+ <p> returns VOID if <var>aNode</var> is empty.</p>
+ */
+ uno::Any makeElement(configapi::Factory& rFactory, rtl::Reference< configuration::ElementTree > const& aTree);
+
+
+ // Info interfaces for Group Nodes
+ class NodeGroupInfoAccess : public NodeAccess
+ {
+ public:
+ // currently only used for tagging group nodes
+ };
+
+ // Info interfaces for Set Nodes
+ class NodeSetInfoAccess : public NodeAccess
+ {
+ friend class SetElement;
+ public:
+ rtl::Reference< configuration::Template > getElementInfo() const;
+ };
+
+ /** extracts a <type scope='configmgr::configuration'>ElementTree</type> from a <type scope='com::sun::star::uno'>Any</type>
+ which must contain an object which wraps an instance of the template available in <var>aTemplate</var>.
+ <p> Uses the <type scope='configmgr::configapi'>Factory</type> provided
+ to resolve inner nodes (which may suppose that the object was created using the same factory)</p>
+ <p> returns an empty tree if <var>aElement</var> is empty.</p>
+ <p> May throw exceptions if the type doesn't match the template.</p>
+ */
+ rtl::Reference< configuration::ElementTree > extractElementTree(Factory& rFactory, uno::Any const& aElement, rtl::Reference< configuration::Template > const& aTemplate );
+
+ /// wraps a NodeAccess; provides both object and provider (read) locks,
+ // ensures object was not disposed
+ template <class Access>
+ class GuardedNodeData
+ {
+ UnoApiLock m_aLock;
+ Access & m_rNode;
+ public:
+ GuardedNodeData(Access& rNode);
+ public:
+ Access& get() const { return m_rNode; }
+
+ rtl::Reference< configuration::Tree > getTree() const;
+ configuration::NodeRef getNode() const;
+ };
+
+ template <class Access>
+ GuardedNodeData<Access>::GuardedNodeData(Access& rNode)
+ : m_rNode(rNode)
+ {
+ rNode.checkAlive();
+ }
+
+ template <class Access>
+ rtl::Reference< configuration::Tree > GuardedNodeData<Access>::getTree() const
+ {
+ return m_rNode.getTree();
+ }
+
+ template <class Access>
+ configuration::NodeRef GuardedNodeData<Access>::getNode() const
+ {
+ return m_rNode.getNodeRef();
+ }
+ }
+}
+
+#endif // CONFIGMGR_API_NODEACCESS_HXX_
diff --git a/configmgr/source/api2/apinodeupdate.cxx b/configmgr/source/api2/apinodeupdate.cxx
new file mode 100644
index 000000000000..115ef3cefe5d
--- /dev/null
+++ b/configmgr/source/api2/apinodeupdate.cxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apinodeupdate.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "apinodeupdate.hxx"
+#include "apitreeimplobj.hxx"
+#include "apitreeaccess.hxx"
+#include "noderef.hxx"
+#include "configset.hxx"
+#include "configgroup.hxx"
+#include "configpath.hxx"
+#include "apifactory.hxx"
+
+namespace configmgr
+{
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+
+NodeGroupAccess& withDefaultData(NodeGroupAccess& _aGroup)
+{
+ configuration::GroupDefaulter::ensureDataAvailable(_aGroup.getTreeRef(),_aGroup.getNodeRef(),
+ _aGroup.getApiTree().getDefaultProvider());
+ return _aGroup;
+}
+//-----------------------------------------------------------------------------
+
+configuration::GroupUpdater NodeGroupAccess::getNodeUpdater()
+{
+ return configuration::GroupUpdater(getTree(),getNodeRef(), getApiTree().getProvider().getTypeConverter());
+}
+//-----------------------------------------------------------------------------
+
+configuration::GroupDefaulter NodeGroupAccess::getNodeDefaulter()
+{
+ return configuration::GroupDefaulter(getTree(),getNodeRef(), getApiTree().getDefaultProvider());
+}
+//-----------------------------------------------------------------------------
+
+configuration::SetElementFactory NodeTreeSetAccess::getElementFactory()
+{
+ configuration::TemplateProvider aProvider = configuration::SetElementFactory::findTemplateProvider(getTree(),getNodeRef());
+ return configuration::SetElementFactory(aProvider);
+}
+//-----------------------------------------------------------------------------
+
+configuration::SetDefaulter NodeSetAccess::getNodeDefaulter()
+{
+ return configuration::SetDefaulter(getTree(),getNodeRef(), getApiTree().getDefaultProvider());
+}
+//-----------------------------------------------------------------------------
+
+configuration::TreeSetUpdater NodeTreeSetAccess::getNodeUpdater()
+{
+ return configuration::TreeSetUpdater(getTree(),getNodeRef(),getElementInfo());
+}
+//-----------------------------------------------------------------------------
+
+
+configuration::ValueSetUpdater NodeValueSetAccess::getNodeUpdater()
+{
+ return configuration::ValueSetUpdater(getTree(),getNodeRef(),getElementInfo(), getApiTree().getProvider().getTypeConverter());
+}
+//-----------------------------------------------------------------------------
+
+void attachSetElement(NodeTreeSetAccess& aSet, SetElement& aElement)
+{
+ OSL_ENSURE( configuration::NodeID(aSet.getTreeRef(),aSet.getNodeRef()) ==
+ configuration::NodeID(rtl::Reference< configuration::Tree >(aElement.getTreeRef()->getContextTree()),aElement.getTreeRef()->getContextNodeRef()),
+ "ERROR: Attaching an unrelated SetElement to a SetInfoAccess");
+
+ aElement.haveNewParent(&aSet);
+}
+//-----------------------------------------------------------------------------
+
+bool attachSetElement(NodeTreeSetAccess& aSet, rtl::Reference< configuration::ElementTree > const& aElementTree)
+{
+ OSL_ENSURE( configuration::NodeID(aSet.getTreeRef(),aSet.getNodeRef()) ==
+ configuration::NodeID(rtl::Reference< configuration::Tree >(aElementTree->getContextTree()), aElementTree->getContextNodeRef()),
+ "ERROR: Attaching an unrelated ElementTree to a SetInfoAccess");
+
+ Factory& rFactory = aSet.getFactory();
+ if (SetElement* pSetElement = rFactory.findSetElement(aElementTree))
+ {
+ // the factory always does an extra acquire
+ uno::Reference<uno::XInterface> xReleaseSetElement(pSetElement->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE);
+
+ attachSetElement(aSet, *pSetElement);
+ return true;
+ }
+ else
+ return false;
+
+}
+//-----------------------------------------------------------------------------
+
+void detachSetElement(SetElement& aElement)
+{
+ OSL_ENSURE( configuration::isEmpty(aElement.getTreeRef()->getContextTree()),
+ "ERROR: Detaching a SetElement that has a parent");
+
+ aElement.haveNewParent(0);
+}
+//-----------------------------------------------------------------------------
+
+bool detachSetElement(Factory& rFactory, rtl::Reference< configuration::ElementTree > const& aElementTree)
+{
+ OSL_ENSURE( configuration::isEmpty(aElementTree->getContextTree()),
+ "ERROR: Detaching an ElementTree that has a parent");
+
+ if (SetElement* pSetElement = rFactory.findSetElement(aElementTree))
+ {
+ // the factory always does an extra acquire
+ uno::Reference<uno::XInterface> xReleaseSetElement(pSetElement->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE);
+
+ detachSetElement(*pSetElement);
+ return true;
+ }
+ else
+ return false;
+
+}
+//-----------------------------------------------------------------------------
+
+UpdateGuardImpl::UpdateGuardImpl(NodeGroupAccess& rNode)
+: m_rNode(rNode)
+{
+ rNode.checkAlive();
+}
+//-----------------------------------------------------------------------------
+
+UpdateGuardImpl::UpdateGuardImpl(NodeSetAccess& rNode)
+: m_rNode(rNode)
+{
+}
+//-----------------------------------------------------------------------------
+
+UpdateGuardImpl::~UpdateGuardImpl() throw ()
+{
+}
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/api2/apinodeupdate.hxx b/configmgr/source/api2/apinodeupdate.hxx
new file mode 100644
index 000000000000..f200a6f7df2c
--- /dev/null
+++ b/configmgr/source/api2/apinodeupdate.hxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apinodeupdate.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_NODEUPDATE_HXX_
+#define CONFIGMGR_API_NODEUPDATE_HXX_
+
+#include "sal/config.h"
+
+#include "boost/utility.hpp"
+
+#include "apinodeaccess.hxx"
+#include "utility.hxx"
+
+namespace configmgr
+{
+ namespace configuration
+ {
+ class GroupUpdater;
+ class GroupDefaulter;
+ class TreeSetUpdater;
+ class ValueSetUpdater;
+ class SetDefaulter;
+ class SetElementFactory;
+
+ class NodeUpdate;
+ }
+ namespace configapi
+ {
+ class SetElement;
+
+ // API object implementation wrappers
+ // these objects just provide the pieces needed to navigate and manipulate trees and nodes
+
+ // Updating access for Group Nodes
+ class NodeGroupAccess : public NodeGroupInfoAccess
+ {
+ public:
+ typedef configuration::GroupUpdater NodeUpdater;
+ typedef configuration::GroupDefaulter NodeDefaulter;
+ NodeUpdater getNodeUpdater();
+ NodeDefaulter getNodeDefaulter();
+
+ /** ensures that the default data for a group is loaded (if possible)
+ <p>Must be called outside of any locks !</p>
+ */
+ friend NodeGroupAccess& withDefaultData(NodeGroupAccess& aGroup);
+ };
+
+ // Updating access for Set Nodes
+ class NodeSetAccess : public NodeSetInfoAccess
+ {
+ public:
+ typedef struct SetUpdater_PlaceHolder NodeUpdater;
+ typedef configuration::SetDefaulter NodeDefaulter;
+ NodeDefaulter getNodeDefaulter();
+ };
+
+ // Updating access for Set Nodes containing whole trees
+ class NodeTreeSetAccess : public NodeSetAccess
+ {
+ public:
+ typedef configuration::TreeSetUpdater NodeUpdater;
+ NodeUpdater getNodeUpdater();
+
+ configuration::SetElementFactory getElementFactory();
+ };
+
+ // Updating access for Set Nodes containing simple values
+ class NodeValueSetAccess : public NodeSetAccess
+ {
+ public:
+ typedef configuration::ValueSetUpdater NodeUpdater;
+ NodeUpdater getNodeUpdater();
+ };
+
+ /// informs a <type>SetElement</type> that it should now link to the given SetElement
+ void attachSetElement(NodeTreeSetAccess& aSet, SetElement& aElement);
+
+ /// informs a <type>SetElement</type> that it should now link to the given SetElement
+ bool attachSetElement(NodeTreeSetAccess& aSet, rtl::Reference< configuration::ElementTree > const& aElementTree);
+
+ /// informs a <type>SetElement</type> that it should now unlink from its owning SetElement
+ void detachSetElement(SetElement& aElement);
+
+ /// informs a <type>SetElement</type> that it should now unlink from its owning SetElement
+ bool detachSetElement(Factory& rFactory, rtl::Reference< configuration::ElementTree > const& aElementTree);
+
+ /// Guarding and locking implementations
+ /// guards a NodeGroupAccess, or NodeSetAccess; provides an object (write)/provider(read) lock; ensures object was not disposed
+ class UpdateGuardImpl : private boost::noncopyable
+ {
+ NodeAccess& m_rNode;
+ public:
+ UpdateGuardImpl(NodeGroupAccess& rNode);
+ UpdateGuardImpl(NodeSetAccess& rNode);
+ ~UpdateGuardImpl() throw ();
+ public:
+ NodeAccess& get() const { return m_rNode; }
+
+ void downgrade() { }
+ };
+
+ // Thin Wrappers around NodeAccesses: Provide guarding and convenient access
+ /// wraps a NodeAccess; provides an object (write)/provider(read) lock, ensures object was not disposed
+ template <class Access>
+ class GuardedNodeUpdate
+ {
+ UnoApiLock m_aLock;
+ UpdateGuardImpl m_aImpl;
+ public:
+ GuardedNodeUpdate(Access& rNode) : m_aImpl(rNode) {}
+ public:
+ Access& get() const { return static_cast<Access&>(m_aImpl.get()); }
+
+ rtl::Reference< configuration::Tree > getTree() const;
+ configuration::NodeRef getNode() const;
+
+ typename Access::NodeUpdater getNodeUpdater() const;
+ typename Access::NodeDefaulter getNodeDefaulter() const;
+
+ void clearForBroadcast() { m_aImpl.downgrade(); }
+ };
+
+ template <class Access>
+ rtl::Reference< configuration::Tree > GuardedNodeUpdate<Access>::getTree() const
+ {
+ return get().getTree();
+ }
+
+ template <class Access>
+ configuration::NodeRef GuardedNodeUpdate<Access>::getNode() const
+ {
+ return get().getNodeRef();
+ }
+
+ template <class Access>
+ typename Access::NodeUpdater GuardedNodeUpdate<Access>::getNodeUpdater() const
+ {
+ return get().getNodeUpdater();
+ }
+
+ template <class Access>
+ typename Access::NodeDefaulter GuardedNodeUpdate<Access>::getNodeDefaulter() const
+ {
+ return get().getNodeDefaulter();
+ }
+ }
+}
+
+#endif // CONFIGMGR_API_NODEUPDATE_HXX_
diff --git a/configmgr/source/api2/apinotifierimpl.cxx b/configmgr/source/api2/apinotifierimpl.cxx
new file mode 100644
index 000000000000..35b74533cfa6
--- /dev/null
+++ b/configmgr/source/api2/apinotifierimpl.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apinotifierimpl.cxx,v $
+ * $Revision: 1.8.20.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "apinotifierimpl.hxx"
+#include "apinodeaccess.hxx"
+#include "noderef.hxx"
+#include "valueref.hxx"
+#include "confignotifier.hxx"
+#include "configexcept.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------------
+ namespace lang = css::lang;
+ namespace util = css::util;
+ namespace beans = css::beans;
+
+// Generic Notifier Support Implementations
+//-----------------------------------------------------------------------------------
+
+/// add a Listener to the notifier of a NodeAccess
+template <class Listener>
+inline
+void genericAddListener(NodeAccess& rNode, const uno::Reference< Listener >& xListener )
+{
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+ aGuardedNotifier->add(rNode.getNodeRef(), xListener);
+}
+
+/// remove a Listener from the notifier of a NodeAccess
+template <class Listener>
+inline
+void genericRemoveListener(NodeAccess& rNode, const uno::Reference< Listener >& xListener )
+{
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+ aGuardedNotifier->remove(rNode.getNodeRef(), xListener);
+}
+
+
+/** add a Listener for all or some children of a NodeAccess to its notifier
+ <p> If the name given is empty, the listener will be added to all children of the node</p>
+ @returns
+ <TRUE/> if the node was found, or the name was empty
+ <FALSE/> if the named node wasn't found
+*/
+template <class Listener>
+inline
+bool genericAddChildListener(NodeGroupInfoAccess& rNode, const uno::Reference< Listener >& xListener, const rtl::OUString& sName )
+{
+ if (sName.getLength() != 0)
+ {
+ GuardedNodeData<NodeAccess> aGuardedNode( rNode ); // guard access to children
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+
+ rtl::Reference< configuration::Tree > aTree( aGuardedNode.getTree() );
+ configuration::NodeRef aNode( aGuardedNode.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildName(sName,aTree,aNode);
+
+ if (!aTree->hasChild(aNode,aChildName)) return false;
+
+ aGuardedNotifier->addForOne(aNode, xListener, aChildName);
+ }
+ else
+ {
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+
+ aGuardedNotifier->addForAll(rNode.getNodeRef(), xListener);
+
+ // always ok, as we addreess no specific NodeRef
+ }
+ return true;
+}
+
+/** remove a Listener from all or some children of a NodeAccess to its notifier
+ <p> If the name given is empty, the listener will be removed from any children of the node</p>
+ @returns
+ <TRUE/> if the node was found, or the name was empty
+ <FALSE/> if the named node wasn't found
+*/
+template <class Listener>
+inline
+bool genericRemoveChildListener(NodeGroupInfoAccess& rNode, const uno::Reference< Listener >& xListener, const rtl::OUString& sName )
+{
+ if (sName.getLength() != 0)
+ {
+ GuardedNodeData<NodeAccess> aGuardedNode( rNode ); // guard access to children
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+
+ rtl::Reference< configuration::Tree > aTree( aGuardedNode.getTree() );
+ configuration::NodeRef aNode( aGuardedNode.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildName(sName,aTree,aNode);
+
+ if (!aTree->hasChild(aNode,aChildName)) return false;
+
+ aGuardedNotifier->removeForOne(aNode, xListener, aChildName);
+ }
+ else
+ {
+ GuardedNotifier aGuardedNotifier( rNode ); // guard the notifier
+
+ aGuardedNotifier->removeForAll(rNode.getNodeRef(), xListener);
+
+ // always ok, as we addreess no specific NodeRef
+ }
+ return true;
+}
+
+
+
+// XComponent
+//-----------------------------------------------------------------------------------
+void implAddListener(NodeAccess& rNode, const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ genericAddListener(rNode,xListener);
+}
+
+void implRemoveListener(NodeAccess& rNode, const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ genericRemoveListener(rNode,xListener);
+}
+
+// XContainer
+//-----------------------------------------------------------------------------------
+void implAddListener(NodeAccess& rNode, const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ genericAddListener(rNode,xListener);
+}
+
+void implRemoveListener(NodeAccess& rNode, const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ genericRemoveListener(rNode,xListener);
+}
+
+// XChangesNotifier
+//-----------------------------------------------------------------------------------
+
+void implAddListener(NodeAccess& rNode, const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ genericAddListener(rNode,xListener);
+}
+
+void implRemoveListener(NodeAccess& rNode, const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ genericRemoveListener(rNode,xListener);
+}
+
+// XMultiPropertySet
+//-----------------------------------------------------------------------------------
+
+void implAddListener( NodeAccess& rNode, const uno::Reference< beans::XPropertiesChangeListener >& xListener, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException)
+{
+
+ GuardedNotifier impl( rNode );
+
+ // TODO: is an exception for unknown names allowed/needed ?
+ impl->add(rNode.getNodeRef(), xListener, aPropertyNames);
+}
+
+
+void implRemoveListener( NodeAccess& rNode, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ genericRemoveListener(rNode,xListener);
+}
+
+// XPropertySet (manages listeners associated with named child node)
+//-----------------------------------------------------------------------------------
+
+// XPropertySet - VetoableChangeListeners
+//-----------------------------------------------------------------------------------
+
+void implAddListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XVetoableChangeListener >& xListener, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ if (!genericAddChildListener(rNode,xListener,sPropertyName))
+ {
+ throw css::beans::UnknownPropertyException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found !")),
+ rNode.getUnoInstance() );
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ throw css::beans::UnknownPropertyException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found:")) += ex.message(),
+ rNode.getUnoInstance() );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+}
+
+
+void implRemoveListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XVetoableChangeListener >& xListener, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ if (!genericRemoveChildListener(rNode,xListener,sPropertyName))
+ {
+ throw css::beans::UnknownPropertyException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found !")),
+ rNode.getUnoInstance() );
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ throw css::beans::UnknownPropertyException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found:")) += ex.message(),
+ rNode.getUnoInstance() );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+// XPropertySet - PropertyChangeListeners
+//-----------------------------------------------------------------------------------
+
+void implAddListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XPropertyChangeListener >& xListener, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ if (!genericAddChildListener(rNode,xListener,sPropertyName))
+ {
+ throw css::beans::UnknownPropertyException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found !")),
+ rNode.getUnoInstance() );
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ throw css::beans::UnknownPropertyException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot add listener - node not found:")) += ex.message(),
+ rNode.getUnoInstance() );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+void implRemoveListener( NodeGroupInfoAccess& rNode, const uno::Reference< beans::XPropertyChangeListener >& xListener, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ if (!genericRemoveChildListener(rNode,xListener,sPropertyName))
+ {
+ throw css::beans::UnknownPropertyException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found !")),
+ rNode.getUnoInstance() );
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ throw css::beans::UnknownPropertyException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: cannot remove listener - node not found:")) += ex.message(),
+ rNode.getUnoInstance() );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+//-----------------------------------------------------------------------------------
+ } // namespace configapi
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/apinotifierimpl.hxx b/configmgr/source/api2/apinotifierimpl.hxx
new file mode 100644
index 000000000000..4a78410d0d83
--- /dev/null
+++ b/configmgr/source/api2/apinotifierimpl.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apinotifierimpl.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_NOTIFIERIMPL_HXX_
+#define CONFIGMGR_API_NOTIFIERIMPL_HXX_
+
+#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
+#include <com/sun/star/container/XChild.hpp>
+#endif
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+
+ /* implementations of the event notification interfaces
+ supported by a node within the configuration tree.
+ */
+ namespace configapi
+ {
+ class NodeAccess;
+ class NodeSetInfoAccess;
+ class NodeGroupInfoAccess;
+
+ // Notification support
+
+ // XComponent
+ void implAddListener(NodeAccess& rNode, const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException);
+
+ void implRemoveListener(NodeAccess& rNode, const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException);
+
+ // XContainer
+ void implAddListener(NodeAccess& rNode, const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException);
+
+ void implRemoveListener(NodeAccess& rNode, const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException);
+
+ // XChangesNotifier
+ void implAddListener(NodeAccess& rNode, const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException);
+
+ void implRemoveListener(NodeAccess& rNode, const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException);
+
+ // XPropertySet - VetoableChangeListeners
+ void implAddListener( NodeGroupInfoAccess& rNode, const uno::Reference< css::beans::XVetoableChangeListener >& xListener, const rtl::OUString& sPropertyName )
+ throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ void implRemoveListener( NodeGroupInfoAccess& rNode, const uno::Reference< css::beans::XVetoableChangeListener >& xListener, const rtl::OUString& sPropertyName )
+ throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XPropertySet
+ void implAddListener( NodeGroupInfoAccess& rNode, const uno::Reference< css::beans::XPropertyChangeListener >& xListener, const rtl::OUString& sPropertyName )
+ throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ void implRemoveListener( NodeGroupInfoAccess& rNode, const uno::Reference< css::beans::XPropertyChangeListener >& xListener, const rtl::OUString& sPropertyName )
+ throw(css::beans::UnknownPropertyException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiPropertySet
+ void implAddListener( NodeAccess& rNode, const uno::Reference< css::beans::XPropertiesChangeListener >& xListener, const uno::Sequence< rtl::OUString >& sPropertyNames )
+ throw(uno::RuntimeException);
+
+ void implRemoveListener( NodeAccess& rNode, const uno::Reference< css::beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException);
+
+ }
+
+}
+#endif // CONFIGMGR_API_NOTIFIERIMPL_HXX_
+
+
diff --git a/configmgr/source/api2/apiserviceinfo.cxx b/configmgr/source/api2/apiserviceinfo.cxx
new file mode 100644
index 000000000000..181f57a2e0ab
--- /dev/null
+++ b/configmgr/source/api2/apiserviceinfo.cxx
@@ -0,0 +1,340 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apiserviceinfo.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "apiserviceinfo.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//========================================================================
+//= service names
+//========================================================================
+
+//========================================================================
+//= service infos
+//========================================================================
+
+//-- ACCESS (CONTAINER) ROLES -----------------------------
+
+#define CFG_SVCLIST_SETACCESS \
+ "com.sun.star.configuration.ConfigurationAccess", \
+ "com.sun.star.configuration.SetAccess", \
+ "com.sun.star.configuration.HierarchyAccess", \
+ "com.sun.star.configuration.SimpleSetAccess"
+
+#define CFG_SVCLIST_GROUPACCESS \
+ "com.sun.star.configuration.ConfigurationAccess", \
+ "com.sun.star.configuration.GroupAccess", \
+ "com.sun.star.configuration.HierarchyAccess", \
+ "com.sun.star.configuration.PropertyHierarchy"
+
+#define CFG_SVCLIST_SETUPDATE \
+ "com.sun.star.configuration.ConfigurationUpdateAccess", \
+ "com.sun.star.configuration.SetUpdate", \
+ "com.sun.star.configuration.SimpleSetUpdate", \
+ "com.sun.star.configuration.ConfigurationContainer", /* Obsolete */ \
+ CFG_SVCLIST_SETACCESS
+
+#define CFG_SVCLIST_GROUPUPDATE \
+ "com.sun.star.configuration.ConfigurationUpdateAccess", \
+ "com.sun.star.configuration.GroupUpdate", \
+ CFG_SVCLIST_GROUPACCESS
+
+//-- ELEMENT ROLES ----------------------------------------
+
+#define CFG_SVCLIST_SETELEMENT \
+ "com.sun.star.configuration.SetElement", \
+ "com.sun.star.configuration.HierarchyElement"
+
+#define CFG_SVCLIST_GROUPELEMENT \
+ "com.sun.star.configuration.GroupElement", \
+ "com.sun.star.configuration.HierarchyElement"
+
+#define CFG_SVCLIST_ACCESSROOTELEMENT \
+ "com.sun.star.configuration.AccessRootElement", \
+ "com.sun.star.configuration.HierarchyElement"
+
+#define CFG_SVCLIST_UPDATEROOTELEMENT \
+ "com.sun.star.configuration.UpdateRootElement", \
+ CFG_SVCLIST_ACCESSROOTELEMENT
+
+//-----------------------------------------------------------------------------
+
+sal_Char const * const c_aNoServices[] =
+{
+ NULL
+};
+
+//-----------------------------------------------------------------------------
+
+sal_Char const * const c_aCreateAccessServiceNames[] =
+{
+ "com.sun.star.configuration.ConfigurationAccess",
+ "com.sun.star.configuration.HierarchyAccess",
+ "com.sun.star.configuration.HierarchyElement",
+ NULL
+};
+
+sal_Char const * const c_aCreateUpdateServiceNames[] =
+{
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ "com.sun.star.configuration.ConfigurationAccess",
+ "com.sun.star.configuration.HierarchyAccess",
+ "com.sun.star.configuration.HierarchyElement",
+ NULL
+};
+
+//-----------------------------------------------------------------------------
+
+sal_Char const * const c_aUserAdministrationServices[] =
+{
+ "com.sun.star.configuration.UserAdministration",
+ "com.sun.star.configuration.SimpleSetUpdate",
+ "com.sun.star.configuration.SimpleSetAccess",
+ "com.sun.star.configuration.ConfigurationContainer", // Obsolete
+ NULL
+};
+
+sal_Char const * const c_aGroupAdministrationServices[] =
+{
+ "com.sun.star.configuration.GroupAdministration",
+ "com.sun.star.configuration.SimpleSetUpdate",
+ "com.sun.star.configuration.SimpleSetAccess",
+ "com.sun.star.configuration.ConfigurationContainer", // Obsolete
+ NULL
+};
+
+//-- ROLE COMBINATIONS ------------------
+
+//-- GroupElements
+
+sal_Char const * const c_aInnerGroupAccessServices[] =
+{
+ CFG_SVCLIST_GROUPACCESS,
+ CFG_SVCLIST_GROUPELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aInnerGroupUpdateServices[] =
+{
+ CFG_SVCLIST_GROUPUPDATE,
+ CFG_SVCLIST_GROUPELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aInnerSetAccessServices[] =
+{
+ CFG_SVCLIST_SETACCESS,
+ CFG_SVCLIST_GROUPELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aInnerSetUpdateServices[] =
+{
+ CFG_SVCLIST_SETUPDATE,
+ CFG_SVCLIST_GROUPELEMENT,
+ NULL
+};
+
+//-- SetElements
+
+sal_Char const * const c_aSetElementGroupAccessServices[] =
+{
+ CFG_SVCLIST_GROUPACCESS,
+ CFG_SVCLIST_SETELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aSetElementGroupUpdateServices[] =
+{
+ CFG_SVCLIST_GROUPUPDATE,
+ CFG_SVCLIST_SETELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aSetElementSetAccessServices[] =
+{
+ CFG_SVCLIST_SETACCESS,
+ CFG_SVCLIST_SETELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aSetElementSetUpdateServices[] =
+{
+ CFG_SVCLIST_SETUPDATE,
+ CFG_SVCLIST_SETELEMENT,
+ NULL
+};
+
+//-- RootElements
+
+sal_Char const * const c_aRootGroupAccessServices[] =
+{
+ CFG_SVCLIST_GROUPACCESS,
+ CFG_SVCLIST_ACCESSROOTELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aRootGroupUpdateServices[] =
+{
+ CFG_SVCLIST_GROUPUPDATE,
+ CFG_SVCLIST_UPDATEROOTELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aRootSetAccessServices[] =
+{
+ CFG_SVCLIST_SETACCESS,
+ CFG_SVCLIST_ACCESSROOTELEMENT,
+ NULL
+};
+
+sal_Char const * const c_aRootSetUpdateServices[] =
+{
+ CFG_SVCLIST_SETUPDATE,
+ CFG_SVCLIST_UPDATEROOTELEMENT,
+ NULL
+};
+//-----------------------------------------------------------------------------
+
+ServiceImplementationInfo const aInnerGroupInfoSI =
+{
+ "com.sun.star.comp.configuration.OInnerGroupInfoAccess",
+ c_aInnerGroupAccessServices,
+ NULL
+};
+ServiceImplementationInfo const aInnerGroupUpdateSI =
+{
+ "com.sun.star.comp.configuration.OInnerGroupUpdateAccess",
+ c_aInnerGroupUpdateServices,
+ NULL
+};
+ServiceImplementationInfo const aInnerSetInfoSI =
+{
+ "com.sun.star.comp.configuration.OInnerSetInfoAccess",
+ c_aInnerSetAccessServices,
+ NULL
+};
+ServiceImplementationInfo const aInnerTreeSetSI =
+{
+ "com.sun.star.comp.configuration.OInnerTreeSetUpdateAccess",
+ c_aInnerSetUpdateServices,
+ NULL
+};
+ServiceImplementationInfo const aInnerValueSetSI =
+{
+ "com.sun.star.comp.configuration.OInnerValueSetUpdateAccess",
+ c_aInnerSetUpdateServices,
+ NULL
+};
+//-----------------------------------------------------------------------------
+
+ServiceImplementationInfo const aSetElementGroupInfoSI =
+{
+ "com.sun.star.comp.configuration.OSetElementGroupInfoAccess",
+ c_aSetElementGroupUpdateServices,
+ NULL
+};
+ServiceImplementationInfo const aSetElementGroupUpdateSI =
+{
+ "com.sun.star.comp.configuration.OSetElementGroupUpdateAccess",
+ c_aSetElementGroupUpdateServices,
+ NULL
+};
+ServiceImplementationInfo const aSetElementSetInfoSI =
+{
+ "com.sun.star.comp.configuration.OSetElementSetInfoAccess",
+ c_aSetElementSetAccessServices,
+ NULL
+};
+ServiceImplementationInfo const aSetElementTreeSetSI =
+{
+ "com.sun.star.comp.configuration.OSetElementTreeSetUpdateAccess",
+ c_aSetElementSetUpdateServices,
+ NULL
+};
+ServiceImplementationInfo const aSetElementValueSetSI =
+{
+ "com.sun.star.comp.configuration.OSetElementValueSetUpdateAccess",
+ c_aSetElementSetUpdateServices,
+ NULL
+};
+//-----------------------------------------------------------------------------
+
+ServiceImplementationInfo const aRootElementGroupInfoSI =
+{
+ "com.sun.star.comp.configuration.ORootElementGroupInfoAccess",
+ c_aRootGroupAccessServices,
+ NULL
+};
+ServiceImplementationInfo const aRootElementGroupUpdateSI =
+{
+ "com.sun.star.comp.configuration.ORootElementGroupUpdateAccess",
+ c_aRootGroupUpdateServices,
+ NULL
+};
+ServiceImplementationInfo const aRootElementSetInfoSI =
+{
+ "com.sun.star.comp.configuration.ORootElementSetInfoAccess",
+ c_aRootSetAccessServices,
+ NULL
+};
+ServiceImplementationInfo const aRootElementTreeSetUpdateSI =
+{
+ "com.sun.star.comp.configuration.ORootElementTreeSetUpdateAccess",
+ c_aRootSetUpdateServices,
+ NULL
+};
+ServiceImplementationInfo const aRootElementValueSetUpdateSI =
+{
+ "com.sun.star.comp.configuration.ORootElementValueSetUpdateAccess",
+ c_aRootSetUpdateServices,
+ NULL
+};
+//-----------------------------------------------------------------------------
+
+ServiceRegistrationInfo const aCreateReadAccessSI =
+{
+ NULL, //"com.sun.star.comp.configuration.ORootElementReadAccess",
+ c_aCreateAccessServiceNames
+};
+ServiceRegistrationInfo const aCreateUpdateAccessSI =
+{
+ NULL, //"com.sun.star.comp.configuration.ORootElementUpdateAccess",
+ c_aCreateUpdateServiceNames
+};
+//-----------------------------------------------------------------------------
+
+ }
+}
diff --git a/configmgr/source/api2/apiserviceinfo.hxx b/configmgr/source/api2/apiserviceinfo.hxx
new file mode 100644
index 000000000000..6e982db381f8
--- /dev/null
+++ b/configmgr/source/api2/apiserviceinfo.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apiserviceinfo.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_SERVICEINFO_HXX_
+#define CONFIGMGR_API_SERVICEINFO_HXX_
+
+#include "serviceinfohelper.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+
+ extern sal_Char const * const c_aUserAdministrationServices[];
+ extern sal_Char const * const c_aGroupAdministrationServices[];
+
+//-----------------------------------------------------------------------------
+ extern ServiceImplementationInfo const aInnerGroupInfoSI;
+ extern ServiceImplementationInfo const aInnerGroupUpdateSI;
+ extern ServiceImplementationInfo const aInnerSetInfoSI;
+ extern ServiceImplementationInfo const aInnerTreeSetSI;
+ extern ServiceImplementationInfo const aInnerValueSetSI;
+ extern ServiceImplementationInfo const aSetElementGroupInfoSI;
+ extern ServiceImplementationInfo const aSetElementGroupUpdateSI;
+ extern ServiceImplementationInfo const aSetElementSetInfoSI;
+ extern ServiceImplementationInfo const aSetElementTreeSetSI;
+ extern ServiceImplementationInfo const aSetElementValueSetSI;
+ extern ServiceImplementationInfo const aRootElementGroupInfoSI;
+ extern ServiceImplementationInfo const aRootElementGroupUpdateSI;
+ extern ServiceImplementationInfo const aRootElementSetInfoSI;
+ extern ServiceImplementationInfo const aRootElementTreeSetUpdateSI;
+ extern ServiceImplementationInfo const aRootElementValueSetUpdateSI;
+
+//-----------------------------------------------------------------------------
+ extern ServiceRegistrationInfo const aCreateReadAccessSI;
+ extern ServiceRegistrationInfo const aCreateUpdateAccessSI;
+
+//-----------------------------------------------------------------------------
+ }
+}
+//-----------------------------------------------------------------------------
+
+#endif // CONFIGMGR_API_SERVICEINFO_HXX_
diff --git a/configmgr/source/api2/apitreeaccess.cxx b/configmgr/source/api2/apitreeaccess.cxx
new file mode 100644
index 000000000000..1415871b94d2
--- /dev/null
+++ b/configmgr/source/api2/apitreeaccess.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apitreeaccess.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "apitreeaccess.hxx"
+
+#include "apitreeimplobj.hxx"
+#include "configset.hxx"
+#include "confignotifier.hxx"
+#include "committer.hxx"
+#include "apinodeaccess.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+
+ // self-locked methods for dispose handling
+void NodeElement::checkAlive() const
+{
+ getApiTree().checkAlive();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< configuration::Tree > TreeElement::getTree() const
+{
+ return getTreeRef();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< configuration::Tree > TreeElement::getTreeRef() const
+{
+ return getApiTree().getTree();
+}
+//-----------------------------------------------------------------------------
+ // self-locked methods for dispose handling
+bool SetElement::disposeTree(bool bForce)
+{
+ return getApiTree().disposeTree(bForce);
+}
+//-----------------------------------------------------------------------------
+Factory& TreeElement::getFactory()
+{
+ return getApiTree().getFactory();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< configuration::ElementTree > SetElement::getElementRef() const
+{
+ return dynamic_cast< configuration::ElementTree * >(getTreeRef().get());
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< configuration::Template > SetElement::getTemplateInfo() const
+{
+ rtl::Reference< configuration::ElementTree > aTree(dynamic_cast< configuration::ElementTree * >(getTreeRef().get()));
+ OSL_ENSURE(aTree.is(), "This really must be a set element");
+ return aTree->getTemplate();
+}
+//-----------------------------------------------------------------------------
+
+void SetElement::haveNewParent(NodeSetInfoAccess* pNewParent)
+{
+ ApiTreeImpl* pNewParentImpl = pNewParent ? &pNewParent->getApiTree() : 0;
+
+ this->getApiTree().haveNewParent( pNewParentImpl );
+}
+//-----------------------------------------------------------------------------
+
+bool RootElement::disposeTree()
+{
+ return getRootTree().disposeTree();
+}
+//-----------------------------------------------------------------------------
+
+Committer UpdateRootElement::getCommitter()
+{
+ return Committer(getRootTree());
+}
+ }
+}
+
diff --git a/configmgr/source/api2/apitreeaccess.hxx b/configmgr/source/api2/apitreeaccess.hxx
new file mode 100644
index 000000000000..28e0de61b6c9
--- /dev/null
+++ b/configmgr/source/api2/apitreeaccess.hxx
@@ -0,0 +1,179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apitreeaccess.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_TREEACCESS_HXX_
+#define CONFIGMGR_API_TREEACCESS_HXX_
+
+#include "sal/config.h"
+
+#include "boost/utility.hpp"
+#include "rtl/ref.hxx"
+
+#include "datalock.hxx"
+#include "options.hxx"
+#include "utility.hxx"
+
+namespace osl { class Mutex; }
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ struct ServiceImplementationInfo;
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+ class ElementTree;
+ class Template;
+ class Tree;
+ }
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+ namespace uno = com::sun::star::uno;
+//-----------------------------------------------------------------------------
+ class Factory;
+ class Notifier;
+ class Committer;
+ class NodeSetInfoAccess;
+//-----------------------------------------------------------------------------
+ // API object implementation wrappers
+ //-------------------------------------------------------------------------
+ class ApiTreeImpl;
+ class ApiRootTreeImpl;
+
+ // these objects just provide the pieces needed to navigate and manipulate trees and nodes
+
+ // A common base class for 'element' classes
+ class NodeElement: private boost::noncopyable
+ {
+ public:
+ virtual ~NodeElement() {}
+
+ // self-locked methods for dispose handling
+ void checkAlive() const;
+
+ // api object handling
+ uno::XInterface* getUnoInstance() const
+ { return doGetUnoInstance(); }
+
+ ServiceImplementationInfo const * getServiceInfo() const
+ { return doGetServiceInfo(); }
+ private:
+ virtual uno::XInterface* doGetUnoInstance() const = 0;
+ virtual ServiceImplementationInfo const* doGetServiceInfo() const = 0;
+ virtual ApiTreeImpl& getApiTree() const = 0;
+
+ friend class Factory;
+ };
+//-----------------------------------------------------------------------------
+
+ // A class for tagging inner nodes
+ class InnerElement : public NodeElement
+ {
+ public:
+ // Only used as a tag
+ };
+//-----------------------------------------------------------------------------
+
+ // A common base class for tree-owning elemnt classes
+ class TreeElement : public NodeElement
+ {
+ public:
+ // model access
+ rtl::Reference< configuration::Tree > getTreeRef() const;
+ rtl::Reference< configuration::Tree > getTree() const;
+
+ // api object handling
+ Factory& getFactory();
+
+ protected:
+ virtual ApiTreeImpl& getApiTree() const = 0;
+ };
+//-----------------------------------------------------------------------------
+
+ // Info interfaces for Set Elements
+ class SetElement : public TreeElement
+ {
+ public:
+ // self-locked methods for dispose handling
+ bool disposeTree(bool bForceDispose);
+
+ void haveNewParent(NodeSetInfoAccess* pNewParent);
+
+ rtl::Reference< configuration::ElementTree > getElementRef() const;
+ rtl::Reference< configuration::Template > getTemplateInfo() const;
+ };
+//-----------------------------------------------------------------------------
+
+ // Info interfaces for Set Elements
+ class RootElement : public TreeElement
+ {
+ public:
+ bool disposeTree();
+ protected:
+ virtual ApiRootTreeImpl& getRootTree() = 0;
+ };
+//-----------------------------------------------------------------------------
+
+ // Info interfaces for Set Elements
+ class UpdateRootElement : public RootElement
+ {
+ public:
+ Committer getCommitter();
+ };
+
+ // Thin Wrappers around TreeElements: Provide guarding and convenient access
+ /// wraps a TreeElement; provides an object (read) lock, ensures object was not disposed
+ class GuardedTreeElement {
+ UnoApiLock m_aLock;
+ TreeElement & m_rTree;
+
+ public:
+ explicit GuardedTreeElement(TreeElement & rTree): m_rTree(rTree)
+ { rTree.checkAlive(); }
+
+ TreeElement & get() const { return m_rTree; }
+ };
+
+ class GuardedRootElement {
+ UnoApiLock m_aLock;
+ RootElement & m_rTree;
+
+ public:
+ explicit GuardedRootElement(RootElement & rTree): m_rTree(rTree)
+ { rTree.checkAlive(); }
+
+ RootElement & get() const { return m_rTree; }
+ };
+ }
+}
+
+#endif // CONFIGMGR_API_TREEACCESS_HXX_
diff --git a/configmgr/source/api2/apitreeimplobj.cxx b/configmgr/source/api2/apitreeimplobj.cxx
new file mode 100644
index 000000000000..1795644ef3c3
--- /dev/null
+++ b/configmgr/source/api2/apitreeimplobj.cxx
@@ -0,0 +1,1004 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apitreeimplobj.cxx,v $
+ * $Revision: 1.44 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+
+#include "apitreeimplobj.hxx"
+#include "confignotifier.hxx"
+#include "notifierimpl.hxx"
+#include "apifactory.hxx"
+#include "apitreeaccess.hxx"
+#include "nodechangeinfo.hxx"
+#include "broadcaster.hxx"
+#include "change.hxx"
+#include "providerimpl.hxx"
+#include "roottree.hxx"
+#include "noderef.hxx"
+#include "anynoderef.hxx"
+#include "tracer.hxx"
+#include "treemanager.hxx"
+#include <cppuhelper/queryinterface.hxx>
+#include <vos/refernce.hxx>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+ namespace lang = ::com::sun::star::lang;
+//-----------------------------------------------------------------------------
+ class Factory;
+ class Notifier;
+//-----------------------------------------------------------------------------
+class ApiTreeImpl::ComponentAdapter : public lang::XEventListener
+{
+ vos::ORefCount m_refs;
+
+ ApiTreeImpl* pOwner;
+
+ uno::Reference< lang::XComponent > xProvider;
+ uno::Reference< lang::XComponent > xParent;
+public:
+ ComponentAdapter(ApiTreeImpl& rParent) : pOwner(&rParent) {}
+ virtual ~ComponentAdapter() {}
+
+ void clear();
+
+ void setProvider(uno::Reference< lang::XComponent > const& xProvider);
+ void setParent(uno::Reference< lang::XComponent > const& xParent);
+ uno::Reference< lang::XComponent > getProvider() const;
+
+// XEventListener
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+private:
+ void setComponent(uno::Reference< lang::XComponent >& rxSlot,uno::Reference< lang::XComponent > const& xComp);
+ uno::Reference< lang::XComponent > getComponent(uno::Reference< lang::XComponent > const& rxSlot) const;
+
+ virtual uno::Any SAL_CALL queryInterface(uno::Type const& rType) throw();
+ virtual void SAL_CALL disposing(com::sun::star::lang::EventObject const& rEvt) throw();
+};
+//-----------------------------------------------------------------------------
+inline
+uno::Reference< lang::XComponent >
+ ApiTreeImpl::ComponentAdapter::getComponent(
+ uno::Reference< lang::XComponent > const& rxSlot
+ ) const
+{
+ return rxSlot;
+}
+//-----------------------------------------------------------------------------
+inline
+void ApiTreeImpl::ComponentAdapter::setComponent(
+ uno::Reference< lang::XComponent >& rxSlot,
+ uno::Reference< lang::XComponent > const& xComp
+ )
+{
+ UnoApiLockClearable aGuard;
+
+ uno::Reference< lang::XComponent > xOld = rxSlot;
+ if (xOld != xComp)
+ {
+ rxSlot = xComp;
+
+ aGuard.clear();
+
+ if (xOld.is()) try { xOld->removeEventListener(this); } catch (uno::Exception & ) {}
+ if (xComp.is()) xComp->addEventListener(this);
+ }
+}
+//-----------------------------------------------------------------------------
+uno::Reference< lang::XComponent > ApiTreeImpl::ComponentAdapter::getProvider() const
+{
+ return this->getComponent( this->xProvider );
+}
+void ApiTreeImpl::ComponentAdapter::setProvider(uno::Reference< lang::XComponent > const& rProvider)
+{
+ this->setComponent( this->xProvider, rProvider);
+}
+void ApiTreeImpl::ComponentAdapter::setParent(uno::Reference< lang::XComponent > const& rParent)
+{
+ this->setComponent( this->xParent, rParent);
+}
+//-----------------------------------------------------------------------------
+
+void SAL_CALL ApiTreeImpl::ComponentAdapter::acquire() throw()
+{
+ ++m_refs;
+}
+//-------------------------------------------------------------------------
+
+void SAL_CALL ApiTreeImpl::ComponentAdapter::release() throw()
+{
+ if (--m_refs == 0)
+ delete this;
+}
+//-------------------------------------------------------------------------
+
+uno::Any SAL_CALL ApiTreeImpl::ComponentAdapter::queryInterface(uno::Type const& rType) throw()
+{
+ return cppu::queryInterface( rType
+ , static_cast< com::sun::star::lang::XEventListener*>(this)
+ , static_cast< uno::XInterface*>(this)
+ );
+}
+//-------------------------------------------------------------------------
+
+void SAL_CALL ApiTreeImpl::ComponentAdapter::disposing(com::sun::star::lang::EventObject const& rEvt) throw()
+{
+ UnoApiLockClearable aGuard;
+
+ if (this->pOwner != NULL)
+ {
+ CFG_TRACE_INFO("ApiTreeImpl:ComponentAdapter: Providing UNO object is disposed - relaying to my owner");
+ // ensure our owner stays alive
+ uno::Reference<uno::XInterface> xKeepOwnerAlive( this->pOwner->getUnoInstance() );
+ // and we stay alive too
+ rtl::Reference< ApiTreeImpl::ComponentAdapter > xKeepAlive( this );
+
+ aGuard.clear();
+
+ pOwner->disposing( rEvt );
+
+ UnoApiLock aClearGuard;
+ if (rEvt.Source == this->xParent) this->xParent.clear();
+ if (rEvt.Source == this->xProvider) this->xProvider.clear();
+ }
+ else
+ CFG_TRACE_INFO("ApiTreeImpl:ComponentAdapter: Providing UNO object is disposed - but my owner is already gone");
+}
+
+//-------------------------------------------------------------------------
+
+void ApiTreeImpl::ComponentAdapter::clear()
+{
+ UnoApiLockClearable aGuard;
+
+ this->pOwner = 0;
+
+ uno::Reference< lang::XComponent > aProvider = this->xProvider;
+ uno::Reference< lang::XComponent > aParent = this->xParent;
+ this->xProvider = 0;
+ this->xParent = 0;
+
+ aGuard.clear();
+
+ if (aParent.is()) try { aParent ->removeEventListener(this); } catch (uno::Exception & ) {}
+ if (aProvider.is()) try { aProvider->removeEventListener(this); } catch (uno::Exception & ) {}
+}
+
+//-----------------------------------------------------------------------------
+class ApiRootTreeImpl::NodeListener : public INodeListener
+{
+ ApiRootTreeImpl* pParent;
+ TreeManager * pSource;
+
+ vos::ORef< OOptions > m_xOptions;
+ configuration::AbsolutePath m_aLocationPath;
+public:
+ NodeListener(ApiRootTreeImpl& _rParent)
+ : pParent(&_rParent)
+ , pSource(NULL)
+ , m_aLocationPath( configuration::AbsolutePath::root() )
+ {}
+ ~NodeListener()
+ {
+ unbind();
+ }
+
+ TreeManager * getSource()
+ {
+ UnoApiLock aGuard;
+ return pSource;
+ }
+
+ void setSource(TreeManager * pNew)
+ {
+ UnoApiLock aGuard;
+ if (pParent)
+ {
+ if (pNew != pSource)
+ {
+ OSL_ENSURE(m_xOptions.isValid(),"Cannot set IConfigListener without Options");
+ if (m_xOptions.isValid())
+ {
+ if (pSource)
+ pSource->removeListener(m_xOptions->getRequestOptions(), this);
+
+ pSource = pNew;
+ if (pNew)
+ {
+ OSL_ENSURE(!m_aLocationPath.isRoot(), "Cannot register for notifications: no location set");
+ pNew->addListener(m_aLocationPath, m_xOptions->getRequestOptions(), this);
+ }
+ }
+ else
+ pSource = 0;
+ }
+ }
+ }
+
+ void setLocation(configuration::AbsolutePath const& _aLocation, vos::ORef< OOptions > const& _xOptions)
+ {
+ OSL_ASSERT(_xOptions.isValid());
+
+ UnoApiLock aGuard;
+
+ if (pSource && pParent)
+ {
+ OSL_ASSERT(m_xOptions.isValid());
+ pSource->removeListener(m_xOptions->getRequestOptions(), this);
+ }
+
+ m_aLocationPath = _aLocation;
+ m_xOptions = _xOptions;
+
+ if (pSource && pParent)
+ pSource->addListener(m_aLocationPath, m_xOptions->getRequestOptions(), this);
+ }
+
+ void unbind()
+ {
+ UnoApiLock aGuard;
+ OSL_ASSERT(pParent == 0);
+ pParent = 0;
+ if (pSource)
+ {
+ OSL_ASSERT(m_xOptions.isValid());
+ pSource->removeListener(m_xOptions->getRequestOptions(), this);
+ m_xOptions.unbind();
+ m_aLocationPath = configuration::AbsolutePath::root();
+ }
+
+ }
+
+ void clearParent()
+ {
+ UnoApiLockClearable aGuard;
+ if (pParent)
+ {
+ pParent = 0;
+
+ if (pSource)
+ {
+ TreeManager * pOrgSource = pSource;
+ vos::ORef< OOptions > xOptions = m_xOptions;
+
+ pSource = 0;
+ m_xOptions.unbind();
+ m_aLocationPath = configuration::AbsolutePath::root();
+
+ aGuard.clear();
+
+ OSL_ASSERT(xOptions.isValid());
+ pOrgSource->removeListener(xOptions->getRequestOptions(), this);
+ }
+ }
+ }
+
+ // Interfaces
+ virtual void disposing(TreeManager * pSource);
+ virtual void nodeChanged(Change const& aChange, configuration::AbsolutePath const& sPath, TreeManager * pSource);
+ virtual void nodeDeleted(configuration::AbsolutePath const& sPath, TreeManager * pSource);
+};
+
+//-------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// API object implementation wrappers
+//-------------------------------------------------------------------------
+ApiProvider::ApiProvider(Factory& rFactory, OProviderImpl& rProviderImpl )
+ : m_rFactory(rFactory)
+ , m_rProviderImpl(rProviderImpl)
+{}
+//-------------------------------------------------------------------------
+
+uno::Reference<com::sun::star::script::XTypeConverter> ApiProvider::getTypeConverter() const
+{
+ return m_rProviderImpl.getTypeConverter();
+}
+//-------------------------------------------------------------------------
+static
+inline
+configuration::DefaultProvider createDefaultProvider(
+ ApiProvider& rProvider,
+ rtl::Reference< configuration::Tree > const& aTree,
+ vos::ORef< OOptions > const& _xOptions
+ )
+{
+ OProviderImpl& rProviderImpl = rProvider.getProviderImpl();
+ rtl::Reference< TreeManager > xDefaultProvider = rProviderImpl.getDefaultProvider();
+
+ OSL_ASSERT(_xOptions.isValid());
+ RequestOptions const aOptions = _xOptions.isValid() ? _xOptions->getRequestOptions() : RequestOptions();
+
+ return configuration::DefaultProvider::create(aTree,aOptions,xDefaultProvider,&rProviderImpl);
+}
+//-------------------------------------------------------------------------
+static
+inline
+configuration::DefaultProvider extractDefaultProvider(ApiTreeImpl* pParentTree)
+{
+ if (pParentTree)
+ return pParentTree->getDefaultProvider();
+
+ else
+ return configuration::DefaultProvider::createEmpty();
+}
+//-------------------------------------------------------------------------
+ApiTreeImpl::ApiTreeImpl(uno::XInterface* pInstance, ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, ApiTreeImpl* pParentTree)
+: m_aTree(aTree)
+, m_aNotifier(new NotifierImpl(aTree))
+, m_aDefaultProvider(extractDefaultProvider(pParentTree))
+, m_xProvider()
+, m_rProvider(rProvider)
+, m_pParentTree(0)
+, m_pInstance(pInstance)
+{
+ OSL_ENSURE(pParentTree == NULL || &rProvider == &pParentTree->m_rProvider,"WARNING: Parent tree has a different provider - trouble may be ahead");
+ setNodeInstance(aTree->getRootNode(), pInstance);
+ init(pParentTree);
+}
+//-------------------------------------------------------------------------
+ApiTreeImpl::ApiTreeImpl(uno::XInterface* _pInstance, ApiProvider& _rProvider, rtl::Reference< configuration::Tree > const& _aTree, configuration::DefaultProvider const& _aDefaultProvider)
+: m_aTree(_aTree)
+, m_aNotifier(new NotifierImpl(_aTree))
+, m_aDefaultProvider(_aDefaultProvider)
+, m_xProvider()
+, m_rProvider(_rProvider)
+, m_pParentTree(0)
+, m_pInstance(_pInstance)
+{
+ setNodeInstance(_aTree->getRootNode(), _pInstance);
+ init(NULL);
+}
+//-------------------------------------------------------------------------
+
+ApiTreeImpl::~ApiTreeImpl()
+{
+ OSL_ENSURE(m_aNotifier->m_aListeners.isDisposed(),"ApiTree Object was not disposed properly");
+ deinit();
+}
+//-------------------------------------------------------------------------
+
+ApiRootTreeImpl::ApiRootTreeImpl(uno::XInterface* pInstance, ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions > const& _xOptions)
+: m_aTreeImpl(pInstance, rProvider, aTree, createDefaultProvider(rProvider, aTree, _xOptions))
+, m_aLocationPath( configuration::Path::Rep() )
+, m_pNotificationListener(NULL)
+, m_xOptions(_xOptions)
+{
+ implSetLocation(aTree);
+ enableNotification(true);
+}
+//-------------------------------------------------------------------------
+ApiRootTreeImpl::~ApiRootTreeImpl()
+{
+ if (m_pNotificationListener.is())
+ {
+ m_pNotificationListener->setSource(0);
+ m_pNotificationListener->clearParent();
+ }
+}
+//-------------------------------------------------------------------------
+
+void ApiTreeImpl::setNodeInstance(configuration::NodeRef const& aNode, uno::XInterface* pInstance)
+{
+ OSL_ENSURE(aNode.isValid(),"ERROR: adding invalid node to ApiTree");
+ OSL_ENSURE(m_aTree->isValidNode(aNode.getOffset()),"ERROR: foreign node being added to ApiTree");
+ m_aNotifier->m_aListeners.setObjectAt( configuration::NodeID(m_aTree, aNode).toIndex(), pInstance );
+}
+
+//-------------------------------------------------------------------------
+
+bool ApiTreeImpl::isAlive() const
+{
+ return m_aNotifier->m_aListeners.isAlive();
+}
+//-------------------------------------------------------------------------
+void ApiTreeImpl::checkAlive() const
+{
+ m_aNotifier->m_aListeners.checkAlive( getUnoInstance() );
+}
+
+//-------------------------------------------------------------------------
+
+Notifier ApiTreeImpl::getNotifier() const
+{
+ return Notifier(m_aNotifier,this);
+}
+//-------------------------------------------------------------------------
+
+bool ApiRootTreeImpl::enableNotification(bool bEnable)
+{
+ TreeManager * pSource = bEnable ? getApiTree().getProvider().getProviderImpl().getNotifier() : 0;
+
+ TreeManager * pOld = this->implSetNotificationSource(pSource);
+
+ return pOld != 0;
+}
+//-------------------------------------------------------------------------
+
+bool ApiTreeImpl::disposeTree(bool bForce)
+{
+ CFG_TRACE_INFO("ApiTreeImpl: Disposing Tree (may throw if already disposed)");
+
+ // ensure our provider stays alive
+ uno::Reference<uno::XInterface> xKeepParentAlive(this->getParentComponent());
+ // ensure we stay alive too
+ uno::Reference<uno::XInterface> xKeepAlive(this->getUnoInstance());
+
+ // #109077# If already disposed, we may have no source data or data lock
+ if (!isAlive())
+ return false;
+
+ if (!bForce)
+ {
+ if (m_pParentTree != 0)
+ return false;
+
+ // recheck after having the mutex
+ checkAlive(); // may throw
+ }
+ else if (m_pParentTree)
+ setParentTree(NULL);
+
+ implDisposeTree();
+ OSL_ASSERT(!isAlive()); // post condition
+
+ return true;
+}
+//-------------------------------------------------------------------------
+
+bool ApiTreeImpl::disposeTreeNow()
+{
+ CFG_TRACE_INFO("ApiTreeImpl: Disposing Tree Now (unless disposed)");
+ if (isAlive() )
+ return implDisposeTree();
+ else
+ return false;
+}
+//-------------------------------------------------------------------------
+bool ApiRootTreeImpl::disposeTree()
+{
+ CFG_TRACE_INFO("Api Root Tree: Disposing Tree And Releasing (unless disposed)");
+ // ensure our provider stays alive
+ uno::Reference<uno::XInterface> xKeepProvider( m_aTreeImpl.getUnoProviderInstance() );
+
+ rtl::Reference<NodeListener> xListener = m_pNotificationListener;
+ if (xListener.is())
+ {
+ xListener->clearParent();
+ xListener.clear();
+ }
+
+ bool bDisposed = m_aTreeImpl.disposeTreeNow();
+
+ if (bDisposed) releaseData();
+
+ if (!m_xOptions.isEmpty())
+ {
+ OSL_ENSURE(!bDisposed, "Disposing/Releasing should clear the options");
+ CFG_TRACE_INFO2("Api Root Tree: data was not released in disposeTree");
+ }
+
+ return bDisposed;
+}
+//-------------------------------------------------------------------------
+bool ApiTreeImpl::implDisposeTree()
+{
+ OSL_ENSURE(m_pParentTree == 0,"WARNING: Disposing a tree that still has a parent tree set");
+
+ SpecialListenerContainer <configuration::SubNodeID,SubNodeHash,SubNodeEq,SubNodeToIndex>& aContainer = m_aNotifier->m_aListeners;
+ if (aContainer.beginDisposing())
+ {
+ CFG_TRACE_INFO("ApiTreeImpl: Tree is now disposed");
+
+ Factory& rFactory = getFactory();
+
+ std::vector<configuration::NodeID> aChildNodes;
+ configuration::getAllContainedNodes( m_aTree, aChildNodes);
+
+ for (std::vector<configuration::NodeID>::reverse_iterator it = aChildNodes.rbegin(), stop = aChildNodes.rend();
+ it != stop;
+ ++it)
+ {
+ rFactory.revokeElement( *it );
+ }
+
+ CFG_TRACE_INFO_NI("ApiTreeImpl: Listeners are now informed");
+ aContainer.notifyDisposing();
+
+ OSL_ASSERT(!aContainer.isDisposed());
+
+ CFG_TRACE_INFO_NI("ApiTreeImpl: Deinitializing");
+ deinit(); // releases the provider and parent
+ aContainer.endDisposing();
+
+ OSL_ASSERT(aContainer.isDisposed());
+
+ return true;
+ }
+ else
+ {
+ CFG_TRACE_INFO("ApiTreeImpl: Tree was already disposed.");
+ return false;
+ }
+}
+//-------------------------------------------------------------------------
+void ApiTreeImpl::disposeNode(configuration::NodeRef const& aNode, uno::XInterface* pInstance)
+{
+ // This used to contain 3 nested 'isAlive()' calls; why !?
+ if (isAlive())
+ implDisposeNode(aNode,pInstance);
+}
+//-------------------------------------------------------------------------
+void ApiTreeImpl::implDisposeNode(configuration::NodeRef const& aNode, uno::XInterface* )
+{
+ CFG_TRACE_INFO("ApiTreeImpl: Disposing a single node.");
+ OSL_ENSURE(aNode.isValid(),"INTERNAL ERROR: Disposing NULL node");
+ OSL_ENSURE(m_aTree->isValidNode(aNode.getOffset()),"INTERNAL ERROR: Disposing: node does not match tree");
+ OSL_ENSURE( !m_aTree->isRootNode(aNode),"INTERNAL ERROR: Disposing the root node of the tree");
+
+ configuration::NodeID aNodeID(m_aTree,aNode);
+
+ if (m_aNotifier->m_aListeners.disposeOne(aNodeID.toIndex()) )
+ {
+ getFactory().revokeElement(aNodeID);
+ }
+}
+//-------------------------------------------------------------------------
+void ApiTreeImpl::init(ApiTreeImpl* pParentTree)
+{
+ m_xProvider = new ComponentAdapter(*this);
+ m_xProvider->setProvider( this->getProviderComponent() );
+
+ OSL_ENSURE(m_xProvider->getProvider().is(),"WARNING: Provider is no Component - Lifetime trouble ahead");
+
+ OSL_ASSERT(m_pParentTree == 0);
+ setParentTree(pParentTree);
+}
+//-------------------------------------------------------------------------
+void ApiTreeImpl::deinit()
+{
+ setParentTree(0);
+
+ uno::Reference<ComponentAdapter> xAdapter = m_xProvider;
+ m_xProvider.clear();
+
+ if (xAdapter.is())
+ xAdapter->clear();
+}
+//-------------------------------------------------------------------------
+void ApiTreeImpl::haveNewParent(ApiTreeImpl* pNewParent) // public interface
+{
+ setParentTree(pNewParent);
+}
+
+//-------------------------------------------------------------------------
+
+ApiTreeImpl const* ApiTreeImpl::getRootTreeImpl() const
+{
+ ApiTreeImpl const* pRet = this;
+ while (pRet->m_pParentTree)
+ pRet = pRet->m_pParentTree;
+
+ return pRet;
+}
+
+//-------------------------------------------------------------------------
+void ApiTreeImpl::setParentTree(ApiTreeImpl* pParentTree) // internal implementation
+{
+#if OSL_DEBUG_LEVEL > 0
+ if (pParentTree)
+ {
+ rtl::Reference< configuration::Tree > aContext = m_aTree->getContextTree();
+ rtl::Reference< configuration::Tree > aParent = pParentTree->m_aTree;
+
+ configuration::NodeID aContextID( aContext, aContext->getRootNode() );
+ configuration::NodeID aParentID( aParent, aParent->getRootNode() );
+
+ OSL_ENSURE( aContextID == aParentID, "Parent relationship mismatch !");
+ }
+#endif
+
+ if (m_pParentTree != pParentTree)
+ {
+ uno::Reference<ComponentAdapter> xAdapter = m_xProvider;
+
+ m_pParentTree = pParentTree;
+
+ uno::Reference<com::sun::star::lang::XComponent> xNew = getParentComponent();
+ OSL_ENSURE( xNew.is() == (pParentTree != 0), "WARNING: Parent Tree is no Component");
+
+ if (xAdapter.is())
+ xAdapter->setParent(xNew);
+ else
+ OSL_ENSURE( pParentTree == 0, "ERROR: Setting New Parent at deinitialized ApiTreeImpl");
+
+ }
+}
+//-------------------------------------------------------------------------
+
+uno::Reference<uno::XInterface> ApiTreeImpl::getUnoProviderInstance() const
+{
+ uno::Reference<ComponentAdapter> xAdapter = m_xProvider;
+
+ uno::Reference<uno::XInterface> xReturn;
+ if (xAdapter.is())
+ xReturn = xAdapter->getProvider();
+ return xReturn;
+}
+
+//-------------------------------------------------------------------------
+uno::Reference<com::sun::star::lang::XComponent> ApiTreeImpl::getParentComponent()
+{
+ uno::XInterface* pInterface = m_pParentTree ? m_pParentTree->getUnoInstance() : 0;
+ return uno::Reference<com::sun::star::lang::XComponent>::query(pInterface);
+}
+//-------------------------------------------------------------------------
+
+uno::Reference<com::sun::star::lang::XComponent> ApiTreeImpl::getProviderComponent()
+{
+ uno::XInterface* pInterface = m_rProvider.getProviderImpl().getProviderInstance();
+ return uno::Reference<com::sun::star::lang::XComponent>::query(pInterface);
+}
+
+//-------------------------------------------------------------------------
+
+void ApiTreeImpl::disposing(com::sun::star::lang::EventObject const& ) throw()
+{
+ // this is a non-UNO external entry point - we need to keep this object alive for the duration of the call
+ CFG_TRACE_INFO("ApiTreeImpl: Providing UNO object is disposed - disposing the tree");
+
+ // Tree write Lock should be set by sender
+
+ CFG_TRACE_INFO_NI("Clearing parent reference");
+ setParentTree(0);
+
+ CFG_TRACE_INFO_NI("Trying to dispose");
+ //implDisposeTree();
+ disposeTreeNow();
+
+ CFG_TRACE_INFO_NI("Done disposing Tree");
+ // uno::Reference<com::sun::star::lang::XComponent> xThis(getUnoInstance(),UNO_QUERY);
+ // if (xThis.is()) xThis->dispose();
+}
+//-------------------------------------------------------------------------
+TreeManager * ApiRootTreeImpl::implSetNotificationSource(TreeManager * pNew)
+{
+ TreeManager * pOld = m_pNotificationListener.is() ? m_pNotificationListener->getSource() : 0;
+ if (pOld != pNew)
+ {
+ OSL_ENSURE(m_xOptions.isValid(), "Cannot change notification source without options");
+
+ if (!m_pNotificationListener.is())
+ m_pNotificationListener = new NodeListener(*this);
+
+ m_pNotificationListener->setSource(pNew);
+
+ }
+ return pOld;
+}
+// ---------------------------------------------------------------------------------------------------
+
+void ApiRootTreeImpl::implSetLocation(rtl::Reference< configuration::Tree > const& _aTree)
+{
+ OSL_ASSERT(_aTree == getApiTree().getTree());
+ if (!configuration::isEmpty(_aTree.get()))
+ {
+ m_aLocationPath = _aTree->getRootPath();
+ OSL_ENSURE(!m_aLocationPath.isRoot(), "Setting up a root tree without location");
+ }
+ else
+ {
+ OSL_ENSURE(false, "Setting up a root tree without data");
+ m_aLocationPath = configuration::AbsolutePath::root();
+ }
+
+ if (!m_pNotificationListener.is())
+ m_pNotificationListener = new NodeListener(*this);
+
+ OSL_ENSURE(!m_aLocationPath.isRoot() && !m_aLocationPath.isDetached(), "Cannot reregister for notifications: setting empty location");
+ OSL_ENSURE( m_xOptions.isValid(), "Cannot reregister for notifications: no options available" );
+
+ m_pNotificationListener->setLocation(m_aLocationPath, m_xOptions);
+}
+// ---------------------------------------------------------------------------------------------------
+
+void ApiRootTreeImpl::releaseData()
+{
+ CFG_TRACE_INFO("Api Root Tree at %s: releasing the Data",OUSTRING2ASCII(m_aLocationPath.toString()));
+ rtl::Reference< configuration::Tree > aTree( m_aTreeImpl.getTree() );
+
+ if (aTree.is()) {
+ aTree->disposeData();
+ }
+ OSL_ASSERT(configuration::isEmpty(aTree.get()));
+
+ OSL_ENSURE( !m_aLocationPath.isRoot() && !m_aLocationPath.isDetached(), "Location still needed to release data" );
+ OSL_ENSURE( m_xOptions.isValid(), "Options still needed to release data" );
+
+ getApiTree().getProvider().getProviderImpl().releaseSubtree(m_aLocationPath,m_xOptions->getRequestOptions());
+ m_xOptions.unbind();
+
+ m_aLocationPath = configuration::AbsolutePath::detachedRoot();
+}
+// ---------------------------------------------------------------------------------------------------
+
+void ApiRootTreeImpl::NodeListener::disposing(TreeManager * _pSource)
+{
+ UnoApiLockClearable aGuard;
+
+ OSL_ASSERT( !pSource || _pSource == pSource );
+ if (pParent)
+ {
+ // this is a non-UNO external entry point - we need to keep this object alive for the duration of the call
+ uno::Reference<uno::XInterface> xKeepAlive( pParent->m_aTreeImpl.getUnoInstance() );
+ ApiRootTreeImpl* pKeepParent = pParent;
+ aGuard.clear();
+
+ pKeepParent->disposing(_pSource);
+ }
+}
+void ApiRootTreeImpl::disposing(TreeManager *)
+{
+ CFG_TRACE_INFO("Api Root Tree at %s: Cache data is disposed - dispose and release own data",
+ OUSTRING2ASCII(m_aLocationPath.toString()));
+ // ensure our provider stays alive
+ uno::Reference<uno::XInterface> xKeepProvider( m_aTreeImpl.getUnoProviderInstance() );
+
+ rtl::Reference<NodeListener> xListener = m_pNotificationListener;
+ if (xListener.is())
+ {
+ xListener->clearParent();
+ xListener.clear();
+ }
+
+ if (m_aTreeImpl.disposeTreeNow())
+ releaseData(); // not really needed: the whole data is going away anyways
+}
+// ---------------------------------------------------------------------------------------------------
+
+static
+void disposeOneRemovedNode(configuration::NodeChangeInformation const& aRemoveInfo, Factory& aFactory)
+{
+ if (aRemoveInfo.change.element.oldValue.is())
+ {
+ OSL_ENSURE(aRemoveInfo.change.element.isDataChange(), "ERROR: Disposing replaced element: Element did not really change !");
+
+ rtl::Reference< configuration::ElementTree > aElementRef( aRemoveInfo.change.element.oldValue.get() );
+
+ SetElement* pSetElement = aFactory.findSetElement(aElementRef );
+ if (pSetElement)
+ {
+ // factory always does an extra acquire
+ uno::Reference<uno::XInterface> xReleaseSetElement(pSetElement->getUnoInstance(), uno::UNO_REF_NO_ACQUIRE);
+
+ pSetElement->haveNewParent(0);
+ pSetElement->disposeTree(true);
+ }
+ }
+ else
+ {
+ // This must apply to a node for which no element tree had been loaded in this view
+ // thus there should not be one now after the change (even if the change was replacing)
+ OSL_ENSURE(!aRemoveInfo.change.element.newValue.is(), "Cannot dispose replaced element: No tree object available");
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+
+static
+void disposeRemovedNodes(configuration::NodeChangesInformation const& aChanges, Factory& aFactory)
+{
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin(); it != aChanges.end(); ++it)
+ {
+ switch (it->change.type)
+ {
+ case configuration::NodeChangeData::eReplaceElement:
+ // check if element is actually unchanged !
+ // (cannot dispose of the tree, if it is still in use)
+ if (! it->change.element.isDataChange()) break;
+
+ // else dispose the old one: fall thru
+
+ case configuration::NodeChangeData::eRemoveElement:
+ disposeOneRemovedNode( *it, aFactory );
+ break;
+
+ default: break;
+ }
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+//INodeListener : IConfigListener
+void ApiRootTreeImpl::NodeListener::nodeChanged(Change const& aChange, configuration::AbsolutePath const& sPath, TreeManager * _pSource)
+{
+ UnoApiLockClearable aGuard;
+
+ OSL_ASSERT( !pSource || _pSource == pSource );
+ if (pParent)
+ {
+ // this is a non-UNO external entry point - we need to keep this object alive for the duration of the call
+ uno::Reference<uno::XInterface> xKeepAlive( pParent->m_aTreeImpl.getUnoInstance() );
+ ApiRootTreeImpl* pKeepParent = pParent;
+ aGuard.clear();
+
+ pKeepParent->nodeChanged(aChange,sPath,_pSource);
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+
+//INodeListener : IConfigListener
+void ApiRootTreeImpl::nodeChanged(Change const& aChange, configuration::AbsolutePath const& aChangePath, TreeManager *)
+{
+ // do not dipatch if we are dying/dead anyway
+ if (m_aTreeImpl.isAlive())
+ try
+ {
+ rtl::Reference< configuration::Tree > aTree(m_aTreeImpl.getTree());
+
+ OSL_ENSURE(configuration::Path::hasPrefix(aChangePath, m_aLocationPath),
+ "'changed' Path does not indicate this tree or its context: ");
+
+ configuration::RelativePath aLocalChangePath = configuration::Path::stripPrefix(aChangePath,m_aLocationPath);
+
+ // find the node and change
+ configuration::NodeRef aNode;
+
+ if ( !aLocalChangePath.isEmpty() )
+ {
+ configuration::NodeRef aBaseNode = aTree->getRootNode();
+
+#ifdef DBG_UTIL
+ try {
+ configuration::RelativePath aLocalPathOld = configuration::validateAndReducePath(aChangePath.toString(), aTree, aBaseNode);
+ OSL_ENSURE( configuration::matches(aLocalPathOld,aLocalChangePath),
+ "New local path different from validateAndReducePath(...) result in notification dispatch");
+ }
+ catch (configuration::Exception& e) {
+ rtl::OString sMsg("Cannot validate new path handling for notification dispatch: ");
+ sMsg += e.what();
+ OSL_ENSURE(false, sMsg.getStr() );
+ }
+#endif // DBG_UTIL
+
+ configuration::AnyNodeRef aFoundNode = configuration::getDeepDescendant(aTree, aBaseNode, aLocalChangePath);
+ if ( aFoundNode.isValid() )
+ {
+ if (aFoundNode.isNode())
+ {
+ aNode = aFoundNode.toNode();
+ }
+ else
+ {
+ // TODO: Notify using parent node and temporary dummy change
+ OSL_ENSURE( false, "Notification broken: Node being adressed is a Value");
+ }
+ }
+ }
+ else
+ {
+ aNode = aTree->getRootNode();
+ }
+
+ SubtreeChange const* pTreeChange = NULL;
+ if (aNode.isValid())
+ {
+ pTreeChange = dynamic_cast<SubtreeChange const*>(&aChange);
+ OSL_ENSURE(pTreeChange != 0, "Notification broken: Change to inner node is not a subtree change"); // TODO: Notify set change using parent (if available) and temporary dummy change
+ }
+
+ if (pTreeChange != NULL) // implies aNode.isValid()
+ {
+ OSL_ENSURE( aChange.getNodeName() == aTree->getSimpleNodeName(aNode.getOffset()),
+ "Change's node-name does not match found node's name - erratic notification");
+
+ configuration::NodeChangesInformation aChanges;
+
+ if (configuration::adjustToChanges(aChanges, aTree,aNode, *pTreeChange))
+ {
+ OSL_ASSERT(aChanges.size() > 0);
+
+ Broadcaster aSender(m_aTreeImpl.getNotifier(),aChanges,false);
+
+ // Should be improved later. Maybe this is the wrong lock for disposeTree ?
+ // aLocalGuard.downgrade(); // partial clear for broadcast
+
+ aSender.notifyListeners(aChanges, false);
+
+ disposeRemovedNodes(aChanges, m_aTreeImpl.getFactory());
+ }
+ }
+ }
+ catch (configuration::InvalidName& i)
+ {
+ rtl::OString sMsg("Cannot locate change within this tree: ");
+ sMsg += i.what();
+ OSL_ENSURE(false, sMsg.getStr() );
+ }
+ catch (configuration::Exception& e)
+ {
+ rtl::OString sMsg("Unexpected error trying to react on update: ");
+ sMsg += e.what();
+ OSL_ENSURE(false, sMsg.getStr() );
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+
+void ApiRootTreeImpl::NodeListener::nodeDeleted(configuration::AbsolutePath const& _aPath, TreeManager * _pSource)
+{
+ UnoApiLockClearable aGuard;
+
+ OSL_ASSERT( !pSource || _pSource == pSource );
+ if (pParent)
+ {
+ // this is a non-UNO external entry point - we need to keep this object alive for the duration of the call
+ uno::Reference<uno::XInterface> xKeepAlive( pParent->m_aTreeImpl.getUnoInstance() );
+ ApiRootTreeImpl* pKeepParent = pParent;
+ aGuard.clear();
+
+ pKeepParent->nodeDeleted(_aPath,_pSource);
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+void ApiRootTreeImpl::nodeDeleted(configuration::AbsolutePath const& _aDeletedPath, TreeManager *)
+{
+ { (void)_aDeletedPath; }
+
+ // this is a non-UNO external entry point - we need to keep this object alive for the duration of the call
+ uno::Reference<uno::XInterface> xKeepAlive( m_aTreeImpl.getUnoInstance() );
+
+#ifdef DBG_UTIL
+ OSL_ENSURE(configuration::Path::hasPrefix(m_aLocationPath, _aDeletedPath),
+ "'deleted' Path does not indicate this tree or its context: ");
+#endif
+ // ensure our provider stays alive
+ uno::Reference<uno::XInterface> xKeepProvider( m_aTreeImpl.getUnoProviderInstance() );
+
+ rtl::Reference<NodeListener> xListener = m_pNotificationListener;
+ if (xListener.is())
+ {
+ xListener->clearParent();
+ xListener.clear();
+ }
+
+ if (m_aTreeImpl.disposeTreeNow())
+ releaseData();
+}
+
+// ---------------------------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/api2/apitreeimplobj.hxx b/configmgr/source/api2/apitreeimplobj.hxx
new file mode 100644
index 000000000000..8b17abc98102
--- /dev/null
+++ b/configmgr/source/api2/apitreeimplobj.hxx
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apitreeimplobj.hxx,v $
+ * $Revision: 1.27 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_TREEIMPLOBJECTS_HXX_
+#define CONFIGMGR_API_TREEIMPLOBJECTS_HXX_
+
+#include "noderef.hxx"
+#include "configset.hxx"
+#include "configdefaultprovider.hxx"
+#include "confevents.hxx"
+#include "options.hxx"
+#include "utility.hxx"
+#include <boost/utility.hpp>
+#include <vos/ref.hxx>
+#include <rtl/ref.hxx>
+#include <osl/mutex.hxx>
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+
+namespace com { namespace sun { namespace star {
+ namespace script { class XTypeConverter; }
+} } }
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ class OProviderImpl;
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+ class Factory;
+ class Notifier;
+ class NotifierImpl;
+//-----------------------------------------------------------------------------
+ class ObjectRegistry;
+//-----------------------------------------------------------------------------
+// API object implementation wrappers
+//-------------------------------------------------------------------------
+ class ApiProvider: private boost::noncopyable
+ {
+ Factory& m_rFactory;
+ OProviderImpl& m_rProviderImpl;
+ public:
+ ApiProvider(Factory& rFactory, OProviderImpl& rProviderImpl );
+
+ ~ApiProvider()
+ {}
+
+ uno::Reference<com::sun::star::script::XTypeConverter> getTypeConverter() const;
+ Factory& getFactory() { return m_rFactory; }
+ OProviderImpl& getProviderImpl() { return m_rProviderImpl; }
+ };
+
+ //-----------------------------------------------------------------------------
+
+ //-------------------------------------------------------------------------
+ class ApiTreeImpl: private boost::noncopyable
+ {
+ class ComponentAdapter;
+
+ rtl::Reference< configuration::Tree > m_aTree;
+ vos::ORef<NotifierImpl> m_aNotifier;
+ configuration::DefaultProvider m_aDefaultProvider;
+ uno::Reference<ComponentAdapter> m_xProvider;
+ ApiProvider& m_rProvider;
+ ApiTreeImpl* m_pParentTree;
+ uno::XInterface* m_pInstance;
+
+ public:
+ explicit ApiTreeImpl(uno::XInterface* pInstance, ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, ApiTreeImpl* pParentTree);
+ explicit ApiTreeImpl(uno::XInterface* _pInstance, ApiProvider& _rProvider, rtl::Reference< configuration::Tree > const& _aTree, configuration::DefaultProvider const & _aDefaultProvider);
+ ~ApiTreeImpl();
+
+ // initialization
+ void setNodeInstance(configuration::NodeRef const& aNode, uno::XInterface* pInstance);
+
+ // model access
+ rtl::Reference< configuration::Tree > getTree() const { return m_aTree; }
+
+ // self-locked methods for dispose handling
+ bool isAlive() const;
+ void checkAlive() const;
+ bool disposeTree(bool bForce);
+ bool disposeTreeNow();
+ void disposeNode(configuration::NodeRef const& aNode, uno::XInterface* pInstance);
+
+ // api object handling
+ Factory& getFactory() const { return m_rProvider.getFactory(); }
+ Notifier getNotifier() const;
+ configuration::DefaultProvider getDefaultProvider() const { return m_aDefaultProvider; }
+
+ // needs external locking
+ ApiTreeImpl const* getRootTreeImpl() const;
+
+ uno::XInterface* getUnoInstance() const { return m_pInstance; }
+ ApiProvider& getProvider() { return m_rProvider; }
+ uno::Reference<uno::XInterface> getUnoProviderInstance() const; // { return m_xProvider; }
+
+ /// wire this to a new parent tree
+ void haveNewParent(ApiTreeImpl* pNewParent);
+ private:
+ void init(ApiTreeImpl* pParentTree);
+ void setParentTree(ApiTreeImpl* pNewParentTree);
+ void deinit();
+
+ bool implDisposeTree();
+ void implDisposeNode(configuration::NodeRef const& aNode, uno::XInterface* pInstance);
+
+ friend class ComponentAdapter;
+ void disposing(com::sun::star::lang::EventObject const& rEvt) throw();
+ uno::Reference<com::sun::star::lang::XComponent> getProviderComponent();
+ uno::Reference<com::sun::star::lang::XComponent> getParentComponent();
+
+ };
+
+ //-----------------------------------------------------------------------------
+ class ApiRootTreeImpl
+ {
+ public:
+ explicit ApiRootTreeImpl(uno::XInterface* pInstance, ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions > const& _xOptions);
+ ~ApiRootTreeImpl();
+
+ ApiTreeImpl& getApiTree() { return m_aTreeImpl; }
+ ApiTreeImpl const& getApiTree() const { return m_aTreeImpl; }
+
+ configuration::AbsolutePath const & getLocation() const { return m_aLocationPath; }
+ vos::ORef< OOptions > getOptions() const { return m_xOptions; }
+
+ // self-locked methods for dispose handling
+ bool disposeTree();
+
+ /// toggle whether this object relays notifications from the base provider
+ bool enableNotification(bool bEnable);
+ private:
+ TreeManager * implSetNotificationSource(TreeManager * pNew);
+ void implSetLocation(rtl::Reference< configuration::Tree > const& _aTree);
+ void releaseData();
+
+ private:
+ class NodeListener;
+ friend class NodeListener;
+
+ // IConfigListener
+ void disposing(TreeManager * pSource) ;
+ //INodeListener : IConfigListener
+ void nodeChanged(Change const& aChange, configuration::AbsolutePath const& aPath, TreeManager * pSource);
+ void nodeDeleted(configuration::AbsolutePath const& aPath, TreeManager * pSource);
+
+ private:
+ ApiTreeImpl m_aTreeImpl;
+ configuration::AbsolutePath m_aLocationPath;
+ rtl::Reference<NodeListener> m_pNotificationListener;
+ vos::ORef< OOptions > m_xOptions;
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_API_TREEIMPLOBJECTS_HXX_
diff --git a/configmgr/source/api2/broadcaster.cxx b/configmgr/source/api2/broadcaster.cxx
new file mode 100644
index 000000000000..7db7b1090111
--- /dev/null
+++ b/configmgr/source/api2/broadcaster.cxx
@@ -0,0 +1,1229 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: broadcaster.cxx,v $
+ * $Revision: 1.21 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "broadcaster.hxx"
+#include "notifierimpl.hxx"
+#include "confignotifier.hxx"
+#include "noderef.hxx"
+#include "nodechange.hxx"
+#include "nodechangeinfo.hxx"
+#include "translatechanges.hxx"
+#include "apifactory.hxx"
+#include "apitreeaccess.hxx"
+#include "apitreeimplobj.hxx"
+#include <vos/refernce.hxx>
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+#ifndef INCLUDED_SET
+#include <set>
+#define INCLUDED_SET
+#endif
+#ifndef INCLUDED_FUNCTIONAL
+#include <functional>
+#define INCLUDED_FUNCTIONAL
+#endif
+
+namespace configmgr
+{
+ namespace configapi
+ {
+// ---------------------------------------------------------------------------------------------------
+// Broadcaster implementation
+// ---------------------------------------------------------------------------------------------------
+ class BroadcasterHelper
+ {
+ public:
+ static vos::ORef<NotifierImpl> getImpl(Notifier const& aNotifier) { return aNotifier.m_aImpl; }
+ };
+// ---------------------------------------------------------------------------------------------------
+
+ namespace
+ {
+ // -----------------------------------------------------------------------------------------------
+ template <class T>
+ struct LessORefBodyPtr
+ {
+ bool operator()(vos::ORef<T> const& lhs, vos::ORef<T> const& rhs) const
+ {
+ return ptr_less(lhs.getBodyPtr(), rhs.getBodyPtr());
+ }
+
+ std::less<T*> ptr_less;
+ };
+ // -----------------------------------------------------------------------------------------------
+ class ApiTreeRef
+ {
+ ApiTreeImpl const* m_pApiTree;
+ uno::Reference<uno::XInterface> m_xKeepAlive;
+ public:
+ explicit ApiTreeRef(ApiTreeImpl const* _pApiTree = NULL)
+ : m_pApiTree(_pApiTree)
+ , m_xKeepAlive()
+ {
+ if (m_pApiTree) m_xKeepAlive = m_pApiTree->getUnoInstance();
+ }
+
+ bool is() const
+ {
+ OSL_ASSERT(!m_pApiTree == !m_xKeepAlive.is());
+ return m_pApiTree != NULL;
+ }
+
+ ApiTreeImpl const* get() const { return m_pApiTree; }
+ ApiTreeImpl const* operator->() const { return m_pApiTree; }
+
+ friend bool operator==(ApiTreeRef const& lhs,ApiTreeRef const& rhs)
+ { return lhs.m_pApiTree == rhs.m_pApiTree; }
+
+ friend bool operator!=(ApiTreeRef const& lhs,ApiTreeRef const& rhs)
+ { return lhs.m_pApiTree != rhs.m_pApiTree; }
+ };
+ // -----------------------------------------------------------------------------------------------
+ typedef std::map< vos::ORef<NotifierImpl>, ApiTreeRef, LessORefBodyPtr<NotifierImpl> > NotifierSet;
+ // -----------------------------------------------------------------------------------------------
+
+ }
+// ---------------------------------------------------------------------------------------------------
+// class Broadcaster::Impl
+// ---------------------------------------------------------------------------------------------------
+ class Broadcaster::Impl : public vos::OReference
+ {
+ private:
+ NotifierSet::value_type m_aNotifierData;
+ public:
+ Impl(NotifierSet::value_type const& aNotifierData) : m_aNotifierData(aNotifierData) {}
+
+ NotifierSet::value_type getNotifierData() const { return m_aNotifierData; }
+
+ bool translateChanges(configuration::NodeChangesInformation& aInfos, configuration::NodeChanges const& aChanges, bool bSingleBase) const;
+ bool translateChanges(configuration::NodeChangesInformation& aInfos, configuration::NodeChangesInformation const& aChanges, bool bSingleBase) const;
+
+ void queryConstraints(configuration::NodeChangesInformation const& aChanges) { this->doQueryConstraints(aChanges); }
+ void notifyListeners(configuration::NodeChangesInformation const& aChanges) { this->doNotifyListeners(aChanges); }
+
+ void notifyRootListeners(configuration::NodeChangesInformation const& aChanges);
+
+ static vos::ORef<Impl> create(vos::ORef<NotifierImpl> const& rNotifierImpl, ApiTreeRef const& pTreeImpl, configuration::NodeChange const& aChange, bool bLocal);
+ static vos::ORef<Impl> create(vos::ORef<NotifierImpl> const& rNotifierImpl, ApiTreeRef const& pTreeImpl, configuration::NodeChanges const& aChange, bool bLocal);
+ static vos::ORef<Impl> create(vos::ORef<NotifierImpl> const& rNotifierImpl, ApiTreeRef const& pTreeImpl, configuration::NodeChangeInformation const& aChange, bool bLocal);
+ static vos::ORef<Impl> create(vos::ORef<NotifierImpl> const& rNotifierImpl, ApiTreeRef const& pTreeImpl, configuration::NodeChangesInformation const& aChange, bool bLocal);
+
+ private:
+ virtual void doQueryConstraints(configuration::NodeChangesInformation const& aChanges) = 0;
+ virtual void doNotifyListeners(configuration::NodeChangesInformation const& aChanges) = 0;
+ };
+// ---------------------------------------------------------------------------------------------------
+ namespace
+ {
+ // -----------------------------------------------------------------------------------------------
+
+ class EmptyBroadcaster_Impl : public Broadcaster::Impl
+ {
+ EmptyBroadcaster_Impl(NotifierSet::value_type const& rNotifierData)
+ : Broadcaster::Impl(rNotifierData)
+ {
+ }
+ public:
+ static
+ vos::ORef< Broadcaster::Impl > create(NotifierSet::value_type const& rRootNotifier)
+ {
+ return new EmptyBroadcaster_Impl(rRootNotifier);
+ }
+ private:
+ virtual void doQueryConstraints(configuration::NodeChangesInformation const& aChanges);
+ virtual void doNotifyListeners(configuration::NodeChangesInformation const& aChanges);
+ };
+
+ void EmptyBroadcaster_Impl::doQueryConstraints(configuration::NodeChangesInformation const&) {}
+ void EmptyBroadcaster_Impl::doNotifyListeners(configuration::NodeChangesInformation const&) {}
+ // -----------------------------------------------------------------------------------------------
+
+ class NodeLocalBroadcaster_Impl : public Broadcaster::Impl
+ {
+ configuration::NodeID aAffectedNode;
+
+ public:
+ NodeLocalBroadcaster_Impl(NotifierSet::value_type const& rTreeNotifierData, configuration::NodeID const& aAffectedID)
+ : Broadcaster::Impl(rTreeNotifierData)
+ , aAffectedNode(aAffectedID)
+ {
+ }
+
+ configuration::NodeID getAffectedNodeID() const { return aAffectedNode; }
+ unsigned int getNodeIndex() const { return aAffectedNode.toIndex(); }
+
+ protected:
+ void querySingleConstraint(configuration::NodeChangeInformation const& aChange, bool bMore);
+ void notifySingleChange(configuration::NodeChangeInformation const& aChange, bool bMore, css::beans::PropertyChangeEvent*& pCurEvent);
+ };
+ // -----------------------------------------------------------------------------------------------
+
+ class SingleChangeBroadcaster_Impl : public NodeLocalBroadcaster_Impl
+ {
+ configuration::SubNodeID m_aChangingValue;
+
+ SingleChangeBroadcaster_Impl(NotifierSet::value_type const& rTreeNotifierData, configuration::NodeID const& aAffectedID, configuration::SubNodeID const& aChangedValue);
+
+ public:
+ static
+ NodeLocalBroadcaster_Impl* create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeChangeLocation const& aChange);
+ static
+ NodeLocalBroadcaster_Impl* create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeID const& aAffectedID,
+ configuration::NodeChangeLocation const& aChange);
+ static
+ NodeLocalBroadcaster_Impl* create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeID const& aAffectedID,
+ configuration::SubNodeID const& aChangedNode,
+ configuration::NodeChangeLocation const& aChange);
+ private:
+ virtual void doQueryConstraints(configuration::NodeChangesInformation const& aChanges);
+ virtual void doNotifyListeners(configuration::NodeChangesInformation const& aChanges);
+ };
+
+ // -----------------------------------------------------------------------------------------------
+ class MultiChangeBroadcaster_Impl : public NodeLocalBroadcaster_Impl
+ {
+ std::set< configuration::SubNodeID > m_aChangingNodes;
+
+ MultiChangeBroadcaster_Impl(NotifierSet::value_type const& rTreeNotifierData, configuration::NodeID const& aAffectedID, std::set< configuration::SubNodeID >& aChangedNodes);
+
+ public:
+ static
+ NodeLocalBroadcaster_Impl* create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeChangesInformation const& aChanges);
+ static
+ NodeLocalBroadcaster_Impl* create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeID const& aAffectedID,
+ configuration::NodeChangesInformation const& aChanges);
+ private:
+ virtual void doQueryConstraints(configuration::NodeChangesInformation const& aChanges);
+ virtual void doNotifyListeners(configuration::NodeChangesInformation const& aChanges);
+ };
+ // -----------------------------------------------------------------------------------------------
+ class SingleTreeBroadcaster_Impl : public Broadcaster::Impl
+ {
+ std::vector< vos::ORef<NodeLocalBroadcaster_Impl> > m_aBroadcasters;
+
+ SingleTreeBroadcaster_Impl(NotifierSet::value_type const& rTreeNotifierData, std::vector< vos::ORef<NodeLocalBroadcaster_Impl> >& aBroadcasters);
+
+ public:
+ //--------------------------
+ static
+ vos::ORef< Broadcaster::Impl > create(
+ NotifierSet::value_type const& rRootNotifier,
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeChangesInformation const& aChanges);
+
+ static bool selectChanges(configuration::NodeChangesInformation& rSelected, configuration::NodeChangesInformation const& aOriginal, configuration::NodeID const& aSelector);
+ //--------------------------
+ private:
+ virtual void doQueryConstraints(configuration::NodeChangesInformation const& aChanges);
+ virtual void doNotifyListeners(configuration::NodeChangesInformation const& aChanges);
+ };
+ // -----------------------------------------------------------------------------------------------
+ class MultiTreeBroadcaster_Impl : public Broadcaster::Impl
+ {
+ std::vector< vos::ORef< Broadcaster::Impl > > m_aBroadcasters;
+
+ MultiTreeBroadcaster_Impl(NotifierSet::value_type const& rRootNotifierData, std::vector< vos::ORef< Broadcaster::Impl > >& aBroadcasters);
+ public:
+ //--------------------------
+ static
+ vos::ORef< Broadcaster::Impl > create(
+ NotifierSet::value_type const& rRootNotifier,
+ NotifierSet const& rNotifiers,
+ configuration::NodeChangesInformation const& aChanges);
+
+ static bool selectChanges(configuration::NodeChangesInformation& rSelected, configuration::NodeChangesInformation const& aOriginal, NotifierSet::value_type const& aSelector);
+ //--------------------------
+ private:
+ virtual void doQueryConstraints(configuration::NodeChangesInformation const& aChanges);
+ virtual void doNotifyListeners(configuration::NodeChangesInformation const& aChanges);
+ };
+
+ // -----------------------------------------------------------------------------------------------
+
+ inline configuration::NodeID makeRootID( rtl::Reference< configuration::Tree > const& aTree ) { return configuration::NodeID( aTree, aTree->getRootNode() ); }
+ inline configuration::NodeID makeRootID( ApiTreeRef const& pTreeImpl ) { return makeRootID( pTreeImpl->getTree() ); }
+ // -----------------------------------------------------------------------------------------------
+ NotifierSet::value_type findNotifier(configuration::NodeChangeLocation const& aChange, ApiTreeRef const& pTreeImpl)
+ {
+ OSL_ENSURE(aChange.isValidData(),"Invalid change location - cannot find notifier");
+
+ configuration::NodeID aAffectedNode = aChange.getAffectedNodeID();
+ if (aAffectedNode.isEmpty())
+ return NotifierSet::value_type();
+
+ ApiTreeRef aAffectedImpl( Factory::findDescendantTreeImpl(aAffectedNode, pTreeImpl.get()) );
+ if (aAffectedImpl.is())
+ {
+ vos::ORef<NotifierImpl> aAffectedNotifier = BroadcasterHelper::getImpl(aAffectedImpl->getNotifier());
+
+ return NotifierSet::value_type(aAffectedNotifier, aAffectedImpl);
+ }
+ else
+ return NotifierSet::value_type();
+ }
+ // -----------------------------------------------------------------------------------------------
+ inline
+ NotifierSet::value_type findNotifier(configuration::NodeChangeInformation const& aChange, ApiTreeRef const& pTreeImpl)
+ {
+ return findNotifier(aChange.location,pTreeImpl);
+ }
+ // -----------------------------------------------------------------------------------------------
+
+ void findNotifiers(NotifierSet& aNotifiers, configuration::NodeChangesInformation const& aChanges, ApiTreeRef const& pTreeImpl )
+ {
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin(); it != aChanges.end(); ++it)
+ {
+ NotifierSet::value_type aNotifierData( findNotifier(*it,pTreeImpl) );
+
+ if (aNotifierData.first.isValid())
+ {
+ aNotifiers.insert( aNotifierData );
+ OSL_ENSURE( aNotifiers[aNotifierData.first] == aNotifierData.second, "Different Api Trees for the same notifier" );
+ }
+ }
+ }
+ // -----------------------------------------------------------------------------------------------
+ // NodeLocalBroadcaster_Impl
+ // -----------------------------------------------------------------------------------------------
+ void NodeLocalBroadcaster_Impl::querySingleConstraint(configuration::NodeChangeInformation const& aChange, bool bMore)
+ {
+ uno::Reference< css::beans::XVetoableChangeListener > const * const SelectListener = 0;
+
+ vos::ORef<NotifierImpl> pNotifierImpl = getNotifierData().first;
+
+ cppu::OInterfaceContainerHelper* pListeners = pNotifierImpl->m_aListeners.getContainer( getNodeIndex(), getCppuType(SelectListener) );
+ cppu::OInterfaceContainerHelper* pSpecial = pNotifierImpl->m_aListeners.getSpecialContainer( aChange.location.getChangingValueID() );
+
+ if (pSpecial || pListeners)
+ {
+ css::beans::PropertyChangeEvent aEvent;
+ aEvent.Source = pNotifierImpl->m_aListeners.getObjectAt( getNodeIndex() );
+
+ if (configapi::fillEventDataFromResolved(aEvent,aChange,bMore))
+ {
+ // Catch only RuntimeExceptions here: vetoableChange issues its veto by throwing
+ // a PropertyVetoException (which is not a RuntimeException)
+ if (pListeners)
+ {
+ ListenerContainerIterator< css::beans::XVetoableChangeListener > aIterator(*pListeners);
+
+ UnoApiLockReleaser aGuardReleaser;
+ while (aIterator.hasMoreElements())
+ try
+ {
+ aIterator.next()->vetoableChange(aEvent);
+ }
+ catch (uno::RuntimeException & )
+ {}
+ }
+ if (pSpecial)
+ {
+ ListenerContainerIterator< css::beans::XVetoableChangeListener > aIterator(*pSpecial);
+
+ UnoApiLockReleaser aGuardReleaser;
+ while (aIterator.hasMoreElements())
+ try
+ {
+ aIterator.next()->vetoableChange(aEvent);
+ }
+ catch (uno::RuntimeException & )
+ {}
+ }
+ }
+ }
+
+ }
+ // -----------------------------------------------------------------------------------------------
+ void NodeLocalBroadcaster_Impl::notifySingleChange(configuration::NodeChangeInformation const& aChange, bool bMore, css::beans::PropertyChangeEvent*& pCurEvent)
+ {
+ uno::Reference< css::beans::XPropertyChangeListener > const * const SelectPropertyListener = 0;
+ uno::Reference< css::container::XContainerListener > const * const SelectContainerListener = 0;
+
+ vos::ORef<NotifierImpl> pNotifierImpl = getNotifierData().first;
+
+ cppu::OInterfaceContainerHelper* pContainerListeners = pNotifierImpl->m_aListeners.getContainer( getNodeIndex(), getCppuType(SelectContainerListener) );
+
+ if (pContainerListeners)
+ {
+ css::container::ContainerEvent aEvent;
+ aEvent.Source = pNotifierImpl->m_aListeners.getObjectAt( getNodeIndex() );
+
+ if (configapi::fillEventDataFromResolved(aEvent,aChange))
+ {
+
+ ListenerContainerIterator< css::container::XContainerListener > aIterator(*pContainerListeners);
+
+ UnoApiLockReleaser aGuardReleaser;
+ while (aIterator.hasMoreElements())
+ try
+ {
+ uno::Reference<css::container::XContainerListener> xListener( aIterator.next() );
+ OSL_ASSERT( xListener.is() );
+
+ switch (aChange.change.type)
+ {
+ case configuration::NodeChangeData::eSetValue:
+ case configuration::NodeChangeData::eSetDefault:
+ case configuration::NodeChangeData::eReplaceElement:
+ xListener->elementReplaced(aEvent);
+ break;
+
+ case configuration::NodeChangeData::eInsertElement:
+ xListener->elementInserted(aEvent);
+ break;
+
+ case configuration::NodeChangeData::eRemoveElement:
+ xListener->elementRemoved(aEvent);
+ break;
+
+
+ case configuration::NodeChangeData::eResetSetDefault:
+ case configuration::NodeChangeData::eRenameElementTree:
+ case configuration::NodeChangeData::eNoChange:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+ catch (uno::Exception &)
+ {}
+ }
+ }
+
+
+ OSL_ASSERT(pCurEvent);
+ css::beans::PropertyChangeEvent& rEvent = *pCurEvent;
+
+ rEvent.Source = pNotifierImpl->m_aListeners.getObjectAt( getNodeIndex() );
+
+ if (configapi::fillEventDataFromResolved(rEvent,aChange,bMore))
+ {
+ cppu::OInterfaceContainerHelper* pPropertyListeners = pNotifierImpl->m_aListeners.getContainer( getNodeIndex(), getCppuType(SelectPropertyListener) );
+ if (pPropertyListeners)
+ {
+ ListenerContainerIterator< css::beans::XPropertyChangeListener > aIterator(*pPropertyListeners);
+ UnoApiLockReleaser aGuardReleaser;
+ while (aIterator.hasMoreElements())
+ try { aIterator.next()->propertyChange(rEvent); } catch (uno::Exception & ) {}
+ }
+
+ cppu::OInterfaceContainerHelper* pSpecialListeners = pNotifierImpl->m_aListeners.getSpecialContainer( aChange.location.getChangingValueID() );
+ if (pSpecialListeners)
+ {
+ ListenerContainerIterator< css::beans::XPropertyChangeListener > aIterator(*pSpecialListeners);
+ UnoApiLockReleaser aGuardReleaser;
+ while (aIterator.hasMoreElements())
+ try { aIterator.next()->propertyChange(rEvent); } catch (uno::Exception & ) {}
+ }
+
+ ++pCurEvent;
+ }
+
+ }
+ // -----------------------------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------------------------
+ // SingleBroadcaster_Impl
+ // -----------------------------------------------------------------------------------------------
+ SingleChangeBroadcaster_Impl::SingleChangeBroadcaster_Impl(
+ NotifierSet::value_type const& rTreeNotifierData,
+ configuration::NodeID const& aAffectedID, configuration::SubNodeID const& aChangedNode
+ )
+ : NodeLocalBroadcaster_Impl(rTreeNotifierData,aAffectedID)
+ , m_aChangingValue(aChangedNode)
+ {
+ }
+ // -----------------------------------------------------------------------------------------------
+ NodeLocalBroadcaster_Impl* SingleChangeBroadcaster_Impl::create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeChangeLocation const& aChange)
+ {
+ OSL_ENSURE(rLocalNotifier.second->getTree() == aChange.getAffectedTreeRef(),
+ "ERROR: Tree Mismatch creating Single Broadcaster");
+
+ OSL_ENSURE(aChange.isValidData(), "ERROR: Invalid Change Location for Broadcaster");
+
+ configuration::NodeID aAffectedNodeID = aChange.getAffectedNodeID();
+ if (aAffectedNodeID.isEmpty())
+ return 0;
+
+ return create(rLocalNotifier,aAffectedNodeID,aChange.getChangingValueID(),aChange);
+ }
+ // -----------------------------------------------------------------------------------------------
+ NodeLocalBroadcaster_Impl* SingleChangeBroadcaster_Impl::create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeID const& aAffectedID,
+ configuration::NodeChangeLocation const& aChange)
+ {
+
+ return create(rLocalNotifier,aAffectedID,aChange.getChangingValueID(),aChange);
+ }
+ // -----------------------------------------------------------------------------------------------
+ NodeLocalBroadcaster_Impl* SingleChangeBroadcaster_Impl::create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeID const& aAffectedID,
+ configuration::SubNodeID const& aChangedNodeID,
+ configuration::NodeChangeLocation const& aChange)
+ {
+ { (void)aChange; }
+ OSL_ENSURE(aChange.isValidData(), "ERROR: Invalid Change Location for Broadcaster");
+ OSL_ENSURE(aAffectedID.isValidNode(),"Cannot broadcast without affected node");
+
+ OSL_ENSURE(rLocalNotifier.second->getTree() == aChange.getAffectedTreeRef(),
+ "ERROR: Tree Mismatch creating Single Broadcaster");
+ OSL_ENSURE( aChange.getAffectedNodeID() == aAffectedID,
+ "ERROR: Node Mismatch creating Single Broadcaster");
+ OSL_ENSURE( aChange.getChangingValueID() == aChangedNodeID,
+ "ERROR: Value Node Mismatch creating Single Broadcaster");
+
+ return new SingleChangeBroadcaster_Impl(rLocalNotifier,aAffectedID,aChangedNodeID);
+ }
+ // -----------------------------------------------------------------------------------------------
+ void SingleChangeBroadcaster_Impl::doQueryConstraints(configuration::NodeChangesInformation const& aChanges)
+ {
+ OSL_ASSERT(aChanges.size() <= 1);
+ if (!aChanges.empty())
+ {
+ std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin();
+
+ OSL_ENSURE( m_aChangingValue == it->location.getChangingValueID(), "Broadcasting unanticipated change");
+
+ querySingleConstraint(*it, false);
+ }
+
+ }
+ // -----------------------------------------------------------------------------------------------
+ void SingleChangeBroadcaster_Impl::doNotifyListeners(configuration::NodeChangesInformation const& aChanges)
+ {
+ OSL_ASSERT(aChanges.size() <= 1);
+ if (!aChanges.empty())
+ {
+ css::beans::PropertyChangeEvent aEvent;
+ css::beans::PropertyChangeEvent * pEventNext = &aEvent;
+
+ std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin();
+
+ OSL_ENSURE( m_aChangingValue == it->location.getChangingValueID(), "Broadcasting unanticipated change");
+
+ notifySingleChange(*it, false, pEventNext);
+
+ if (pEventNext != &aEvent)
+ {
+ uno::Sequence< css::beans::PropertyChangeEvent > aPropertyEvents(&aEvent,1);
+
+ uno::Reference< css::beans::XPropertiesChangeListener > const * const SelectListener = 0;
+
+ vos::ORef<NotifierImpl> pNotifierImpl = getNotifierData().first;
+
+ cppu::OInterfaceContainerHelper* pContainer = pNotifierImpl->m_aListeners.getContainer( getNodeIndex(), getCppuType(SelectListener) );
+
+ if (pContainer)
+ {
+ ListenerContainerIterator< css::beans::XPropertiesChangeListener > aIterator(*pContainer);
+ UnoApiLockReleaser aGuardReleaser;
+ while (aIterator.hasMoreElements())
+ try { aIterator.next()->propertiesChange(aPropertyEvents); } catch (uno::Exception & ) {}
+ }
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // MultiChangeBroadcaster_Impl
+ // -----------------------------------------------------------------------------------------------
+
+ MultiChangeBroadcaster_Impl::MultiChangeBroadcaster_Impl(
+ NotifierSet::value_type const& rTreeNotifierData,
+ configuration::NodeID const& aAffectedID, std::set< configuration::SubNodeID >& aChangedNodes
+ )
+ : NodeLocalBroadcaster_Impl(rTreeNotifierData,aAffectedID)
+ , m_aChangingNodes()
+ {
+ m_aChangingNodes.swap(aChangedNodes);
+ }
+ // -----------------------------------------------------------------------------------------------
+ NodeLocalBroadcaster_Impl* MultiChangeBroadcaster_Impl::create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeChangesInformation const& aChanges)
+ {
+ if (aChanges.empty())
+ return 0;
+
+ OSL_ENSURE(aChanges.begin()->hasValidLocation(), "ERROR: Invalid Change Location for Broadcaster");
+
+ configuration::NodeID aAffectedNodeID = aChanges.begin()->location.getAffectedNodeID();
+ if (aAffectedNodeID.isEmpty())
+ return 0;
+
+ return create(rLocalNotifier, aAffectedNodeID, aChanges);
+ }
+ // -----------------------------------------------------------------------------------------------
+ NodeLocalBroadcaster_Impl* MultiChangeBroadcaster_Impl::create(
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeID const& aAffectedNodeID,
+ configuration::NodeChangesInformation const& aChanges)
+ {
+ if (aChanges.empty())
+ return 0;
+
+ else if (aChanges.size() == 1)
+ return SingleChangeBroadcaster_Impl::create(rLocalNotifier,aAffectedNodeID,aChanges.begin()->location);
+
+ else
+ {
+ OSL_ENSURE(aAffectedNodeID.isValidNode(),"Cannot broadcast without affected node");
+
+ std::set< configuration::SubNodeID > aChangedNodes;
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin(); it != aChanges.end(); ++it)
+ {
+ OSL_ENSURE(it->hasValidLocation(), "ERROR: Invalid Change Location for Broadcaster");
+
+ OSL_ENSURE(it->location.getAffectedNodeID() == aAffectedNodeID, "ERROR: Change is not local to affected node (as advertised)");
+ OSL_ENSURE(rLocalNotifier.second->getTree() == it->location.getAffectedTreeRef(),
+ "ERROR: Tree Mismatch creating Multi Change Broadcaster");
+
+ configuration::SubNodeID aChangedValueID = it->location.getChangingValueID();
+
+ aChangedNodes.insert(aChangedValueID);
+ }
+ OSL_ENSURE(!aChangedNodes.empty(), "Changes don't affect any nodes");
+
+ if (aChangedNodes.size() == 1) OSL_TRACE("WARNING: Different changes all affect the same node !");
+
+ return new MultiChangeBroadcaster_Impl(rLocalNotifier, aAffectedNodeID, aChangedNodes);
+ }
+ }
+ // -----------------------------------------------------------------------------------------------
+ void MultiChangeBroadcaster_Impl::doQueryConstraints(configuration::NodeChangesInformation const& aChanges)
+ {
+ std::vector< configuration::NodeChangeInformation >::const_iterator const stop = aChanges.end(), last = stop-1;
+
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin(); it != stop; ++it)
+ {
+ OSL_ENSURE( m_aChangingNodes.find( it->location.getChangingValueID() ) != m_aChangingNodes.end(), "Broadcasting unanticipated change");
+
+ querySingleConstraint(*it, it != last);
+ }
+
+ }
+ // -----------------------------------------------------------------------------------------------
+ void MultiChangeBroadcaster_Impl::doNotifyListeners(configuration::NodeChangesInformation const& aChanges)
+ {
+ uno::Sequence< css::beans::PropertyChangeEvent > aPropertyEvents(aChanges.size());
+
+ css::beans::PropertyChangeEvent * const pEventStart = aPropertyEvents.getArray();
+ css::beans::PropertyChangeEvent * pEventNext = pEventStart;
+
+ std::vector< configuration::NodeChangeInformation >::const_iterator const stop = aChanges.end(), last = stop-1;
+
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin(); it != stop; ++it)
+ {
+ // #92463# Skip nodes that are not in the tree
+ if (it->location.getAffectedNodeID().isEmpty()) continue;
+
+ OSL_ENSURE( m_aChangingNodes.find( it->location.getChangingValueID() ) != m_aChangingNodes.end(), "Broadcasting unanticipated change");
+
+ notifySingleChange(*it, it != last, pEventNext);
+ }
+
+ sal_Int32 nPropertyEvents = pEventNext-pEventStart;
+
+ if (nPropertyEvents > 0)
+ {
+ OSL_ASSERT(nPropertyEvents <= aPropertyEvents.getLength());
+ if (nPropertyEvents != aPropertyEvents.getLength())
+ aPropertyEvents.realloc(nPropertyEvents);
+
+ uno::Reference< css::beans::XPropertiesChangeListener > const * const SelectListener = 0;
+
+ vos::ORef<NotifierImpl> pNotifierImpl = getNotifierData().first;
+
+ cppu::OInterfaceContainerHelper* pContainer = pNotifierImpl->m_aListeners.getContainer( getNodeIndex(), getCppuType(SelectListener) );
+
+ if (pContainer)
+ {
+ ListenerContainerIterator< css::beans::XPropertiesChangeListener > aIterator(*pContainer);
+ UnoApiLockReleaser aGuardReleaser;
+ while (aIterator.hasMoreElements())
+ try { aIterator.next()->propertiesChange(aPropertyEvents); } catch (uno::Exception & ) {}
+ }
+ }
+ }
+ // -----------------------------------------------------------------------------------------------
+ // TreeLocalBroadcaster_Impl
+ // -----------------------------------------------------------------------------------------------
+
+ SingleTreeBroadcaster_Impl::SingleTreeBroadcaster_Impl(
+ NotifierSet::value_type const& aTreeNotifierData,
+ std::vector< vos::ORef<NodeLocalBroadcaster_Impl> >& aBroadcasters
+ )
+ : Broadcaster::Impl(aTreeNotifierData)
+ , m_aBroadcasters()
+ {
+ m_aBroadcasters.swap(aBroadcasters);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ bool SingleTreeBroadcaster_Impl::selectChanges(configuration::NodeChangesInformation& rSelected, configuration::NodeChangesInformation const& aOriginal, configuration::NodeID const& aSelector)
+ {
+ OSL_ASSERT(rSelected.empty()); // nothing in there yet
+
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aOriginal.begin(); it != aOriginal.end(); ++it)
+ {
+ if ( it->location.getAffectedNodeID() == aSelector )
+ {
+ rSelected.push_back(*it);
+ }
+ }
+ return !rSelected.empty();
+ }
+ // -----------------------------------------------------------------------------------------------
+
+ vos::ORef< Broadcaster::Impl > SingleTreeBroadcaster_Impl::create(
+ NotifierSet::value_type const& rRootNotifier,
+ NotifierSet::value_type const& rLocalNotifier,
+ configuration::NodeChangesInformation const& aChanges)
+ {
+ std::set< configuration::NodeID > aNodes;
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator itChanges = aChanges.begin(); itChanges != aChanges.end(); ++itChanges)
+ {
+ OSL_ENSURE(itChanges->hasValidLocation(), "ERROR: Invalid Change Location for Broadcaster");
+
+ configuration::NodeID aAffectedNodeID = itChanges->location.getAffectedNodeID();
+ if (!aAffectedNodeID.isEmpty())
+ aNodes.insert(aAffectedNodeID);
+ }
+
+ std::vector< vos::ORef<NodeLocalBroadcaster_Impl> > aNodecasters;
+ for (std::set< configuration::NodeID >::const_iterator itNodes = aNodes.begin(); itNodes != aNodes.end(); ++itNodes)
+ {
+ OSL_ASSERT(itNodes->isValidNode()); // filtered empty ones above
+
+ configuration::NodeChangesInformation aSelectedChanges;
+ if ( selectChanges(aSelectedChanges, aChanges, *itNodes))
+ {
+ NodeLocalBroadcaster_Impl* pSelectedImpl = MultiChangeBroadcaster_Impl::create(rLocalNotifier, *itNodes, aSelectedChanges);
+ if (pSelectedImpl)
+ aNodecasters.push_back(pSelectedImpl);
+ }
+ }
+
+ if (aNodecasters.empty())
+ return 0;
+
+ else if (aNodecasters.size() == 1)
+ return aNodecasters.begin()->getBodyPtr();
+
+ else
+ return new SingleTreeBroadcaster_Impl(rRootNotifier, aNodecasters);
+ }
+ // -----------------------------------------------------------------------------------------------
+ void SingleTreeBroadcaster_Impl::doQueryConstraints(configuration::NodeChangesInformation const& aChanges)
+ {
+ for(std::vector< vos::ORef<NodeLocalBroadcaster_Impl> >::iterator it = m_aBroadcasters.begin(); it != m_aBroadcasters.end(); ++it)
+ {
+ configuration::NodeChangesInformation aSelectedInfos;
+ if ( selectChanges(aSelectedInfos, aChanges, (*it)->getAffectedNodeID()) )
+ (*it)->queryConstraints(aSelectedInfos);
+ }
+ }
+ // -----------------------------------------------------------------------------------------------
+ void SingleTreeBroadcaster_Impl::doNotifyListeners(configuration::NodeChangesInformation const& aChanges)
+ {
+ for(std::vector< vos::ORef<NodeLocalBroadcaster_Impl> >::iterator it = m_aBroadcasters.begin(); it != m_aBroadcasters.end(); ++it)
+ {
+ configuration::NodeChangesInformation aSelectedInfos;
+ if ( selectChanges(aSelectedInfos, aChanges, (*it)->getAffectedNodeID()) )
+ (*it)->notifyListeners(aSelectedInfos);
+ }
+ }
+ // -----------------------------------------------------------------------------------------------
+ // MultiTreeBroadcaster_Impl
+ // -----------------------------------------------------------------------------------------------
+ MultiTreeBroadcaster_Impl::MultiTreeBroadcaster_Impl(NotifierSet::value_type const& aRootSelector, std::vector< vos::ORef< Broadcaster::Impl > >& aBroadcasters)
+ : Broadcaster::Impl(aRootSelector)
+ , m_aBroadcasters()
+ {
+ m_aBroadcasters.swap(aBroadcasters);
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ bool MultiTreeBroadcaster_Impl::selectChanges(configuration::NodeChangesInformation& rSelected, configuration::NodeChangesInformation const& aOriginal, NotifierSet::value_type const& aSelector)
+ {
+ OSL_ASSERT(aSelector.first.isValid());
+ OSL_ASSERT(aSelector.second.is());
+
+ OSL_ASSERT(rSelected.empty()); // nothing in there yet
+
+ rtl::Reference< configuration::Tree > const aSelectedTree( aSelector.second->getTree() );
+
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aOriginal.begin(); it != aOriginal.end(); ++it)
+ {
+ if (it->location.getAffectedTreeRef() == aSelectedTree)
+ {
+ rSelected.push_back(*it);
+ }
+ }
+ return !rSelected.empty();
+ }
+ // -------------------------------------------------------------------------------------------
+
+ vos::ORef< Broadcaster::Impl > MultiTreeBroadcaster_Impl::create(NotifierSet::value_type const& rRootNotifier, NotifierSet const& rNotifiers, configuration::NodeChangesInformation const& aChanges)
+ {
+ std::vector< vos::ORef< Broadcaster::Impl > > aTreecasters;
+ for (NotifierSet::const_iterator it = rNotifiers.begin(); it != rNotifiers.end(); ++it)
+ {
+ configuration::NodeChangesInformation aSelectedChanges;
+ if ( selectChanges(aSelectedChanges, aChanges, *it))
+ {
+ vos::ORef< Broadcaster::Impl > pSelectedImpl = SingleTreeBroadcaster_Impl::create(rRootNotifier, *it, aSelectedChanges);
+ if (pSelectedImpl.isValid())
+ aTreecasters.push_back(pSelectedImpl);
+ }
+ }
+
+ if (aTreecasters.empty())
+ return 0;
+
+ else if (aTreecasters.size() == 1)
+ return *aTreecasters.begin();
+
+ else
+ return new MultiTreeBroadcaster_Impl(rRootNotifier, aTreecasters);
+ }
+ // -------------------------------------------------------------------------------------------
+
+ void MultiTreeBroadcaster_Impl::doQueryConstraints(configuration::NodeChangesInformation const& aChanges)
+ {
+ for(std::vector< vos::ORef< Broadcaster::Impl > >::iterator it = m_aBroadcasters.begin(); it != m_aBroadcasters.end(); ++it)
+ {
+ configuration::NodeChangesInformation aSelectedInfos;
+ if ( selectChanges(aSelectedInfos, aChanges, (*it)->getNotifierData()) )
+ (*it)->queryConstraints(aSelectedInfos);
+ }
+ }
+ // -------------------------------------------------------------------------------------------
+
+ void MultiTreeBroadcaster_Impl::doNotifyListeners(configuration::NodeChangesInformation const& aChanges)
+ {
+ for(std::vector< vos::ORef< Broadcaster::Impl > >::iterator it = m_aBroadcasters.begin(); it != m_aBroadcasters.end(); ++it)
+ {
+ configuration::NodeChangesInformation aSelectedInfos;
+ if ( selectChanges(aSelectedInfos, aChanges, (*it)->getNotifierData()) )
+ (*it)->notifyListeners(aSelectedInfos);
+ }
+ }
+ // -----------------------------------------------------------------------------------------------
+ }
+// ---------------------------------------------------------------------------------------------------
+
+ vos::ORef< Broadcaster::Impl > Broadcaster::Impl::create(vos::ORef<NotifierImpl> const& rNotifierImpl, ApiTreeRef const& pTreeImpl, configuration::NodeChange const& aChange, bool bLocal)
+ {
+ OSL_ASSERT(pTreeImpl.is());
+
+ vos::ORef< Broadcaster::Impl > pRet;
+
+ configuration::NodeChangeLocation aLocation;
+ if (aChange.getChangeLocation(aLocation))
+ {
+ if (bLocal)
+ {
+ pRet = SingleChangeBroadcaster_Impl::create( NotifierSet::value_type(rNotifierImpl,pTreeImpl), aLocation);
+ }
+ else
+ {
+ NotifierSet::value_type aAffectedNotifier( findNotifier(aLocation, pTreeImpl) );
+ if (aAffectedNotifier.second.is()) // only if we found a notifier we are able to create a broadcaster (DG)
+ pRet = SingleChangeBroadcaster_Impl::create( aAffectedNotifier, aLocation);
+ }
+ }
+ else
+ {
+ OSL_ENSURE(false, "Invalid change location set in node change - cannot broadcast");
+ // can't create a matching change - must still create an empty one
+ }
+
+ if (pRet.isEmpty())
+ pRet = EmptyBroadcaster_Impl::create( NotifierSet::value_type(rNotifierImpl,pTreeImpl) );
+
+ return pRet;
+ }
+// ---------------------------------------------------------------------------------------------------
+
+ vos::ORef< Broadcaster::Impl > Broadcaster::Impl::create(vos::ORef<NotifierImpl> const& rNotifierImpl, ApiTreeRef const& pTreeImpl, configuration::NodeChanges const& aChanges, bool bLocal)
+ {
+ NotifierSet::value_type aRootData(rNotifierImpl, pTreeImpl);
+
+ configuration::NodeChangesInformation aChangeInfos;
+ if (aChanges.getChangesInfos(aChangeInfos))
+ {
+ return create(rNotifierImpl,pTreeImpl,aChangeInfos,bLocal);
+ }
+ else
+ {
+ OSL_ENSURE(aChanges.isEmpty(), "Cannot get information for changes - cannot notify");
+
+ // make an empty one below
+ vos::ORef< Broadcaster::Impl > pRet = EmptyBroadcaster_Impl::create( aRootData );
+
+ return pRet;
+ }
+
+ }
+// ---------------------------------------------------------------------------------------------------
+
+ vos::ORef< Broadcaster::Impl > Broadcaster::Impl::create(vos::ORef<NotifierImpl> const& rNotifierImpl, ApiTreeRef const& pTreeImpl, configuration::NodeChangeInformation const& aChange, bool bLocal)
+ {
+ OSL_ASSERT(pTreeImpl.is());
+
+ vos::ORef< Broadcaster::Impl > pRet;
+
+ if (aChange.hasValidLocation())
+ {
+ if (bLocal)
+ {
+ pRet = SingleChangeBroadcaster_Impl::create( NotifierSet::value_type(rNotifierImpl,pTreeImpl), aChange.location);
+ }
+ else
+ {
+ NotifierSet::value_type aAffectedNotifier( findNotifier(aChange.location, pTreeImpl) );
+ if (aAffectedNotifier.second.is()) // only if we found a notifier we are able to create a broadcaster (DG)
+ pRet = SingleChangeBroadcaster_Impl::create( aAffectedNotifier, aChange.location);
+ }
+ }
+ else
+ {
+ OSL_ENSURE(false, "Invalid change location set in node change - cannot broadcast");
+ // can't create a matching change - must still create an empty one
+ }
+
+ if (pRet.isEmpty())
+ pRet = EmptyBroadcaster_Impl::create( NotifierSet::value_type(rNotifierImpl,pTreeImpl) );
+
+ return pRet;
+ }
+// ---------------------------------------------------------------------------------------------------
+
+ vos::ORef< Broadcaster::Impl > Broadcaster::Impl::create(vos::ORef<NotifierImpl> const& rNotifierImpl, ApiTreeRef const& pTreeImpl, configuration::NodeChangesInformation const& aChanges, bool bLocal)
+ {
+ vos::ORef< Broadcaster::Impl > pRet;
+
+ NotifierSet::value_type aRootData(rNotifierImpl, pTreeImpl);
+
+ if (aChanges.size() == 1)
+ {
+ pRet = create(rNotifierImpl, pTreeImpl, *aChanges.begin(), bLocal);
+ }
+ else if (bLocal)
+ {
+ pRet = MultiChangeBroadcaster_Impl::create( aRootData, aChanges);
+ }
+ else
+ {
+ NotifierSet aNotifiers;
+ findNotifiers( aNotifiers, aChanges, pTreeImpl);
+
+ if (aNotifiers.size() > 1)
+ {
+ pRet = MultiTreeBroadcaster_Impl::create(aRootData, aNotifiers, aChanges);
+ }
+ else if (!aNotifiers.empty())
+ {
+ pRet = SingleTreeBroadcaster_Impl::create(aRootData, *aNotifiers.begin(), aChanges);
+ }
+ // else: empty
+ }
+
+ if (pRet.isEmpty())
+ pRet = EmptyBroadcaster_Impl::create( aRootData );
+
+ return pRet;
+ }
+// ---------------------------------------------------------------------------------------------------
+
+ bool Broadcaster::Impl::translateChanges(configuration::NodeChangesInformation& _rInfos, configuration::NodeChanges const& aChanges, bool /*bSingleBase*/) const
+ {
+ rtl::Reference< configuration::Tree > aBaseTree = m_aNotifierData.second->getTree();
+ Factory& rFactory = m_aNotifierData.second->getFactory();
+
+ configuration::NodeChangesInformation aRawInfos;
+
+ sal_uInt32 nChanges = aChanges.getChangesInfos(aRawInfos);
+
+ OSL_ENSURE(nChanges, "Cannot get info(s) for change - skipping for notification");
+ OSL_ENSURE(nChanges == aRawInfos.size(), "Incorrect change count returned");
+
+ configuration::NodeChangesInformation aNewInfos;
+ aNewInfos.reserve(nChanges);
+
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator pos = aRawInfos.begin(); pos != aRawInfos.end(); ++pos)
+ {
+ configuration::NodeChangeInformation aInfo = *pos;
+ if( !configapi::rebaseChange(aInfo.location,aBaseTree) )
+ {
+ OSL_TRACE("Change is not within expected tree - skipping for notification");
+ continue;
+ }
+
+ OSL_ENSURE(!pos->isEmptyChange(), "Empty Change Found for Notification");
+ // it actually is expected that elements may not be found - thus ignoring result
+ configapi::resolveToUno(aInfo.change, rFactory);
+
+ aNewInfos.push_back( aInfo );
+ }
+
+ aNewInfos.swap(_rInfos);
+
+ return !_rInfos.empty();
+ }
+
+// ---------------------------------------------------------------------------------------------------
+
+ bool Broadcaster::Impl::translateChanges(configuration::NodeChangesInformation& aInfos, configuration::NodeChangesInformation const& aChanges, bool /*bSingleBase*/) const
+ {
+ configuration::NodeChangesInformation aNewInfos;
+ aNewInfos.reserve( aChanges.size() );
+
+ rtl::Reference< configuration::Tree > aBaseTree = m_aNotifierData.second->getTree();
+ Factory& rFactory = m_aNotifierData.second->getFactory();
+
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin(); it != aChanges.end(); ++it)
+ {
+ configuration::NodeChangeInformation aInfo(*it);
+ if( !configapi::rebaseChange(aInfo.location,aBaseTree) )
+ {
+ OSL_TRACE("Change is not within expected tree - skipping for notification");
+ continue;
+ }
+
+ if( !configapi::resolveToUno(aInfo.change,rFactory) )
+ {
+ // it actually is expected that elements may not be found
+ // OSL_TRACE("Cannot find affected elements of Change");
+ }
+
+ aNewInfos.push_back( aInfo );
+ }
+
+ aNewInfos.swap(aInfos);
+ return !aInfos.empty();
+ }
+
+// ---------------------------------------------------------------------------------------------------
+ void Broadcaster::Impl::notifyRootListeners(configuration::NodeChangesInformation const& aChanges)
+ {
+ if (aChanges.empty()) return;
+
+ ApiTreeRef pRootTree( m_aNotifierData.second->getRootTreeImpl() );
+ if (pRootTree.is())
+ {
+ vos::ORef<NotifierImpl> aRootNotifier = BroadcasterHelper::getImpl(pRootTree->getNotifier());
+ if (aRootNotifier.isValid())
+ {
+ uno::Reference< css::util::XChangesListener > const * const pSelect = 0;
+
+ configuration::NodeID aNotifiedNode = makeRootID( pRootTree );
+
+ if (cppu::OInterfaceContainerHelper* pContainer = aRootNotifier->m_aListeners.getContainer(aNotifiedNode.toIndex(), ::getCppuType(pSelect)) )
+ {
+ css::util::ChangesEvent aEvent;
+ aEvent.Source = pRootTree->getUnoInstance();
+
+ uno::Reference<uno::XInterface> xBaseInstance = m_aNotifierData.second->getUnoInstance();
+ aEvent.Base <<= xBaseInstance;
+
+ // translate and collect the changes
+ aEvent.Changes.realloc(aChanges.size());
+ css::util::ElementChange* pChange = aEvent.Changes.getArray();
+
+ for (std::vector< configuration::NodeChangeInformation >::const_iterator it = aChanges.begin(); it != aChanges.end(); ++it)
+ {
+ fillChangeFromResolved(*pChange, *it);
+ ++pChange;
+ }
+
+ // now notify
+ ListenerContainerIterator< css::util::XChangesListener > aIter(*pContainer);
+
+ UnoApiLockReleaser aGuardReleaser;
+ while (aIter.hasMoreElements())
+ try { aIter.next()->changesOccurred(aEvent); } catch (uno::Exception & ) {}
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------------------------------
+// class Broadcaster
+// ---------------------------------------------------------------------------------------------------
+Broadcaster::Broadcaster(Notifier const& aNotifier, configuration::NodeChange const& aChange, bool bLocal)
+: m_pImpl( Impl::create(aNotifier.m_aImpl,ApiTreeRef(aNotifier.m_pTree),aChange,bLocal) )
+{
+ OSL_ASSERT(m_pImpl.isValid());
+}
+// ---------------------------------------------------------------------------------------------------
+Broadcaster::Broadcaster(Notifier const& aNotifier, configuration::NodeChanges const& aChanges, bool bLocal)
+: m_pImpl( Impl::create(aNotifier.m_aImpl,ApiTreeRef(aNotifier.m_pTree),aChanges,bLocal) )
+{
+ OSL_ASSERT(m_pImpl.isValid());
+}
+// ---------------------------------------------------------------------------------------------------
+Broadcaster::Broadcaster(Notifier const& aNotifier, configuration::NodeChangesInformation const& aChanges, bool bLocal)
+: m_pImpl( Impl::create(aNotifier.m_aImpl,ApiTreeRef(aNotifier.m_pTree),aChanges,bLocal) )
+{
+ OSL_ASSERT(m_pImpl.isValid());
+}
+// ---------------------------------------------------------------------------------------------------
+
+Broadcaster::Broadcaster(Broadcaster const& aOther)
+: m_pImpl(aOther.m_pImpl)
+{
+ OSL_ASSERT(m_pImpl.isValid());
+}
+// ---------------------------------------------------------------------------------------------------
+
+Broadcaster::~Broadcaster()
+{
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Broadcaster::queryConstraints(configuration::NodeChange const& aChange) throw(beans::PropertyVetoException)
+{
+ OSL_ENSURE(aChange.isChange(),"Constraint query without a change !");
+
+ configuration::NodeChanges aChanges;
+ aChanges.add(aChange);
+ this->queryConstraints(aChanges,true);
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Broadcaster::queryConstraints(configuration::NodeChanges const& aChanges, bool bSingleBase) throw(beans::PropertyVetoException)
+{
+ OSL_ENSURE(!aChanges.isEmpty(),"Constraint query without a change !");
+
+ try
+ {
+ configuration::NodeChangesInformation aInfos;
+ if (m_pImpl->translateChanges(aInfos,aChanges,bSingleBase))
+ {
+ m_pImpl->queryConstraints(aInfos);
+ }
+ }
+ catch (beans::PropertyVetoException & )
+ {
+ throw;
+ }
+ catch (uno::Exception & )
+ {
+ OSL_ENSURE(false, "configmgr::Broadcaster: Unexpected UNO exception in notifyListeners");
+ }
+ catch (configuration::Exception & )
+ {
+ OSL_ENSURE(false, "configmgr::Broadcaster: Unexpected internal exception in notifyListeners");
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Broadcaster::notifyListeners(configuration::NodeChange const& aChange) throw()
+{
+ OSL_ENSURE(aChange.isChange(),"Notifying without a change !");
+
+ configuration::NodeChanges aChanges;
+ aChanges.add(aChange);
+ this->notifyListeners(aChanges, true);
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Broadcaster::notifyListeners(configuration::NodeChanges const& aChanges, bool bSingleBase) throw()
+{
+ OSL_ENSURE(!aChanges.isEmpty(),"Notifying without a change !");
+
+ try
+ {
+ configuration::NodeChangesInformation aInfos;
+ if (m_pImpl->translateChanges(aInfos,aChanges, bSingleBase))
+ {
+ m_pImpl->notifyListeners(aInfos);
+ m_pImpl->notifyRootListeners(aInfos);
+ }
+ }
+ catch (uno::Exception & )
+ {
+ OSL_ENSURE(false, "configmgr::Broadcaster: Unexpected UNO exception in notifyListeners");
+ }
+ catch (configuration::Exception & )
+ {
+ OSL_ENSURE(false, "configmgr::Broadcaster: Unexpected internal exception in notifyListeners");
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Broadcaster::notifyListeners(configuration::NodeChangesInformation const& aChanges, bool bSingleBase) throw()
+{
+ OSL_ENSURE(!aChanges.empty(),"Notifying without a change !");
+
+ try
+ {
+ configuration::NodeChangesInformation aInfos;
+ if (m_pImpl->translateChanges(aInfos,aChanges, bSingleBase))
+ {
+ m_pImpl->notifyListeners(aInfos);
+ m_pImpl->notifyRootListeners(aInfos);
+ }
+ }
+ catch (uno::Exception & )
+ {
+ OSL_ENSURE(false, "configmgr::Broadcaster: Unexpected UNO exception in notifyListeners");
+ }
+ catch (configuration::Exception & )
+ {
+ OSL_ENSURE(false, "configmgr::Broadcaster: Unexpected internal exception in notifyListeners");
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/api2/broadcaster.hxx b/configmgr/source/api2/broadcaster.hxx
new file mode 100644
index 000000000000..07dfbeba1b1c
--- /dev/null
+++ b/configmgr/source/api2/broadcaster.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: broadcaster.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_BROADCASTER_HXX_
+#define CONFIGMGR_API_BROADCASTER_HXX_
+
+#include <com/sun/star/beans/PropertyVetoException.hpp>
+
+#include <vos/ref.hxx>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+// ---------------------------------------------------------------------------------------------------
+ class NodeChange;
+ class NodeChanges;
+ class NodeChangeInformation;
+ class NodeChangesInformation;
+ }
+// ---------------------------------------------------------------------------------------------------
+ namespace configapi
+ {
+ class Notifier;
+
+ namespace css = ::com::sun::star;
+// ---------------------------------------------------------------------------------------------------
+
+ /// broadcasts events for changes to a single config node or several sibling nodes
+ class Broadcaster
+ {
+ public:
+ /// construct a broadcaster
+ Broadcaster(Notifier const& aNotifier, configuration::NodeChange const& aChange, bool bLocal);
+ Broadcaster(Notifier const& aNotifier, configuration::NodeChanges const& aChanges, bool bLocal);
+ Broadcaster(Notifier const& aNotifier, configuration::NodeChangesInformation const& aChanges, bool bLocal);
+ Broadcaster(Broadcaster const& aOther);
+ ~Broadcaster();
+
+ /// give all property veto listeners on the affected node a chance to veto
+ void queryConstraints(configuration::NodeChange const& aChange) throw(css::beans::PropertyVetoException);
+ /// give all property veto listeners on any of the affected nodes a chance to veto
+ void queryConstraints(configuration::NodeChanges const& aChanges, bool bSingleBase = true) throw(css::beans::PropertyVetoException);
+
+ /// notify all listeners which are affected by this change
+ void notifyListeners(configuration::NodeChange const& aChange) throw();
+ /// notify all listeners which are affected by any of these changes (potentially from many different bases)
+ void notifyListeners(configuration::NodeChanges const& aChanges, bool bSingleBase) throw();
+ /// notify all listeners which are affected by any of these changes (potentially from many different bases)
+ void notifyListeners(configuration::NodeChangesInformation const& aChanges, bool bSingleBase = false) throw();
+
+ class Impl;
+ private:
+ vos::ORef<Impl> m_pImpl;
+ private:
+ void operator=(Broadcaster const& aOther);
+ };
+
+// ---------------------------------------------------------------------------------------------------
+
+ }
+}
+
+#endif // CONFIGMGR_API_BROADCASTER_HXX_
diff --git a/configmgr/source/api2/committer.cxx b/configmgr/source/api2/committer.cxx
new file mode 100644
index 000000000000..a108195ddf74
--- /dev/null
+++ b/configmgr/source/api2/committer.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: committer.cxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "committer.hxx"
+#include "apitreeimplobj.hxx"
+#include "providerimpl.hxx"
+#include "roottree.hxx"
+#include "treechangelist.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+namespace
+{
+ //-------------------------------------------------------------------------
+ struct NotifyDisabler
+ {
+ ApiRootTreeImpl& m_rTree;
+ bool m_bOldState;
+
+ NotifyDisabler(ApiRootTreeImpl& rTree)
+ : m_rTree(rTree)
+ , m_bOldState(rTree .enableNotification(false) )
+ {
+ }
+
+ ~NotifyDisabler()
+ {
+ m_rTree.enableNotification(m_bOldState);
+ }
+ };
+ //-------------------------------------------------------------------------
+}
+
+//-----------------------------------------------------------------------------
+// class Committer
+//-----------------------------------------------------------------------------
+
+Committer::Committer(ApiRootTreeImpl& rTree)
+: m_rTree(rTree)
+{}
+//-----------------------------------------------------------------------------
+
+OProviderImpl * Committer::getUpdateProvider()
+{
+ return &m_rTree.getApiTree().getProvider().getProviderImpl();
+}
+
+//-----------------------------------------------------------------------------
+void Committer::commit()
+{
+ ApiTreeImpl& rApiTree = m_rTree.getApiTree();
+
+ OSL_PRECOND(!m_rTree.getLocation().isRoot(),"INTERNAL ERROR: Empty location used.");
+ OSL_PRECOND(m_rTree.getOptions().isValid(),"INTERNAL ERROR: Invalid Options used.");
+
+ if (!m_rTree.getOptions().isValid()) return;
+
+ RequestOptions aOptions = m_rTree.getOptions()->getRequestOptions();
+
+ OProviderImpl * pUpdateProvider = getUpdateProvider();
+ OSL_ASSERT(pUpdateProvider);
+
+ rtl::Reference< configuration::Tree > aTree( rApiTree.getTree());
+ if (!aTree->hasChanges()) return;
+
+ TreeChangeList aChangeList(aOptions,
+ aTree->getRootPath(),
+ aTree->getAttributes(aTree->getRootNode()));
+
+ // now do the commit
+ configuration::CommitHelper aHelper(rApiTree.getTree());
+ if (aHelper.prepareCommit(aChangeList))
+ try
+ {
+ pUpdateProvider->updateTree(aChangeList);
+
+ aHelper.finishCommit(aChangeList);
+
+ NotifyDisabler aDisableNotify(m_rTree); // do not notify self
+ pUpdateProvider->saveAndNotifyUpdate(aChangeList);
+ }
+ catch(...)
+ {
+ // should be a special clean-up routine, but for now we just need a consistent state
+ try
+ {
+ aHelper.failedCommit(aChangeList);
+ }
+ catch(configuration::Exception&)
+ {
+ OSL_ENSURE(false, "Cleanup really should not throw");
+ }
+ throw;
+ }
+}
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/api2/committer.hxx b/configmgr/source/api2/committer.hxx
new file mode 100644
index 000000000000..1440a2358e8b
--- /dev/null
+++ b/configmgr/source/api2/committer.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: committer.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_COMMITTER_HXX_
+#define CONFIGMGR_API_COMMITTER_HXX_
+
+namespace configmgr
+{
+ class OProviderImpl;
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+
+ class ApiRootTreeImpl;
+//-----------------------------------------------------------------------------
+
+ /// allows to update values of a simple type within a <type>NodeRef</type> that refers to a Group
+ class Committer
+ {
+ ApiRootTreeImpl& m_rTree;
+ public:
+ Committer(ApiRootTreeImpl& rTree);
+
+ void commit();
+ private:
+ OProviderImpl * getUpdateProvider();
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_API_COMMITTER_HXX_
diff --git a/configmgr/source/api2/confignotifier.cxx b/configmgr/source/api2/confignotifier.cxx
new file mode 100644
index 000000000000..281924d1526f
--- /dev/null
+++ b/configmgr/source/api2/confignotifier.cxx
@@ -0,0 +1,246 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: confignotifier.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "confignotifier.hxx"
+
+#include "notifierimpl.hxx"
+#include "broadcaster.hxx"
+
+#include "noderef.hxx"
+#include "valueref.hxx"
+#include "nodechange.hxx"
+
+#include "apinodeaccess.hxx"
+#include "apitreeaccess.hxx"
+#include "apitreeimplobj.hxx"
+
+#include <set>
+#include <functional>
+
+namespace configmgr
+{
+ namespace configapi
+ {
+// ---------------------------------------------------------------------------------------------------
+// class Notifier (-Impl)
+// ---------------------------------------------------------------------------------------------------
+
+Notifier::Notifier(vos::ORef<NotifierImpl> const& aImpl,ApiTreeImpl const* pTree)
+: m_aImpl(aImpl)
+, m_pTree(pTree)
+{
+ OSL_ENSURE(aImpl.isValid(),"Invalid initialization of a Notifier: No impl");
+ OSL_ENSURE(pTree,"Invalid initialization of a Notifier: No tree");
+}
+// ---------------------------------------------------------------------------------------------------
+
+Notifier::Notifier(Notifier const& aOther)
+: m_aImpl(aOther.m_aImpl)
+, m_pTree(aOther.m_pTree)
+{
+}
+// ---------------------------------------------------------------------------------------------------
+
+Notifier::~Notifier()
+{
+}
+// ---------------------------------------------------------------------------------------------------
+
+Broadcaster Notifier::makeBroadcaster(configuration::NodeChange const& aChange, bool bLocal) const
+{
+ return Broadcaster(*this,aChange,bLocal);
+}
+// ---------------------------------------------------------------------------------------------------
+
+Broadcaster Notifier::makeBroadcaster(configuration::NodeChanges const& aChanges, bool bLocal) const
+{
+ OSL_ENSURE(!aChanges.isEmpty(),"Creating broadcaster for no changes");
+ return Broadcaster(*this,aChanges,bLocal);
+}
+// ---------------------------------------------------------------------------------------------------
+
+NotifierImpl::NotifierImpl(rtl::Reference< configuration::Tree > const& aTree)
+: m_aListeners(aTree->nodeCount(), SubNodeToIndex(aTree))
+{
+}
+// ---------------------------------------------------------------------------------------------------
+
+NotifierImpl::~NotifierImpl()
+{
+}
+
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::add(configuration::NodeRef const& aNode, uno::Reference< css::lang::XEventListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->add( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::add(configuration::NodeRef const& aNode, uno::Reference< css::container::XContainerListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->add( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::add(configuration::NodeRef const& aNode, uno::Reference< css::util::XChangesListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->add( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::addForAll(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->addForAll( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::addForOne(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener, rtl::OUString const& aName) const
+{
+ if (xListener.is())
+ m_aImpl->addNamed( configuration::SubNodeID(m_pTree->getTree(),aNode, aName), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::addForAll(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->addForAll( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::addForOne(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener, rtl::OUString const& aName) const
+{
+ if (xListener.is())
+ m_aImpl->addNamed( configuration::SubNodeID(m_pTree->getTree(),aNode, aName), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::add(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertiesChangeListener > const& xListener, uno::Sequence<rtl::OUString> const& aNames) const
+{
+ if (xListener.is())
+ {
+ if (aNames.getLength() > 0)
+ m_aImpl->add( configuration::NodeID(m_pTree->getTree(),aNode), xListener, aNames);
+ else
+ m_aImpl->add( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::remove(configuration::NodeRef const& aNode, uno::Reference< css::lang::XEventListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->remove( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::remove(configuration::NodeRef const& aNode, uno::Reference< css::container::XContainerListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->remove( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::remove(configuration::NodeRef const& aNode, uno::Reference< css::util::XChangesListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->remove( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::removeForAll(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->removeForAll( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::removeForOne(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener, rtl::OUString const& aName) const
+{
+ if (xListener.is())
+ m_aImpl->removeNamed( configuration::SubNodeID(m_pTree->getTree(),aNode, aName), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::removeForAll(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->removeForAll( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::removeForOne(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener, rtl::OUString const& aName) const
+{
+ if (xListener.is())
+ m_aImpl->removeNamed( configuration::SubNodeID(m_pTree->getTree(),aNode, aName), xListener );
+}
+// ---------------------------------------------------------------------------------------------------
+
+void Notifier::remove(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertiesChangeListener > const& xListener) const
+{
+ if (xListener.is())
+ m_aImpl->remove( configuration::NodeID(m_pTree->getTree(),aNode), xListener );
+}
+
+// ---------------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------------
+
+DisposeGuardImpl::DisposeGuardImpl(Notifier const&) throw()
+{
+}
+// ---------------------------------------------------------------------------------------------------
+DisposeGuardImpl::~DisposeGuardImpl() throw ()
+{
+}
+// ---------------------------------------------------------------------------------------------------
+GuardedNotifier::GuardedNotifier(NodeAccess& rNode) throw()
+: m_aNotifier(rNode.getNotifier())
+, m_aImpl(m_aNotifier)
+{
+}
+// ---------------------------------------------------------------------------------------------------
+
+DisposeGuard::DisposeGuard(NodeAccess& rNode) throw(css::lang::DisposedException)
+: m_aImpl(rNode.getNotifier())
+{
+ rNode.checkAlive();
+}
+// ---------------------------------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/api2/confignotifier.hxx b/configmgr/source/api2/confignotifier.hxx
new file mode 100644
index 000000000000..2c0507e7304c
--- /dev/null
+++ b/configmgr/source/api2/confignotifier.hxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: confignotifier.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGNOTIFIER_HXX_
+#define CONFIGMGR_CONFIGNOTIFIER_HXX_
+
+#include "configexcept.hxx"
+#include "configpath.hxx"
+#include "datalock.hxx"
+#include "utility.hxx"
+#include <boost/utility.hpp>
+#include <vos/ref.hxx>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace beans
+ {
+ class XPropertyChangeListener;
+ class XVetoableChangeListener;
+ class XPropertiesChangeListener;
+ class PropertyVetoException;
+ }
+ namespace lang
+ {
+ class XEventListener;
+ struct EventObject;
+ }
+ namespace container { class XContainerListener; }
+ namespace util { class XChangesListener; }
+ namespace uno { class RuntimeException; }
+} } }
+namespace osl { class Mutex; }
+
+namespace configmgr
+{
+ namespace configuration
+ {
+// ---------------------------------------------------------------------------------------------------
+ class NodeRef;
+ class ValueRef;
+ class NodeChange;
+ class NodeChanges;
+ }
+// ---------------------------------------------------------------------------------------------------
+ namespace configapi
+ {
+// ---------------------------------------------------------------------------------------------------
+ class Broadcaster;
+ class NotifierImpl;
+ class ApiTreeImpl;
+
+ namespace css = ::com::sun::star;
+// ---------------------------------------------------------------------------------------------------
+ /// manages collections of event listeners observing a config tree, thread-safe
+ class Notifier
+ {
+ friend class Broadcaster;
+ friend class BroadcasterHelper;
+ vos::ORef<NotifierImpl> m_aImpl;
+ ApiTreeImpl const*const m_pTree;
+ public:
+ /// construct this around the given Implementation, for the given tree
+ explicit Notifier(vos::ORef<NotifierImpl> const & aImpl, ApiTreeImpl const* pTree);
+ Notifier(Notifier const& aOther);
+ ~Notifier();
+
+ // ---------------------------------------------------------------------------------------------------
+ /// create a broadcaster for a single change (either local or (possibly) nested)
+ Broadcaster makeBroadcaster(configuration::NodeChange const& aChange, bool bLocal) const;
+ /// create a broadcaster for a collection of changes (either local or (possibly) nested)
+ Broadcaster makeBroadcaster(configuration::NodeChanges const& aChange, bool bLocal) const;
+
+ // ---------------------------------------------------------------------------------------------------
+ bool checkAlive(uno::XInterface* pObject) const throw(css::lang::DisposedException);
+
+ // ---------------------------------------------------------------------------------------------------
+ /// Add a <type scope='com::sun::star::lang'>XEventListener</type> observing <var>aNode</var>.
+ void add(configuration::NodeRef const& aNode, uno::Reference< css::lang::XEventListener > const& xListener) const;
+
+ /// Add a <type scope='com::sun::star::container'>XContainerListener</type> observing <var>aNode</var>.
+ void add(configuration::NodeRef const& aNode, uno::Reference< css::container::XContainerListener > const& xListener) const;
+
+ /// Add a <type scope='com::sun::star::util'>XChangesListener</type> observing <var>aNode</var> and its descendants.
+ void add(configuration::NodeRef const& aNode, uno::Reference< css::util::XChangesListener > const& xListener) const;
+
+ /// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing all children of <var>aNode</var>.
+ void addForAll(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const;
+ /// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing only the child named <var>aName</var> of <var>aNode</var>.
+ void addForOne(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener, rtl::OUString const& aName) const;
+ /// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining all children of <var>aNode</var>.
+ void addForAll(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
+ /// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining only the child named <var>aName</var> of <var>aNode</var>.
+ void addForOne(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener, rtl::OUString const& aName) const;
+
+ /** Add a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
+ observing the properties of <var>aNode</var> (optimally only those given by <var>aNames</var>.
+ */
+ void add(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertiesChangeListener > const& xListener, uno::Sequence<rtl::OUString> const& aNames) const;
+
+ // ---------------------------------------------------------------------------------------------------
+ /// Remove a <type scope='com::sun::star::lang'>XEventListener</type> observing <var>aNode</var>.
+ void remove(configuration::NodeRef const& aNode, uno::Reference< css::lang::XEventListener > const& xListener) const;
+
+ /// Remove a <type scope='com::sun::star::container'>XContainerListener</type> observing <var>aNode</var>.
+ void remove(configuration::NodeRef const& aNode, uno::Reference< css::container::XContainerListener > const& xListener) const;
+
+ /// Remove a <type scope='com::sun::star::util'>XChangesListener</type> observing <var>aNode</var> and its descendants.
+ void remove(configuration::NodeRef const& aNode, uno::Reference< css::util::XChangesListener > const& xListener) const;
+
+ /// Remove a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
+ void removeForAll(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener) const;
+ /// Remove a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing the child named <var>aName</var> of <var>aNode</var>.
+ void removeForOne(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener, rtl::OUString const& aName) const;
+ /// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void removeForAll(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
+ /// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining the child named <var>aName</var> of <var>aNode</var>.
+ void removeForOne(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener, rtl::OUString const& aName) const;
+
+ /// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void remove(configuration::NodeRef const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener) const;
+ /** Remove a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
+ observing any properties of <var>aNode</var>.
+ */
+ void remove(configuration::NodeRef const& aNode, uno::Reference< css::beans::XPropertiesChangeListener > const& xListener) const;
+ // ---------------------------------------------------------------------------------------------------
+ private:
+ void operator=(Notifier const& aOther);
+ };
+// ---------------------------------------------------------------------------------------------------
+
+// Thin Wrappers around Notifiers: Provide guarding and convenient access
+ // Guarding and locking implementations
+ class NodeAccess;
+ class TreeElement;
+
+ /// guards a NodeAccess; provides a simple lock for non-data access, does not check for disposed state
+ class DisposeGuardImpl: private boost::noncopyable
+ {
+ public:
+ DisposeGuardImpl(Notifier const& rNotifier) throw();
+ ~DisposeGuardImpl() throw ();
+ };
+
+ /// wraps a Notifier (from a node or tree); provides a simple lock for notifier access, does not check for disposed state
+ class GuardedNotifier
+ {
+ UnoApiLock m_aLock;
+ Notifier m_aNotifier;
+ DisposeGuardImpl m_aImpl;
+ public:
+ GuardedNotifier(NodeAccess& rNode) throw();
+ public:
+ Notifier const& get() const { return m_aNotifier; }
+
+ Notifier const& operator *() const { return get(); }
+ Notifier const* operator->() const { return &get(); }
+ };
+
+ /// guards a Node or Tree provides a simple lock for non-data access, does (!) check for disposed state
+ class DisposeGuard
+ {
+ DisposeGuardImpl m_aImpl;
+ UnoApiLock m_aLock;
+ public:
+ DisposeGuard(NodeAccess& rNode) throw(css::lang::DisposedException);
+ };
+
+// ---------------------------------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGNOTIFIER_HXX_
diff --git a/configmgr/source/api2/elementaccess.cxx b/configmgr/source/api2/elementaccess.cxx
new file mode 100644
index 000000000000..77188de1a6b5
--- /dev/null
+++ b/configmgr/source/api2/elementaccess.cxx
@@ -0,0 +1,489 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementaccess.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "elementaccess.hxx"
+
+#include "elementimpl.hxx"
+#include "apinotifierimpl.hxx"
+
+#include "apitreeaccess.hxx"
+
+//-----------------------------------------------------------------------------------
+namespace configmgr
+{
+//-----------------------------------------------------------------------------------
+
+ namespace uno = com::sun::star::uno;
+
+//-----------------------------------------------------------------------------------
+// XInterface (but not method queryInterface)
+//-----------------------------------------------------------------------------------
+
+// acuire doesn't really do anything but forward. OTOH it should always be overridden when release() is
+void SAL_CALL BasicInnerElement ::acquire() throw() { cppu::WeakImplHelper3< css::container::XChild, css::container::XNamed, css::lang::XServiceInfo >::acquire(); }
+void SAL_CALL BasicSetElement ::acquire() throw() { cppu::WeakImplHelper6< css::container::XChild, css::container::XNamed, css::lang::XComponent, css::lang::XServiceInfo, css::configuration::XTemplateInstance, css::lang::XUnoTunnel >::acquire(); }
+void SAL_CALL BasicRootElement ::acquire() throw() { cppu::WeakImplHelper5< css::container::XNamed, css::util::XChangesNotifier, css::lang::XComponent, css::lang::XServiceInfo, css::lang::XLocalizable >::acquire(); }
+void SAL_CALL BasicUpdateElement::acquire() throw() { cppu::WeakImplHelper6< css::container::XNamed, css::util::XChangesNotifier, css::lang::XComponent, css::lang::XServiceInfo, css::lang::XLocalizable, css::util::XChangesBatch >::acquire(); }
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicInnerElement::release() throw()
+{
+ // FIXME: this looks highly flaky wrt. weak-refs etc.
+ bool bLastRef = (1 == m_refCount);
+ if (bLastRef)
+ {
+ UnoApiLock::acquire();
+ configapi::implDisposeObject( getNodeAccess(), getElementClass() );
+ }
+ cppu::WeakImplHelper3< css::container::XChild, css::container::XNamed, css::lang::XServiceInfo >::release();
+ if (bLastRef)
+ UnoApiLock::release();
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicSetElement::release() throw()
+{
+ // FIXME: this looks highly flaky wrt. weak-refs etc.
+ bool bLastRef = (1 == m_refCount);
+ if (bLastRef)
+ {
+ UnoApiLock::acquire();
+ configapi::implDisposeObject( getNodeAccess(), getElementClass() );
+ }
+ cppu::WeakImplHelper6< css::container::XChild, css::container::XNamed, css::lang::XComponent, css::lang::XServiceInfo, css::configuration::XTemplateInstance, css::lang::XUnoTunnel >::release();
+ if (bLastRef)
+ UnoApiLock::release();
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicRootElement::release() throw()
+{
+ // FIXME: this looks highly flaky wrt. weak-refs etc.
+ bool bLastRef = (1 == m_refCount);
+ if (bLastRef)
+ {
+ UnoApiLock::acquire();
+ configapi::implDisposeObject( getNodeAccess(), getElementClass() );
+ }
+ cppu::WeakImplHelper5< css::container::XNamed, css::util::XChangesNotifier, css::lang::XComponent, css::lang::XServiceInfo, css::lang::XLocalizable >::release();
+ if (bLastRef)
+ UnoApiLock::release();
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::release() throw()
+{
+ // FIXME: this looks highly flaky wrt. weak-refs etc.
+ bool bLastRef = (1 == m_refCount);
+ if (bLastRef)
+ {
+ UnoApiLock::acquire();
+ configapi::implDisposeObject( getNodeAccess(), getElementClass() );
+ }
+ cppu::WeakImplHelper6< css::container::XNamed, css::util::XChangesNotifier, css::lang::XComponent, css::lang::XServiceInfo, css::lang::XLocalizable, css::util::XChangesBatch >::release();
+ if (bLastRef)
+ UnoApiLock::release();
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XTypeProvider (but not method getTypes)
+//-----------------------------------------------------------------------------------
+
+uno::Sequence<sal_Int8> SAL_CALL BasicInnerElement::getImplementationId( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetImplementationId( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Sequence<sal_Int8> SAL_CALL BasicSetElement::getImplementationId( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetImplementationId( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Sequence<sal_Int8> SAL_CALL BasicRootElement::getImplementationId( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetImplementationId( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Sequence<sal_Int8> SAL_CALL BasicUpdateElement::getImplementationId( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetImplementationId( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XChild (not for root elements)
+//-----------------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > SAL_CALL BasicInnerElement::getParent( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetParent( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > SAL_CALL BasicSetElement::getParent( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetParent( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+void SAL_CALL BasicInnerElement::setParent( const uno::Reference< uno::XInterface >& xParent )
+ throw(css::lang::NoSupportException, uno::RuntimeException)
+{
+ configapi::implSetParent( getNodeAccess(), getElementClass(), xParent );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicSetElement::setParent( const uno::Reference< uno::XInterface >& xParent )
+ throw(css::lang::NoSupportException, uno::RuntimeException)
+{
+ configapi::implSetParent( getNodeAccess(), getElementClass(), xParent );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XNamed
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicInnerElement::getName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetName( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicSetElement::getName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetName( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicRootElement::getName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetName( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicUpdateElement::getName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetName( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+void SAL_CALL BasicInnerElement::setName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ configapi::implSetName( getNodeAccess(), getElementClass(), aName );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicSetElement::setName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ configapi::implSetName( getNodeAccess(), getElementClass(), aName );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicRootElement::setName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ configapi::implSetName( getNodeAccess(), getElementClass(), aName );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::setName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ configapi::implSetName( getNodeAccess(), getElementClass(), aName );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XChangesNotifier
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicRootElement::addChangesListener( const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implAddListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::addChangesListener( const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implAddListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+void SAL_CALL BasicRootElement::removeChangesListener( const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::removeChangesListener( const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XComponent
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicSetElement::dispose( ) throw(uno::RuntimeException)
+{
+ configapi::implDispose( getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicRootElement::dispose( ) throw(uno::RuntimeException)
+{
+ configapi::implDispose( getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::dispose( ) throw(uno::RuntimeException)
+{
+ configapi::implDispose( getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+void SAL_CALL BasicSetElement::addEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implAddListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicRootElement::addEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implAddListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::addEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implAddListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+void SAL_CALL BasicSetElement::removeEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicRootElement::removeEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::removeEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNodeAccess(), xListener );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XServiceInfo
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicInnerElement::getImplementationName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetImplementationName( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicSetElement::getImplementationName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetImplementationName( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicRootElement::getImplementationName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetImplementationName( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicUpdateElement::getImplementationName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetImplementationName( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+sal_Bool SAL_CALL BasicInnerElement::supportsService( const rtl::OUString& ServiceName ) throw(uno::RuntimeException)
+{
+ return configapi::implSupportsService( getNodeAccess(), getElementClass(), ServiceName );
+}
+//-----------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL BasicSetElement::supportsService( const rtl::OUString& ServiceName ) throw(uno::RuntimeException)
+{
+ return configapi::implSupportsService( getNodeAccess(), getElementClass(), ServiceName );
+}
+//-----------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL BasicRootElement::supportsService( const rtl::OUString& ServiceName ) throw(uno::RuntimeException)
+{
+ return configapi::implSupportsService( getNodeAccess(), getElementClass(), ServiceName );
+}
+//-----------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL BasicUpdateElement::supportsService( const rtl::OUString& ServiceName ) throw(uno::RuntimeException)
+{
+ return configapi::implSupportsService( getNodeAccess(), getElementClass(), ServiceName );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+uno::Sequence< rtl::OUString > SAL_CALL BasicInnerElement::getSupportedServiceNames( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetSupportedServiceNames( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Sequence< rtl::OUString > SAL_CALL BasicSetElement::getSupportedServiceNames( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetSupportedServiceNames( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Sequence< rtl::OUString > SAL_CALL BasicRootElement::getSupportedServiceNames( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetSupportedServiceNames( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Sequence< rtl::OUString > SAL_CALL BasicUpdateElement::getSupportedServiceNames( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetSupportedServiceNames( getNodeAccess(), getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+// ONLY set elements
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XTemplateInstance
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicSetElement::getTemplateName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetTemplateName( getElementClass() );
+}
+
+//-----------------------------------------------------------------------------------
+// XUnoTunnel
+//-----------------------------------------------------------------------------------
+
+sal_Int64 SAL_CALL BasicSetElement::getSomething( const uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(uno::RuntimeException)
+{
+ return configapi::implGetSomething( getElementClass(), aIdentifier);
+}
+
+//-----------------------------------------------------------------------------------
+
+// ONLY root elements
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XLocalizable
+//-----------------------------------------------------------------------------------
+
+css::lang::Locale SAL_CALL BasicRootElement::getLocale( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetLocale( getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+css::lang::Locale SAL_CALL BasicUpdateElement::getLocale( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetLocale( getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+void SAL_CALL BasicRootElement::setLocale( const css::lang::Locale& eLocale ) throw(uno::RuntimeException)
+{
+ configapi::implSetLocale( getElementClass(), eLocale );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::setLocale( const css::lang::Locale& eLocale ) throw(uno::RuntimeException)
+{
+ configapi::implSetLocale( getElementClass(), eLocale );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// XChangesBatch (only on update root)
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateElement::commitChanges( ) throw(css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implCommitChanges( getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL BasicUpdateElement::hasPendingChanges( ) throw(uno::RuntimeException)
+{
+ return configapi::implHasPendingChanges( getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Sequence< css::util::ElementChange > SAL_CALL BasicUpdateElement::getPendingChanges( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetPendingChanges( getElementClass() );
+}
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/elementaccess.hxx b/configmgr/source/api2/elementaccess.hxx
new file mode 100644
index 000000000000..88f285f9b6e5
--- /dev/null
+++ b/configmgr/source/api2/elementaccess.hxx
@@ -0,0 +1,386 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementaccess.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_ELEMENTACCESS_HXX_
+#define CONFIGMGR_API_ELEMENTACCESS_HXX_
+
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/configuration/XTemplateInstance.hpp>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/implbase5.hxx>
+#include <cppuhelper/implbase6.hxx>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+ class NodeAccess;
+ class InnerElement;
+ class SetElement;
+ class RootElement;
+ class UpdateRootElement;
+ }
+//-----------------------------------------------------------------------------
+
+ /** implements the interfaces supported by a inner node
+ within the configuration tree that is a plain node (group member).
+ <p> Is an interface adapter around
+ <type scope='configmgr::configapi'>NodeAccess</type> and
+ <type scope='configmgr::configapi'>InnerElement</type>.</p>
+ */
+ class BasicInnerElement : public cppu::WeakImplHelper3< css::container::XChild, css::container::XNamed, css::lang::XServiceInfo >
+ {
+ protected:
+ // Destructors
+ virtual ~BasicInnerElement() {}
+
+ public:
+ // Interface methods
+ // XInterface ('dispose' management) - partial implementation
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider (from implhelper) - partial implementation
+ virtual uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId( )
+ throw(uno::RuntimeException);
+
+ // XChild
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ getParent( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL // not supported
+ setParent( const uno::Reference< uno::XInterface >& Parent )
+ throw(css::lang::NoSupportException, css::uno::RuntimeException);
+
+ // XNamed
+ virtual rtl::OUString SAL_CALL
+ getName( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL // not supported (! - missing exception)
+ setName( const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw(uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& ServiceName )
+ throw(uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw(uno::RuntimeException);
+
+ protected:
+ virtual configapi::InnerElement& getElementClass() = 0;
+ virtual configapi::NodeAccess& getNodeAccess() = 0;
+ };
+//-----------------------------------------------------------------------------
+
+ /** implements the interfaces supported by a node
+ within the configuration tree that is a set element (or floating free).
+ <p> Is an interface adapter around
+ <type scope='configmgr::configapi'>NodeAccess</type> and
+ <type scope='configmgr::configapi'>SetElement</type>.</p>
+ */
+ class BasicSetElement : public cppu::WeakImplHelper6< css::container::XChild, css::container::XNamed, css::lang::XComponent, css::lang::XServiceInfo, css::configuration::XTemplateInstance, css::lang::XUnoTunnel >
+ {
+ protected:
+ // Destructors
+ virtual ~BasicSetElement() {}
+
+ public:
+ // Interface methods
+ // XInterface ('dispose' management) - partial implementation
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider (from implhelper) - partial implementation
+ virtual uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId( )
+ throw(uno::RuntimeException);
+
+ // XChild
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ getParent( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL // currently not supported
+ setParent( const uno::Reference< uno::XInterface >& Parent )
+ throw(css::lang::NoSupportException, css::uno::RuntimeException);
+
+ // XNamed
+ virtual rtl::OUString SAL_CALL
+ getName( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL // generally not supported (! - missing exception)
+ setName( const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeEventListener( const uno::Reference< css::lang::XEventListener >& aListener )
+ throw(uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw(uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& ServiceName )
+ throw(uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw(uno::RuntimeException);
+
+ // XTemplateInstance
+ virtual rtl::OUString SAL_CALL
+ getTemplateName( )
+ throw(uno::RuntimeException);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL
+ getSomething( const uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(uno::RuntimeException);
+
+ protected:
+ virtual configapi::SetElement& getElementClass() = 0;
+ virtual configapi::NodeAccess& getNodeAccess() = 0;
+ };
+//-----------------------------------------------------------------------------
+
+ /** implements the interfaces supported by a node
+ within the configuration that is the root of a read-only access
+ <p> Is an interface adapter around
+ <type scope='configmgr::configapi'>NodeAccess</type> and
+ <type scope='configmgr::configapi'>SetElement</type>.</p>
+ */
+ class BasicRootElement : public cppu::WeakImplHelper5< css::container::XNamed, css::util::XChangesNotifier, css::lang::XComponent, css::lang::XServiceInfo, css::lang::XLocalizable >
+ {
+ protected:
+ // Destructors
+ virtual ~BasicRootElement() {}
+
+ public:
+ // Interface methods
+ // XInterface ('dispose' management) - partial implementation
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider (from implhelper) - partial implementation
+ virtual uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId( )
+ throw(uno::RuntimeException);
+
+ // XNamed
+ virtual rtl::OUString SAL_CALL
+ getName( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL // generally not supported (! - missing exception)
+ setName( const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XChangesNotifier
+ virtual void SAL_CALL
+ addChangesListener( const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeChangesListener( const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeEventListener( const uno::Reference< css::lang::XEventListener >& aListener )
+ throw(uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw(uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& ServiceName )
+ throw(uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw(uno::RuntimeException);
+
+ // XLocalizable
+ virtual css::lang::Locale SAL_CALL
+ getLocale( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL // maybe not supported (! - missing exception)
+ setLocale( const css::lang::Locale& eLocale )
+ throw(uno::RuntimeException);
+
+ protected:
+ virtual configapi::RootElement& getElementClass() = 0;
+ virtual configapi::NodeAccess& getNodeAccess() = 0;
+ };
+//-----------------------------------------------------------------------------
+
+ /** implements the interfaces supported by a node
+ within the configuration that is the root of an update access
+ <p> Is an interface adapter around
+ <type scope='configmgr::configapi'>NodeAccess</type> and
+ <type scope='configmgr::configapi'>SetElement</type>.</p>
+ */
+ class BasicUpdateElement : public cppu::WeakImplHelper6< css::container::XNamed, css::util::XChangesNotifier, css::lang::XComponent, css::lang::XServiceInfo, css::lang::XLocalizable, css::util::XChangesBatch >
+ {
+ protected:
+ // Destructors
+ virtual ~BasicUpdateElement() {}
+
+ public:
+ // Interface methods
+ // XInterface ('dispose' management) - partial implementation
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider (from implhelper) - partial implementation
+ virtual uno::Sequence<sal_Int8> SAL_CALL
+ getImplementationId( )
+ throw(uno::RuntimeException);
+
+ // XNamed
+ virtual rtl::OUString SAL_CALL
+ getName( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL // generally not supported (! - missing exception)
+ setName( const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XChangesNotifier
+ virtual void SAL_CALL
+ addChangesListener( const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeChangesListener( const uno::Reference< css::util::XChangesListener >& xListener )
+ throw(uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL
+ dispose( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addEventListener( const uno::Reference< css::lang::XEventListener >& xListener )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeEventListener( const uno::Reference< css::lang::XEventListener >& aListener )
+ throw(uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw(uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& ServiceName )
+ throw(uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw(uno::RuntimeException);
+
+ // XChangesBatch
+ virtual void SAL_CALL
+ commitChanges( )
+ throw(css::lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasPendingChanges( )
+ throw(uno::RuntimeException);
+
+ virtual uno::Sequence< css::util::ElementChange > SAL_CALL
+ getPendingChanges( )
+ throw(uno::RuntimeException);
+
+ // XLocalizable
+ virtual css::lang::Locale SAL_CALL
+ getLocale( )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL // maybe not supported (! - missing exception)
+ setLocale( const css::lang::Locale& eLocale )
+ throw(uno::RuntimeException);
+
+ protected:
+ virtual configapi::UpdateRootElement& getElementClass() = 0;
+ virtual configapi::NodeAccess& getNodeAccess() = 0;
+ };
+//-----------------------------------------------------------------------------
+}
+#endif // CONFIGMGR_API_ELEMENTACCESS_HXX_
+
+
diff --git a/configmgr/source/api2/elementimpl.cxx b/configmgr/source/api2/elementimpl.cxx
new file mode 100644
index 000000000000..e8cf6c926e64
--- /dev/null
+++ b/configmgr/source/api2/elementimpl.cxx
@@ -0,0 +1,591 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementimpl.cxx,v $
+ * $Revision: 1.17.14.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "elementimpl.hxx"
+#include "apitreeaccess.hxx"
+#include "apinodeaccess.hxx"
+#include "apifactory.hxx"
+#include "noderef.hxx"
+#include "nodechange.hxx"
+#include "nodechangeinfo.hxx"
+#include "translatechanges.hxx"
+#include "apitypes.hxx"
+#include "configset.hxx"
+#include "confignotifier.hxx"
+#include "confsvccomponent.hxx"
+#include "committer.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/configuration/XTemplateContainer.hpp>
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------------
+ namespace lang = css::lang;
+ namespace util = css::util;
+
+//-----------------------------------------------------------------------------------
+
+// Interface methods
+//-----------------------------------------------------------------------------------
+
+// XChild
+//-----------------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > implGetParent(NodeAccess& rNode, InnerElement&) throw(uno::RuntimeException)
+{
+ uno::Reference<uno::XInterface> xRet;
+
+ try
+ {
+ GuardedNodeData<NodeAccess> impl( rNode ); // no provider lock needed - tree must be prebuilt already
+
+ rtl::Reference< configuration::Tree > aTree(impl.getTree());
+ configuration::NodeRef aParentNode = aTree->getParent(impl.getNode());
+
+ uno::Any aAny = configapi::makeInnerElement( rNode.getFactory(), aTree, aParentNode );
+
+ if (!(aAny >>= xRet)) // no parent available
+ {
+ OSL_ASSERT(!xRet.is()); // make sure we return NULL
+ OSL_ENSURE(!aAny.hasValue(), "configmgr: BasicElement::getParent: could not extract parent - node is not an object");
+ }
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return xRet;
+}
+
+//-----------------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > implGetParent(NodeAccess& rNode, SetElement& /*rElement*/) throw(uno::RuntimeException)
+{
+ uno::Reference<uno::XInterface> xRet;
+
+ try
+ {
+ // assume shared lock for connected trees
+ GuardedNodeData<NodeAccess> impl( rNode ); // no provider lock needed - tree must be prebuilt already
+
+ rtl::Reference< configuration::Tree > aTree(impl.getTree());
+
+ rtl::Reference< configuration::Tree > aParentTree( aTree->getContextTree() );
+
+ if (!configuration::isEmpty(aParentTree.get()))
+ {
+ configuration::NodeRef aParentNode( aTree->getContextNodeRef() );
+
+ // assume shared factory for connected trees
+ uno::Any aAny = configapi::makeInnerElement( rNode.getFactory(), aParentTree, aParentNode );
+
+ if (!(aAny >>= xRet)) // no parent available
+ {
+ // should occur only if the any is void
+ OSL_ENSURE(!aAny.hasValue(), "configmgr: BasicSetElement::getParent: could not extract parent - node is not an object");
+ OSL_ASSERT(!xRet.is()); // make sure we return NULL
+ }
+ }
+ else
+ {
+ OSL_ASSERT(!xRet.is()); // make sure we return NULL
+ }
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return xRet;
+}
+//-----------------------------------------------------------------------------------
+
+// UNSUPPORTED method
+void implSetParent(NodeAccess& rNode, InnerElement& /*rElement*/, const uno::Reference< uno::XInterface >& /*xParent*/ )
+ throw(lang::NoSupportException, uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ rNode.checkAlive(); // Does locking internally, checks for disposed nodes
+
+ // TODO(?): allow for xParent == getParent()
+ throw lang::NoSupportException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("configmgr: BasicElement::setParent: cannot move Entry")),
+ rNode.getUnoInstance() );
+}
+//-----------------------------------------------------------------------------------
+
+// preliminary implementation
+void implSetParent(NodeAccess& rNode, SetElement& rElement, const uno::Reference< uno::XInterface >& xParent )
+ throw(lang::NoSupportException, uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ //implSetParent(rNode,xParent);
+ // TODO: lock the whole transaction ???? - would need Uno Tunneling ?
+ uno::Reference< uno::XInterface > xGotParent( implGetParent(rNode,rElement) );
+ uno::Reference< css::container::XNameContainer > xOldParent( xGotParent, uno::UNO_QUERY );
+ uno::Reference< css::container::XNameContainer > xNewParent( xParent, uno::UNO_QUERY );
+
+ if (xGotParent.is() && !xOldParent.is())
+ {
+ throw lang::NoSupportException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: this is not element of a container")),
+ rNode.getUnoInstance() );
+ }
+ if (xParent.is() && !xNewParent.is())
+ {
+ throw lang::NoSupportException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: new parent is no container")),
+ rNode.getUnoInstance() );
+ }
+
+ uno::Reference< uno::XInterface > xThis(rNode.getUnoInstance());
+ OSL_ASSERT(xThis.is());
+
+ if (xOldParent != xNewParent)
+ {
+ rtl::OUString const sName( implGetName(rNode,rElement) );
+
+ if (xParent.is())
+ {
+ rtl::OUString const sTemplate( implGetTemplateName(rElement) );
+
+ if (sTemplate.getLength() == 0)
+ {
+ throw lang::NoSupportException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: object has no recognizable type")),
+ xThis );
+ }
+
+ uno::Reference< css::configuration::XTemplateContainer > xNewTemplate( xParent, uno::UNO_QUERY );
+ if (!xNewTemplate.is())
+ {
+ throw lang::NoSupportException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: new parent has no element template")),
+ xThis );
+ }
+
+ if ( sTemplate != xNewTemplate->getElementTemplateName())
+ {
+ throw lang::NoSupportException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: object has wrong type")),
+ xThis );
+ }
+
+ if ( xNewParent->hasByName( sName ) )
+ {
+ throw lang::NoSupportException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: an object of this name already exists in new parent")),
+ xThis );
+ }
+
+ // TODO: check for circularity (i.e. that This is not one of new parent's ancestors) !!
+ }
+
+ // now do it
+
+ try
+ {
+ if ( xOldParent.is()) xOldParent->removeByName(sName);
+ if ( xNewParent.is()) xNewParent->insertByName(sName, uno::makeAny(xThis));
+ }
+ catch (uno::Exception& e)
+ {
+ e.Message = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Config API: implSetParent: changing parent failed: "))
+ += e.Message;
+
+ if (xOldParent.is())
+ try
+ {
+ xOldParent->insertByName(sName, uno::makeAny(xThis));
+ }
+ catch(uno::Exception& bad)
+ {
+ e.Message += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n\t ! Could not restore old parent: ")) += bad.Message;
+ }
+
+ throw uno::RuntimeException(e.Message,xThis);
+ }
+
+ }
+}
+//-----------------------------------------------------------------------------
+
+
+// XNamed
+//-----------------------------------------------------------------------------
+rtl::OUString implGetName(NodeAccess& rNode, NodeElement& ) throw(uno::RuntimeException)
+{
+ rtl::OUString sRet;
+ try
+ {
+ GuardedNodeData<NodeAccess> impl( rNode ); // maybe passive only ?
+
+ rtl::Reference< configuration::Tree > aTree(impl.getTree());
+ configuration::NodeRef aNode(impl.getNode());
+
+ sRet = aTree->getSimpleNodeName(aNode.getOffset());
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return sRet;
+}
+//-----------------------------------------------------------------------------
+
+// UNSUPPORTED method
+void implSetName(NodeAccess & rNode, NodeElement& /*rElement*/, const rtl::OUString& /*aName*/ ) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ rNode.checkAlive(); // Does locking internally, checks for disposed nodes
+
+ // TODO(?): allow for aName == getName()
+ throw uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("configmgr: BasicElement::setName: cannot rename Entry")),
+ rNode.getUnoInstance() );
+}
+//-----------------------------------------------------------------------------
+
+// TODO: Implementations for elements to be added to a container node
+void implSetName(NodeAccess& rNode, SetElement& rElement, const rtl::OUString& aName ) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ // TODO: Implement
+ NodeElement& rDelegate = rElement;
+ implSetName(rNode,rDelegate,aName); // delegate to unsupported version
+}
+//-----------------------------------------------------------------------------
+
+// XComponent & XInterface
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+
+void implDispose( SetElement& rElement) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ if (!rElement.disposeTree(false))
+ {
+ throw uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONFIGURATION: Can't dispose an object that has an owner")),
+ rElement.getUnoInstance() );
+ }
+}
+//-----------------------------------------------------------------------------
+
+void implDispose( RootElement& rElement) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ if (!rElement.disposeTree())
+ {
+ throw lang::DisposedException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONFIGURATION: Can't dispose an object that already was disposed")),
+ rElement.getUnoInstance() );
+ }
+}
+//-----------------------------------------------------------------------------
+
+void implDisposeObject( NodeAccess& ,SetElement& rElement) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+// FIXME: should we hold a ref on the element over this ?
+// call apitreeaccess.hxx (doGetUnoInterface) & hold a ref / unref ?
+// [or!] - call getApiTree & ref/unref on that ?
+// [or!] - hold the ref inside the dispose method itself ...
+ rElement.disposeTree(true);
+}
+//-----------------------------------------------------------------------------
+
+void implDisposeObject( NodeAccess& , RootElement& rElement) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ rElement.disposeTree();
+}
+//-----------------------------------------------------------------------------
+
+void implDisposeObject( NodeAccess& rNode, InnerElement& ) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ rNode.disposeNode();
+}
+//-----------------------------------------------------------------------------
+
+
+// XTypeProvider
+//-----------------------------------------------------------------------------
+
+uno::Sequence<sal_Int8> implGetImplementationId(NodeAccess& rNode, NodeElement& rElement)
+ throw(uno::RuntimeException)
+{
+ DisposeGuard aLock(rNode);
+ ServiceImplementationInfo const* pInfo = rElement.getServiceInfo();
+
+ OSL_ENSURE(pInfo, "Configuration: Object has no implementation (service) info - cannot get implementation id");
+ if (!pInfo)
+ throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONFIGURATION: Object has no implementation information - cannot get implementation id")),rElement.getUnoInstance() );
+
+ return ServiceComponentImpl::getStaticImplementationId(pInfo);
+}
+//-----------------------------------------------------------------------------
+
+// XServiceInfo
+//-----------------------------------------------------------------------------
+
+rtl::OUString implGetImplementationName( NodeAccess& rNode, NodeElement& rElement ) throw(uno::RuntimeException)
+{
+ DisposeGuard aLock(rNode);
+ ServiceImplementationInfo const* pInfo = rElement.getServiceInfo();
+ OSL_ENSURE(pInfo, "Configuration: Object has no service info");
+
+ return ServiceInfoHelper(pInfo).getImplementationName();
+}
+//-----------------------------------------------------------------------------
+
+sal_Bool implSupportsService( NodeAccess& rNode, NodeElement& rElement, const rtl::OUString& ServiceName ) throw(uno::RuntimeException)
+{
+ DisposeGuard aLock(rNode);
+ ServiceImplementationInfo const* pInfo = rElement.getServiceInfo();
+ OSL_ENSURE(pInfo, "Configuration: Object has no service info");
+
+ return ServiceInfoHelper(pInfo).supportsService(ServiceName);
+}
+//-----------------------------------------------------------------------------
+
+uno::Sequence< rtl::OUString > implGetSupportedServiceNames( NodeAccess& rNode, NodeElement& rElement ) throw(uno::RuntimeException)
+{
+ DisposeGuard aLock(rNode);
+ ServiceImplementationInfo const* pInfo = rElement.getServiceInfo();
+ OSL_ENSURE(pInfo, "Configuration: Object has no service info");
+
+ return ServiceInfoHelper(pInfo).getSupportedServiceNames();
+}
+//-----------------------------------------------------------------------------
+
+// Root only ------------------------------------------------------------------
+
+// XLocalizable
+// TODO: Implement locale support
+//-----------------------------------------------------------------------------
+
+lang::Locale implGetLocale( RootElement& rElement ) throw(uno::RuntimeException)
+{
+ GuardedRootElement aLocked(rElement);
+
+ OSL_ENSURE(false,"CONFIGURATION: Locale information is not yetsupported.");
+ return lang::Locale();
+}
+//-----------------------------------------------------------------------------
+
+void implSetLocale( RootElement& rElement, const css::lang::Locale& /*eLocale*/ ) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+ // TODO: Implement if possible
+ rElement.checkAlive();
+
+ OSL_ENSURE(false,"CONFIGURATION: Changing the set Locale is not supported.");
+ throw uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CONFIGURATION: Changing the locale is currently not supported")),
+ rElement.getUnoInstance()
+ );
+}
+//-----------------------------------------------------------------------------
+
+// XChangesBatch
+//-----------------------------------------------------------------------------
+
+void implCommitChanges( UpdateRootElement& rElement ) throw(css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ // quick check to avoid big locks for nothing (has its own locking)
+ if (!implHasPendingChanges(rElement)) return;
+
+ try
+ {
+ rElement.getCommitter().commit();
+ }
+
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rElement.getUnoInstance() );
+ e.unhandled();
+ }
+
+ // filter/wrap uno::Exceptions
+ catch (lang::WrappedTargetException& ) { throw; }
+ catch (uno::RuntimeException& ) { throw; }
+ catch (uno::Exception& ex)
+ {
+ uno::Reference<uno::XInterface> xContext( rElement.getUnoInstance() );
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration: can't commit Changes: ") );
+ throw lang::WrappedTargetException( sMessage += ex.Message, xContext, uno::makeAny(ex));
+ }
+}
+//-----------------------------------------------------------------------------
+
+sal_Bool implHasPendingChanges( RootElement& rElement ) throw(uno::RuntimeException)
+{
+ try
+ {
+ GuardedRootElement aLocked(rElement);
+ return aLocked.get().getTree()->hasChanges();
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rElement.getUnoInstance() );
+ e.unhandled();
+ }
+
+ OSL_ENSURE(false,"Unreachable Code");
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+uno::Sequence< css::util::ElementChange > implGetPendingChanges( RootElement& rElement )
+ throw(uno::RuntimeException)
+{
+ std::vector<css::util::ElementChange> aResult;
+ try
+ {
+ GuardedRootElement aLocked(rElement);
+
+ rtl::Reference< configuration::Tree > aTree( aLocked.get().getTree() );
+
+ configuration::NodeChangesInformation aInfos;
+
+ {
+ configuration::NodeChanges aChanges;
+ if (aTree->collectChanges(aChanges))
+ {
+ aChanges.getChangesInfos(aInfos);
+ }
+ }
+
+ Factory& rFactory = rElement.getFactory();
+
+ for(std::vector< configuration::NodeChangeInformation >::const_iterator it = aInfos.begin(), stop = aInfos.end();
+ it != stop;
+ ++it)
+ {
+ css::util::ElementChange aChange;
+ fillChange(aChange,*it,aTree,rFactory);
+ aResult.push_back(aChange);
+ }
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rElement.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return makeSequence(aResult);
+}
+//-----------------------------------------------------------------------------
+
+// Set only -------------------------------------------------------------------------
+
+// XTemplateInstance
+//-----------------------------------------------------------------------------------
+
+rtl::OUString implGetTemplateName(SetElement& rElement)
+ throw(uno::RuntimeException)
+{
+ try
+ {
+ GuardedTreeElement aLocked(rElement);
+ return rElement.getTemplateInfo()->getPathString();
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rElement.getUnoInstance() );
+ e.unhandled();
+ }
+
+ OSL_ENSURE(false,"Unreachable Code");
+ return rtl::OUString();
+}
+//-----------------------------------------------------------------------------------
+
+// XUnoTunnel
+//-----------------------------------------------------------------------------------
+sal_Int64 implGetSomething(SetElement& rElement, const uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(uno::RuntimeException)
+{
+ sal_Int64 nSomething = 0;
+ try
+ {
+ GuardedTreeElement aLocked(rElement);
+
+ if (!rElement.getFactory().tunnelSetElement(nSomething, rElement, aIdentifier))
+ OSL_ASSERT(nSomething == 0);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rElement.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return nSomething;
+}
+//-----------------------------------------------------------------------------------
+
+ } // namespace configapi
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/elementimpl.hxx b/configmgr/source/api2/elementimpl.hxx
new file mode 100644
index 000000000000..ab17bd927428
--- /dev/null
+++ b/configmgr/source/api2/elementimpl.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementimpl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_ELEMENTIMPL_HXX_
+#define CONFIGMGR_API_ELEMENTIMPL_HXX_
+
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/configuration/XTemplateInstance.hpp>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+
+ /* implementations of the interfaces supported by a (parent) node
+ within the configuration tree.
+ (read-only operation)
+ */
+ namespace configapi
+ {
+ //-------------------------------------------------------------------------
+ class NodeAccess;
+ class NodeElement;
+ class InnerElement;
+ class TreeElement;
+ class SetElement;
+ class RootElement;
+ class UpdateRootElement;
+ //-------------------------------------------------------------------------
+
+ // XComponent and XInterface (EOL handling)
+ //---------------------------------------------------------------------
+ void implDispose( SetElement& rElement)
+ throw(uno::RuntimeException);
+
+ void implDispose( RootElement& rElement)
+ throw(uno::RuntimeException);
+
+ void implDisposeObject( NodeAccess& aNode, SetElement& rElement)
+ throw(uno::RuntimeException);
+
+ void implDisposeObject( NodeAccess& aNode, RootElement& rElement)
+ throw(uno::RuntimeException);
+
+ void implDisposeObject( NodeAccess& aNode, InnerElement& rElement)
+ throw(uno::RuntimeException);
+
+ // XTypeProvider
+ //---------------------------------------------------------------------
+ uno::Sequence<sal_Int8> implGetImplementationId(NodeAccess& rNode, NodeElement& rElement ) throw(uno::RuntimeException);
+
+ // XChild
+ //---------------------------------------------------------------------
+ uno::Reference< uno::XInterface > implGetParent(NodeAccess& rNode, InnerElement& rElement)
+ throw(uno::RuntimeException);
+
+ uno::Reference< uno::XInterface > implGetParent(NodeAccess& rNode, SetElement& rElement)
+ throw(uno::RuntimeException);
+
+ void implSetParent(NodeAccess& rNode, InnerElement& rElement, const uno::Reference< uno::XInterface >& Parent ) // generally not supported
+ throw(css::lang::NoSupportException, css::uno::RuntimeException);
+
+ void implSetParent(NodeAccess& rNode, SetElement& rElement, const uno::Reference< uno::XInterface >& Parent ) // maybe supported
+ throw(css::lang::NoSupportException, css::uno::RuntimeException);
+
+ // XNamed
+ //---------------------------------------------------------------------
+ rtl::OUString implGetName(NodeAccess& rNode, NodeElement& rElement)
+ throw(uno::RuntimeException);
+
+ void implSetName(NodeAccess& rNode, NodeElement& rElement, const rtl::OUString& aName ) // generally not supported (! - missing exception)
+ throw(uno::RuntimeException);
+
+ void implSetName(NodeAccess& rNode, SetElement& rElement, const rtl::OUString& aName ) // maybe supported
+ throw(uno::RuntimeException);
+
+ // XServiceInfo
+ //---------------------------------------------------------------------
+ rtl::OUString implGetImplementationName( NodeAccess& rNode, NodeElement& rElement )
+ throw(uno::RuntimeException);
+
+ sal_Bool implSupportsService( NodeAccess& rNode, NodeElement& rElement, const rtl::OUString& ServiceName )
+ throw(uno::RuntimeException);
+
+ uno::Sequence< rtl::OUString > implGetSupportedServiceNames( NodeAccess& rNode, NodeElement& rElement )
+ throw(uno::RuntimeException);
+
+ // Root only only
+ //-------------------------------------------------------------------------
+
+ // XLocalizable
+ //---------------------------------------------------------------------
+
+ css::lang::Locale implGetLocale( RootElement& rElement )
+ throw(uno::RuntimeException);
+
+ void implSetLocale( RootElement& rElement, const css::lang::Locale& eLocale )
+ throw(uno::RuntimeException);
+
+ // XChangesBatch
+ //---------------------------------------------------------------------
+
+ void implCommitChanges( UpdateRootElement& rElement )
+ throw(css::lang::WrappedTargetException, uno::RuntimeException);
+
+ sal_Bool implHasPendingChanges( RootElement& rElement )
+ throw(uno::RuntimeException);
+
+ uno::Sequence< css::util::ElementChange > implGetPendingChanges( RootElement& rElement )
+ throw(uno::RuntimeException);
+
+ // Set only
+ //-------------------------------------------------------------------------
+ // XTemplateInstance
+ //---------------------------------------------------------------------
+ rtl::OUString implGetTemplateName(SetElement& rElement)
+ throw(uno::RuntimeException);
+
+ // XUnoTunnel
+ //---------------------------------------------------------------------
+ sal_Int64 implGetSomething(SetElement& rElement, const uno::Sequence< sal_Int8 >& aIdentifier )
+ throw(uno::RuntimeException);
+
+ //-------------------------------------------------------------------------
+ }
+
+}
+#endif // CONFIGMGR_API_BASEACCESSIMPL_HXX_
+
+
diff --git a/configmgr/source/api2/groupaccess.cxx b/configmgr/source/api2/groupaccess.cxx
new file mode 100644
index 000000000000..8b375319f34a
--- /dev/null
+++ b/configmgr/source/api2/groupaccess.cxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: groupaccess.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "groupaccess.hxx"
+#include "accessimpl.hxx"
+#include "apinotifierimpl.hxx"
+#include "apinodeaccess.hxx"
+
+namespace configmgr
+{
+
+// XHierarchicalName
+//------------------------------------------------------------------------------------------------------------------
+rtl::OUString SAL_CALL BasicGroupAccess::getHierarchicalName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetHierarchicalName( getNode() );
+}
+
+//------------------------------------------------------------------------------------------------------------------
+rtl::OUString SAL_CALL BasicGroupAccess::composeHierarchicalName( const rtl::OUString& sRelativeName )
+ throw(css::lang::IllegalArgumentException, css::lang::NoSupportException, uno::RuntimeException)
+{
+ return configapi::implComposeHierarchicalName( getNode(), sRelativeName );
+}
+
+//------------------------------------------------------------------------------------------------------------------
+
+// XElementAccess, base class of XNameAccess (and XHierarchicalNameAccess ? )
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+uno::Type SAL_CALL BasicGroupAccess::getElementType( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetElementType( getNode() );
+}
+
+//-----------------------------------------------------------------------------------
+sal_Bool SAL_CALL BasicGroupAccess::hasElements( ) throw(uno::RuntimeException)
+{
+ return configapi::implHasElements( getNode() );
+}
+
+// XExactName
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicGroupAccess::getExactName( const rtl::OUString& rApproximateName ) throw(uno::RuntimeException)
+{
+ return configapi::implGetExactName( getNode(), rApproximateName);
+}
+
+// XProperty
+//-----------------------------------------------------------------------------------
+
+css::beans::Property SAL_CALL BasicGroupAccess::getAsProperty( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetAsProperty( getNode() );
+}
+
+// XNameAccess
+//-----------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL BasicGroupAccess::hasByName( const rtl::OUString& sName ) throw(uno::RuntimeException)
+{
+ return configapi::implHasByName( getNode(), sName);
+}
+
+//-----------------------------------------------------------------------------------
+uno::Any SAL_CALL BasicGroupAccess::getByName( const rtl::OUString& sName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ return configapi::implGetByName( getNode(), sName );
+}
+
+//-----------------------------------------------------------------------------------
+uno::Sequence< rtl::OUString > SAL_CALL BasicGroupAccess::getElementNames( ) throw( uno::RuntimeException)
+{
+ return configapi::implGetElementNames( getNode() );
+}
+
+// XHierarchicalNameAccess
+//-----------------------------------------------------------------------------------
+sal_Bool SAL_CALL BasicGroupAccess::hasByHierarchicalName( const rtl::OUString& sName ) throw(uno::RuntimeException)
+{
+ return configapi::implHasByHierarchicalName( getNode(), sName);
+}
+
+//-----------------------------------------------------------------------------------
+uno::Any SAL_CALL BasicGroupAccess::getByHierarchicalName( const rtl::OUString& sName )
+ throw(css::container::NoSuchElementException, uno::RuntimeException)
+{
+ return configapi::implGetByHierarchicalName( getNode(), sName );
+}
+
+
+// XContainer
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicGroupAccess::addContainerListener( const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implAddListener( getNode(), xListener );
+}
+
+//-----------------------------------------------------------------------------------
+void SAL_CALL BasicGroupAccess::removeContainerListener( const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNode(), xListener );
+}
+
+
+
+//-----------------------------------------------------------------------------------
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/groupaccess.hxx b/configmgr/source/api2/groupaccess.hxx
new file mode 100644
index 000000000000..1cbfd7227ca3
--- /dev/null
+++ b/configmgr/source/api2/groupaccess.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: groupaccess.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_GROUPACCESS_HXX_
+#define CONFIGMGR_API_GROUPACCESS_HXX_
+
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XProperty.hpp>
+#include <cppuhelper/implbase6.hxx>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+
+ namespace configapi { class NodeGroupInfoAccess; }
+
+ /** implements the (read-only) interfaces supported by a group node
+ within the configuration tree.
+ <p> Is an interface adapter around <type scope='configmgr::configapi'>NodeAccess</type>.</p>
+ */
+ class BasicGroupAccess
+ : public ::cppu::ImplHelper6
+ < css::container::XNameAccess
+ , css::container::XHierarchicalName
+ , css::container::XHierarchicalNameAccess
+ , css::container::XContainer
+ , css::beans::XExactName
+ , css::beans::XProperty
+ >
+ {
+ protected:
+ // Destructors
+ virtual ~BasicGroupAccess() {}
+
+ public:
+ // Interface methods
+
+ // XHierarchicalName
+ virtual rtl::OUString SAL_CALL
+ getHierarchicalName( )
+ throw(uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ composeHierarchicalName( const rtl::OUString& aRelativeName )
+ throw(css::lang::IllegalArgumentException, css::lang::NoSupportException,
+ uno::RuntimeException);
+
+ // XElementAccess, base class of XNameAccess
+ virtual uno::Type SAL_CALL
+ getElementType( )
+ throw(uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasElements( )
+ throw(uno::RuntimeException);
+
+ // XNameAccess
+ virtual uno::Any SAL_CALL
+ getByName( const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getElementNames( )
+ throw( uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XHierarchicalNameAccess
+ virtual uno::Any SAL_CALL
+ getByHierarchicalName( const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasByHierarchicalName( const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XContainer
+ virtual void SAL_CALL
+ addContainerListener( const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeContainerListener( const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException);
+
+ // XExactName
+ virtual ::rtl::OUString SAL_CALL
+ getExactName( const rtl::OUString& aApproximateName )
+ throw(uno::RuntimeException);
+
+ // XProperty
+ virtual css::beans::Property SAL_CALL
+ getAsProperty( )
+ throw(uno::RuntimeException);
+
+ protected:
+ virtual configapi::NodeGroupInfoAccess& getNode() = 0;
+ };
+
+}
+#endif // CONFIGMGR_API_GROUPACCESS_HXX_
+
+
diff --git a/configmgr/source/api2/groupobjects.cxx b/configmgr/source/api2/groupobjects.cxx
new file mode 100644
index 000000000000..b1a047345e47
--- /dev/null
+++ b/configmgr/source/api2/groupobjects.cxx
@@ -0,0 +1,410 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: groupobjects.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "groupobjects.hxx"
+#include "comphelper/sequence.hxx"
+
+//........................................................................
+namespace configmgr
+{
+
+//==========================================================================
+//= OInnerGroupInfo
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OInnerGroupInfo::acquire( ) throw ()
+{
+ BasicInnerElement::acquire();
+}
+
+void SAL_CALL OInnerGroupInfo::release( ) throw ()
+{
+ BasicInnerElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OInnerGroupInfo::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicInnerElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicGroupAccess::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicPropertySet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OInnerGroupInfo::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicInnerElement::getTypes(), BasicGroupAccess::getTypes(), BasicPropertySet::getTypes());
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OInnerGroupInfo::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicInnerElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OInnerGroupInfo::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupInfoAccess& OInnerGroupInfo::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupAccess* OInnerGroupInfo::maybeGetUpdateAccess()
+{
+ return 0;
+}
+
+configapi::InnerElement& OInnerGroupInfo::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= OInnerGroupUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OInnerGroupUpdate::acquire( ) throw ()
+{
+ BasicInnerElement::acquire();
+}
+
+void SAL_CALL OInnerGroupUpdate::release( ) throw ()
+{
+ BasicInnerElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OInnerGroupUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicInnerElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicGroup::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicPropertySet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OInnerGroupUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicInnerElement::getTypes(), BasicGroup::getTypes(), BasicPropertySet::getTypes());
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OInnerGroupUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicInnerElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OInnerGroupUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupInfoAccess& OInnerGroupUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupAccess* OInnerGroupUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::InnerElement& OInnerGroupUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= OSetElementGroupInfo
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OSetElementGroupInfo::acquire( ) throw ()
+{
+ BasicSetElement::acquire();
+}
+
+void SAL_CALL OSetElementGroupInfo::release( ) throw ()
+{
+ BasicSetElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OSetElementGroupInfo::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicSetElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicGroupAccess::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicPropertySet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OSetElementGroupInfo::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicSetElement::getTypes(), BasicGroupAccess::getTypes(), BasicPropertySet::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OSetElementGroupInfo::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicSetElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OSetElementGroupInfo::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupInfoAccess& OSetElementGroupInfo::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupAccess* OSetElementGroupInfo::maybeGetUpdateAccess()
+{
+ return 0;
+}
+
+configapi::SetElement& OSetElementGroupInfo::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= OSetElementGroupUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OSetElementGroupUpdate::acquire( ) throw ()
+{
+ BasicSetElement::acquire();
+}
+
+void SAL_CALL OSetElementGroupUpdate::release( ) throw ()
+{
+ BasicSetElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OSetElementGroupUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicSetElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicGroup::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicPropertySet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OSetElementGroupUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicSetElement::getTypes(), BasicGroup::getTypes(), BasicPropertySet::getTypes());
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OSetElementGroupUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicSetElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OSetElementGroupUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupInfoAccess& OSetElementGroupUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupAccess* OSetElementGroupUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::SetElement& OSetElementGroupUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= ORootElementGroupInfo
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL ORootElementGroupInfo::acquire( ) throw ()
+{
+ BasicRootElement::acquire();
+}
+
+void SAL_CALL ORootElementGroupInfo::release( ) throw ()
+{
+ BasicRootElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL ORootElementGroupInfo::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicRootElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicGroupAccess::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicPropertySet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL ORootElementGroupInfo::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicRootElement::getTypes(), BasicGroupAccess::getTypes(), BasicPropertySet::getTypes());
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL ORootElementGroupInfo::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicRootElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& ORootElementGroupInfo::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupInfoAccess& ORootElementGroupInfo::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupAccess* ORootElementGroupInfo::maybeGetUpdateAccess()
+{
+ return 0;
+}
+
+configapi::RootElement& ORootElementGroupInfo::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= ORootElementGroupUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL ORootElementGroupUpdate::acquire( ) throw ()
+{
+ BasicUpdateElement::acquire();
+}
+
+void SAL_CALL ORootElementGroupUpdate::release( ) throw ()
+{
+ BasicUpdateElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL ORootElementGroupUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicUpdateElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicGroup::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicPropertySet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL ORootElementGroupUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicUpdateElement::getTypes(),BasicGroup::getTypes(), BasicPropertySet::getTypes());
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL ORootElementGroupUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicUpdateElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& ORootElementGroupUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupInfoAccess& ORootElementGroupUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeGroupAccess* ORootElementGroupUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::UpdateRootElement& ORootElementGroupUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//........................................................................
+} // namespace configmgr
+//........................................................................
+
diff --git a/configmgr/source/api2/groupobjects.hxx b/configmgr/source/api2/groupobjects.hxx
new file mode 100644
index 000000000000..b992c334c0f4
--- /dev/null
+++ b/configmgr/source/api2/groupobjects.hxx
@@ -0,0 +1,271 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: groupobjects.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_GROUPOBJECTS_HXX_
+#define CONFIGMGR_API_GROUPOBJECTS_HXX_
+
+#include "groupaccess.hxx"
+#include "groupupdate.hxx"
+#include "propertysetaccess.hxx"
+#include "elementaccess.hxx"
+
+#include "apiaccessobj.hxx"
+
+//........................................................................
+namespace configmgr
+{
+//........................................................................
+
+//==========================================================================
+//= Inner Group Instances
+//==========================================================================
+
+/** read-only access class for configuration nodes which are inner nodes and groups of other nodes
+*/
+ class OInnerGroupInfo
+ : public BasicInnerElement
+ , public BasicGroupAccess
+ , public BasicPropertySet
+ {
+ public:
+ // Construction/Destruction
+ OInnerGroupInfo(configapi::ApiTreeImpl& rTree, configuration::NodeRef const& aNode)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),rTree,aNode)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeGroupInfoAccess& getNode();
+ virtual configapi::NodeGroupAccess* maybeGetUpdateAccess();
+ virtual configapi::InnerElement& getElementClass();
+ private:
+ configapi::OInnerElement<configapi::NodeGroupInfoAccess> m_aAccessElement;
+ };
+
+/** updating access class for configuration nodes which are inner nodes and groups of other nodes
+*/
+ class OInnerGroupUpdate
+ : public BasicInnerElement
+ , public BasicGroup
+ , public BasicPropertySet
+ {
+ public:
+ // Construction/Destruction
+ OInnerGroupUpdate(configapi::ApiTreeImpl& rTree, configuration::NodeRef const& aNode)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),rTree,aNode)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeGroupInfoAccess& getNode();
+ virtual configapi::NodeGroupAccess* maybeGetUpdateAccess();
+ virtual configapi::InnerElement& getElementClass();
+ private:
+ configapi::OInnerElement<configapi::NodeGroupAccess> m_aAccessElement;
+ };
+
+
+//==========================================================================
+//= Set Element Group Instances
+//==========================================================================
+
+/** read-only access class for configuration nodes which are set elements and groups of other nodes
+*/
+ class OSetElementGroupInfo
+ : public BasicSetElement
+ , public BasicGroupAccess
+ , public BasicPropertySet
+ {
+ public:
+ // Construction/Destruction
+ OSetElementGroupInfo(rtl::Reference< configuration::Tree > const& aTree, configapi::ApiProvider& rProvider, configapi::ApiTreeImpl* pParentTree = 0)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),aTree,rProvider,pParentTree)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeGroupInfoAccess& getNode();
+ virtual configapi::NodeGroupAccess* maybeGetUpdateAccess();
+ virtual configapi::SetElement& getElementClass();
+ private:
+ configapi::OSetElement<configapi::NodeGroupInfoAccess> m_aAccessElement;
+ };
+
+/** updating access class for configuration nodes which are set elements and groups of other nodes
+*/
+ class OSetElementGroupUpdate
+ : public BasicSetElement
+ , public BasicGroup
+ , public BasicPropertySet
+ {
+ public:
+ // Construction/Destruction
+ OSetElementGroupUpdate(rtl::Reference< configuration::Tree > const& aTree, configapi::ApiProvider& rProvider, configapi::ApiTreeImpl* pParentTree = 0)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),aTree,rProvider,pParentTree)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeGroupInfoAccess& getNode();
+ virtual configapi::NodeGroupAccess* maybeGetUpdateAccess();
+ virtual configapi::SetElement& getElementClass();
+ private:
+ configapi::OSetElement<configapi::NodeGroupAccess> m_aAccessElement;
+ };
+
+
+//==========================================================================
+//= Root Element Set Instances
+//==========================================================================
+
+/** read-only access class for configuration nodes which are root nodes and groups of other nodes
+*/
+ class ORootElementGroupInfo
+ : public BasicRootElement
+ , public BasicGroupAccess
+ , public BasicPropertySet
+ {
+ public:
+ // Construction/Destruction
+ ORootElementGroupInfo(configapi::ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions >const& _xOptions)
+ : m_aAccessElement(static_cast<css::lang::XComponent*>(this),rProvider,aTree, _xOptions)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeGroupInfoAccess& getNode();
+ virtual configapi::NodeGroupAccess* maybeGetUpdateAccess();
+ virtual configapi::RootElement& getElementClass();
+ private:
+ configapi::OReadRootElement<configapi::NodeGroupInfoAccess> m_aAccessElement;
+ };
+
+/** updating access class for configuration nodes which are root nodes and groups of other nodes
+*/
+ class ORootElementGroupUpdate
+ : public BasicUpdateElement
+ , public BasicGroup
+ , public BasicPropertySet
+ {
+ public:
+ // Construction/Destruction
+ ORootElementGroupUpdate(configapi::ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions >const& _xOptions)
+ : m_aAccessElement(static_cast<css::lang::XComponent*>(this),rProvider,aTree, _xOptions)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeGroupInfoAccess& getNode();
+ virtual configapi::NodeGroupAccess* maybeGetUpdateAccess();
+ virtual configapi::UpdateRootElement& getElementClass();
+ private:
+ configapi::OUpdateRootElement<configapi::NodeGroupAccess> m_aAccessElement;
+ };
+
+
+//........................................................................
+} // namespace configmgr
+//........................................................................
+
+#endif // CONFIGMGR_API_GROUPOBJECTS_HXX_
+
+
diff --git a/configmgr/source/api2/groupupdate.cxx b/configmgr/source/api2/groupupdate.cxx
new file mode 100644
index 000000000000..41b9cf9013f7
--- /dev/null
+++ b/configmgr/source/api2/groupupdate.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: groupupdate.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "groupupdate.hxx"
+#include "updateimpl.hxx"
+#include "apinodeaccess.hxx"
+#include "apitypes.hxx"
+
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+namespace configmgr
+{
+//////////////////////////////////////////////////////////////////////////////////
+// class BasicGroup
+//////////////////////////////////////////////////////////////////////////////////
+
+// XInterface joining
+//////////////////////////////////////////////////////////////////////////////////
+uno::Any SAL_CALL BasicGroup::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicGroupAccess::queryInterface( rType );
+ if (!aRet.hasValue())
+ {
+ aRet = cppu::queryInterface(rType
+ , static_cast< css::container::XNameReplace *>(this)
+ );
+ }
+ return aRet;
+}
+
+// XTypeProvider joining
+//////////////////////////////////////////////////////////////////////////////////
+uno::Sequence< uno::Type > SAL_CALL BasicGroup::getTypes( ) throw (uno::RuntimeException )
+{
+ /*static ?*/
+ cppu::OTypeCollection aTypes(
+ configapi::getReferenceType(static_cast< css::container::XNameReplace *>(this)),
+ BasicGroupAccess::getTypes());
+
+ return aTypes.getTypes();
+}
+
+//uno::Sequence< sal_Int8 > SAL_CALL BasicGroup::getImplementationId( ) throw (uno::RuntimeException ) = 0;
+
+//////////////////////////////////////////////////////////////////////////////////
+
+// safe write access
+/////////////////////////////////////////////////////////////
+configapi::NodeGroupAccess& BasicGroup::getGroupNode()
+{
+ configapi::NodeGroupAccess* pAccess = maybeGetUpdateAccess();
+ OSL_ENSURE(pAccess, "Write operation invoked on a read-only node access - failing with RuntimeException");
+
+ if (!pAccess)
+ {
+ throw uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: Invalid Object - internal update interface missing.")),
+ static_cast< css::container::XNameReplace * >(this)
+ );
+ }
+ return *pAccess;
+}
+
+// New Interface methods
+// XNameReplace
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicGroup::replaceByName( const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implReplaceByName( getGroupNode(), rName, rElement );
+}
+
+//-----------------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/groupupdate.hxx b/configmgr/source/api2/groupupdate.hxx
new file mode 100644
index 000000000000..97d93b9da7c0
--- /dev/null
+++ b/configmgr/source/api2/groupupdate.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: groupupdate.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_GROUPUPDATE_HXX_
+#define CONFIGMGR_API_GROUPUPDATE_HXX_
+
+#include "groupaccess.hxx"
+#include <com/sun/star/container/XNameReplace.hpp>
+
+//........................................................................
+namespace configmgr
+{
+//........................................................................
+ namespace configapi { class NodeGroupAccess; }
+
+//==========================================================================
+//= BasicGroup
+//==========================================================================
+
+/** base class for configuration nodes which are dynamic sets of complex types (trees)
+*/
+ class BasicGroup
+ : public BasicGroupAccess
+ , public css::container::XNameReplace
+ {
+ protected:
+ // Destructors
+ virtual ~BasicGroup() {}
+
+ public:
+ // Base class Interface methods
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException ) = 0;
+
+ // XElementAccess forwarding
+ virtual uno::Type SAL_CALL getElementType( ) throw(uno::RuntimeException)
+ { return BasicGroupAccess::getElementType(); }
+
+ virtual sal_Bool SAL_CALL hasElements( ) throw(uno::RuntimeException)
+ { return BasicGroupAccess::hasElements(); }
+
+ // XNameAccess forwarding
+ virtual uno::Any SAL_CALL getByName( const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+ { return BasicGroupAccess::getByName(aName); }
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL getElementNames( ) throw( uno::RuntimeException)
+ { return BasicGroupAccess::getElementNames(); }
+
+ virtual sal_Bool SAL_CALL hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+ { return BasicGroupAccess::hasByName(aName); }
+
+ // New Interface methods
+ // XNameReplace
+ virtual void SAL_CALL
+ replaceByName( const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ protected:
+ configapi::NodeGroupAccess& getGroupNode();
+ virtual configapi::NodeGroupAccess* maybeGetUpdateAccess() = 0;
+ };
+
+//........................................................................
+} // namespace configmgr
+//........................................................................
+
+#endif // CONFIGMGR_API_GROUPUPDATE_HXX_
+
+
diff --git a/configmgr/source/api2/listenercontainer.cxx b/configmgr/source/api2/listenercontainer.cxx
new file mode 100644
index 000000000000..7149186c69db
--- /dev/null
+++ b/configmgr/source/api2/listenercontainer.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: listenercontainer.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "listenercontainer.hxx"
+#include <com/sun/star/lang/XEventListener.hpp>
+
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configapi
+ {
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+// class DisposeNotifier
+//-----------------------------------------------------------------------------
+
+void DisposeNotifier::appendAndClearContainer(cppu::OInterfaceContainerHelper* pContainer)
+{
+ if (pContainer)
+ {
+ {
+ cppu::OInterfaceIteratorHelper aIterator(*pContainer);
+ while (aIterator.hasMoreElements())
+ {
+ aListeners.push_back(uno::Reference< lang::XEventListener >::query(aIterator.next()));
+ }
+ }
+ pContainer->clear();
+ }
+}
+//-----------------------------------------------------------------------------
+void DisposeNotifier::notify()
+{
+ for(std::vector< uno::Reference< lang::XEventListener > >::iterator it = aListeners.begin(); it != aListeners.end(); ++it)
+ {
+ if (it->is())
+ {
+ try { (*it)->disposing(aEvent); } catch (uno::Exception & ) {}
+ it->clear();
+ }
+ }
+ aListeners.clear();
+}
+
+//-----------------------------------------------------------------------------
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+ }
+}
+
+
diff --git a/configmgr/source/api2/listenercontainer.hxx b/configmgr/source/api2/listenercontainer.hxx
new file mode 100644
index 000000000000..ecc0ebfaa705
--- /dev/null
+++ b/configmgr/source/api2/listenercontainer.hxx
@@ -0,0 +1,584 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: listenercontainer.hxx,v $
+ * $Revision: 1.19 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_LISTENERCONTAINER_HXX_
+#define CONFIGMGR_API_LISTENERCONTAINER_HXX_
+
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <cppuhelper/interfacecontainer.hxx>
+#include "datalock.hxx"
+#include "utility.hxx"
+
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configapi
+ {
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+//-----------------------------------------------------------------------------
+ template <class Listener>
+ class ListenerContainerIterator
+ {
+ public:
+ /**
+ * Create an iterator over the elements of the container. The iterator
+ * copies the elements of the conatainer. A change to the container does not
+ * affect the iterator.<BR>
+ * Remark: The copy is on demand. The iterator copy the elements only if the container
+ * change the contens. It is not allowed to destroy the container if a iterator exist.
+ *
+ * @param rCont the container of the elements.
+ */
+ ListenerContainerIterator( cppu::OInterfaceContainerHelper& rCont )
+ : m_aIter(rCont)
+ , m_xNext()
+ { advance(); }
+
+ /**
+ * Release the connection to the container.
+ */
+ ~ListenerContainerIterator() {}
+
+ /** Return true, if there are more elements in the iterator. */
+ sal_Bool hasMoreElements() const { return m_xNext.is() != 0; }
+
+ /** Return the next element of the iterator. Call this method if
+ * hasMoreElements return false, is an error.
+ */
+ uno::Reference<Listener> next();
+
+ private:
+ void advance();
+
+ cppu::OInterfaceIteratorHelper m_aIter;
+ uno::Reference<Listener> m_xNext;
+ };
+//-----------------------------------------------------------------------------
+ class DisposeNotifier
+ {
+ lang::EventObject aEvent;
+ std::vector< uno::Reference< lang::XEventListener > > aListeners;
+ public:
+ explicit
+ DisposeNotifier(uno::Reference<uno::XInterface> const& aInterface) : aEvent(aInterface) {}
+
+ void appendAndClearContainer(cppu::OInterfaceContainerHelper* pContainer);
+ void notify();
+ };
+//-----------------------------------------------------------------------------
+ struct BasicContainerInfo
+ {
+ uno::XInterface* pInterface;
+ cppu::OMultiTypeInterfaceContainerHelper* pContainer;
+ BasicContainerInfo() : pInterface(0), pContainer(0) {}
+ };
+
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ class SpecialListenerContainer
+ {
+ public:
+ /**
+ * Create a container of interface containers.
+ */
+ SpecialListenerContainer(std::vector<BasicContainerInfo>::size_type nCount, KeyToIndex_ aMapper)
+ : m_aSpecialHelper(UnoApiLock::getLock())
+ , m_aContainers(nCount)
+ , m_aMapper(aMapper)
+ , m_bDisposeLock(false)
+ {}
+
+ ~SpecialListenerContainer()
+ {
+ OSL_ENSURE(isDisposed(), "ERROR: Object was not disposed properly");
+ }
+ public:
+ /**
+ * check whether this is disposed or still alive
+ * @param pObject
+ * an interface on the object on which's behalf the operation was started
+ * @return <FALSE/>
+ * if the object is being disposed
+ * @throw com::sun::star::lang::DisposedException
+ * if the object was disposed completely
+ */
+ bool checkAlive(uno::XInterface* pObject = 0) volatile const throw(lang::DisposedException);
+
+ /// return whether the object is completely alive
+ bool isAlive() volatile const throw();
+ /// return whether the object is currently being disposed
+ bool isDisposing()volatile const throw();
+ /// return whether the object is completely disposed
+ bool isDisposed()volatile const throw();
+
+ /// return whether the object is present in this container
+ bool isAvailable(std::vector<BasicContainerInfo>::size_type nIndex) const throw()
+ {
+ return nIndex < m_aContainers.size() && m_aContainers[nIndex].pInterface;
+ }
+
+ std::vector<BasicContainerInfo>::size_type getSize() const
+ {
+ return m_aContainers.size();
+ }
+
+ /// return the interface associated with an index
+ void setObjectAt(std::vector<BasicContainerInfo>::size_type nIndex, uno::XInterface* pInterface)
+ {
+ OSL_ENSURE( !isDisposed(), "object is disposed" );
+
+ if (isAlive())
+ {
+ OSL_ENSURE( nIndex < m_aContainers.size(), " Invalid Index into Notifier");
+ OSL_ENSURE( pInterface, "Invalid NULL Interface passed into Notifier");
+
+ if ( nIndex < m_aContainers.size() && pInterface != NULL)
+ {
+ OSL_ENSURE( m_aContainers[nIndex].pInterface == NULL, "Interface already set");
+ if (m_aContainers[nIndex].pInterface == NULL)
+ m_aContainers[nIndex].pInterface = pInterface;
+ }
+ }
+ }
+
+
+ /// return the interface associated with an index
+ uno::Reference<uno::XInterface> getObjectAt(std::vector<BasicContainerInfo>::size_type nIndex) const
+ {
+ uno::Reference<uno::XInterface> xRet( nIndex < m_aContainers.size() ? m_aContainers[nIndex].pInterface : 0 );
+ return xRet;
+ }
+
+ /// return the interface associated with an index
+ uno::Reference<uno::XInterface> getObjectForKey(Key_ const& aKey ) const
+ {
+ std::vector<BasicContainerInfo>::size_type nIndex = m_aMapper.findIndexForKey(aKey);
+ uno::Reference<uno::XInterface> xRet( nIndex < m_aContainers.size() ? m_aContainers[nIndex].pInterface : 0 );
+ return xRet;
+ }
+
+ /**
+ * Call disposing on all object in all the container for anIndex
+ * and in the containers for the associated indices
+ * support XEventListener. Then clear the container.
+ */
+ bool disposeOne( std::vector<BasicContainerInfo>::size_type anIndex ) throw();
+
+ /**
+ * Start disposing this object
+ * @return <TRUE/>
+ * if disposing has been started
+ * @return <FALSE/>
+ * if disposing had already been started before
+ */
+ bool beginDisposing() throw();
+ /**
+ * Continue disposing this object
+ * <p> Call disposing on all object in all the containers that
+ * support XEventListener. Then clear the container.
+ * </p>
+ * @return <TRUE/>
+ * if disposing has been started
+ * @return <FALSE/>
+ * if disposing had already been started before
+ */
+ void notifyDisposing() throw();
+
+ /// mark the end of the dispose processing
+ void endDisposing() throw();
+
+ public:
+ /**
+ * Return the specuial container created under this key.
+ * @return the container created under this key. If the container
+ * was not created, null was returned.
+ */
+ cppu::OInterfaceContainerHelper * getSpecialContainer( const Key_ & aKey) const
+ { return m_aSpecialHelper.aLC.getContainer(aKey); }
+
+ /**
+ * Return the containerhelper created under this index.
+ * @return the container helper created under this key. If the container helper
+ * was not created, null was returned.
+ */
+ cppu::OMultiTypeInterfaceContainerHelper * getContainerHelper( std::vector<BasicContainerInfo>::size_type nIndex) const
+ {
+ return ((nIndex < m_aContainers.size()) ? m_aContainers[nIndex].pContainer : 0 );
+ }
+ /**
+ * Return the container for the given type created under this index.
+ * @return the container created under this key. If the container
+ * was not created, null was returned.
+ */
+ cppu::OInterfaceContainerHelper * getContainer( std::vector<BasicContainerInfo>::size_type nIndex, const uno::Type & aType) const
+ {
+ cppu::OMultiTypeInterfaceContainerHelper* pContainer = (nIndex < m_aContainers.size()) ? m_aContainers[nIndex].pContainer : 0 ;
+
+ return pContainer ? pContainer->getContainer(aType) : 0;
+ }
+
+ /**
+ * Insert an element in the container specified with the index and type. The position is not specified.
+ * The interface at the given index must be set already.
+ * @param aKey the id of the container.
+ * @param xListener the added interface. It is allowed to insert null or
+ * the same pointer more than once.
+ * @return the new count of elements in the container (or 0 if the object is ready being disposed).
+ */
+ sal_Int32 addListener( std::vector<BasicContainerInfo>::size_type nIndex, const uno::Type& aType, uno::Reference< lang::XEventListener > const& xListener) throw();
+
+ /**
+ * Remove an element from the container specified with the index and type.
+ * It uses the equal definition of uno objects to remove the interfaces.
+ * @param aKey the id of the container.
+ * @param xListener the removed interface.
+ * @return the new count of elements in the container (or 0 if the object is ready being disposed).
+ */
+ sal_Int32 removeListener( std::vector<BasicContainerInfo>::size_type nIndex, const uno::Type& aType, uno::Reference< lang::XEventListener > const& xListener) throw();
+
+
+ /**
+ * Insert an element in the special container specified with the key. The position is not specified.
+ * The interface at the given index must be set already.
+ * @param aKey the id of the container.
+ * @param xListener the added interface. It is allowed to insert null or
+ * the same pointer more than once.
+ * @return the new count of elements in the container (or 0 if the object is ready being disposed).
+ */
+ sal_Int32 addSpecialListener( const Key_& aKey, uno::Reference< lang::XEventListener > const& xListener) throw();
+
+ /**
+ * Remove an element from the container specified with the key.
+ * It uses the equal definition of uno objects to remove the interfaces.
+ * @param aKey the id of the container.
+ * @param xListener the removed interface.
+ * @return the new count of elements in the container (or 0 if the object is ready being disposed).
+ */
+ sal_Int32 removeSpecialListener( const Key_& aKey, uno::Reference< lang::XEventListener > const& xListener) throw();
+
+ private:
+ void implFillDisposer(DisposeNotifier& aNotifier, std::vector<BasicContainerInfo>::size_type nIndex);
+
+ cppu::OBroadcastHelperVar< cppu::OMultiTypeInterfaceContainerHelperVar< Key_,KeyHash_,KeyEq_ >, Key_ > m_aSpecialHelper;
+ std::vector<BasicContainerInfo> m_aContainers;
+ KeyToIndex_ m_aMapper;
+ bool m_bDisposeLock;
+ };
+//-----------------------------------------------------------------------------
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::checkAlive(uno::XInterface* pObject) volatile const throw(lang::DisposedException)
+ {
+ bool bAlive = !m_aSpecialHelper.bInDispose;
+ if (m_aSpecialHelper.bDisposed)
+ {
+ throw lang::DisposedException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("The object has already been disposed")),pObject);
+ }
+ return bAlive;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ inline
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::isAlive() volatile const throw()
+ {
+ return !m_aSpecialHelper.bInDispose && !m_aSpecialHelper.bDisposed;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ inline
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::isDisposing() volatile const throw()
+ {
+ return !!m_aSpecialHelper.bInDispose;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ inline
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::isDisposed() volatile const throw()
+ {
+ return !!m_aSpecialHelper.bDisposed;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::disposeOne(std::vector<BasicContainerInfo>::size_type nIndex) throw()
+ {
+ // OSL_ENSURE(!isDisposed(),"Object is already disposed in toto");
+ if (isAlive())
+ {
+ if (nIndex < m_aContainers.size())
+ {
+ if (uno::XInterface* pObject = m_aContainers[nIndex].pInterface)
+ {
+ DisposeNotifier aNotifier(pObject);
+
+ implFillDisposer(aNotifier, nIndex);
+ m_aContainers[nIndex].pInterface = 0;
+ delete m_aContainers[nIndex].pContainer;
+
+ aNotifier.notify();
+ }
+ }
+ return true;
+ }
+ else
+ return false;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::beginDisposing() throw()
+ {
+ if (isAlive())
+ {
+ m_aSpecialHelper.bInDispose = sal_True;
+ m_bDisposeLock = true;
+
+ return true;
+ }
+ return false;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ void SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::notifyDisposing() throw()
+ {
+ OSL_ENSURE(isDisposing(),"Disposing isn't in progress on this object");
+ OSL_ENSURE(m_bDisposeLock,"Duplicate call for dispose notification or disposing is not taking place");
+
+ if (m_bDisposeLock)
+ {
+ OSL_ASSERT(m_aSpecialHelper.bInDispose);
+
+ lang::EventObject aBaseEvt;
+ std::vector<DisposeNotifier> aNotifiers;
+
+ if (std::vector<BasicContainerInfo>::size_type size = m_aContainers.size())
+ {
+ aNotifiers.reserve(m_aContainers.size());
+
+ aBaseEvt.Source = m_aContainers[0].pInterface;
+ for(std::vector<BasicContainerInfo>::size_type ix = 0; ix < size; ++ix)
+ {
+ if (m_aContainers[ix].pInterface)
+ {
+ aNotifiers.push_back(DisposeNotifier(m_aContainers[ix].pInterface));
+ implFillDisposer(aNotifiers.back(), ix);
+ m_aContainers[ix].pInterface = 0;
+ delete m_aContainers[ix].pContainer;
+ }
+ }
+ }
+
+ m_bDisposeLock = false;
+
+ for(std::vector<BasicContainerInfo>::size_type jx = 0, count = aNotifiers.size(); jx < count; ++jx)
+ {
+ aNotifiers[jx].notify();
+ }
+ // in case we missed something
+ m_aSpecialHelper.aLC.disposeAndClear( aBaseEvt );
+ }
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ void SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::endDisposing() throw()
+ {
+ OSL_ENSURE(isDisposing(),"Disposing isn't in progress on this object");
+
+ if (!isAlive())
+ {
+ OSL_ENSURE(!m_bDisposeLock,"Did you forget to notify ?");
+
+ m_aSpecialHelper.bDisposed = sal_True;
+ m_aSpecialHelper.bInDispose = sal_False;
+
+ if (m_bDisposeLock)
+ {
+ m_bDisposeLock = false;
+ }
+ }
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ sal_Int32 SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::addListener( std::vector<BasicContainerInfo>::size_type nIndex, const uno::Type& aType, const uno::Reference< lang::XEventListener > & xListener ) throw()
+ {
+ if ( nIndex < m_aContainers.size() && m_aContainers[nIndex].pInterface )
+ {
+ if ( isAlive() )
+ {
+ if (m_aContainers[nIndex].pContainer == 0)
+ m_aContainers[nIndex].pContainer = new cppu::OMultiTypeInterfaceContainerHelper(UnoApiLock::getLock());
+
+ return m_aContainers[nIndex].pContainer->addInterface(aType,xListener);
+ }
+
+ else if (xListener.is())
+ {
+ lang::EventObject aEvent(m_aContainers[nIndex].pInterface);
+ try { xListener->disposing(aEvent); } catch (uno::Exception & ) {}
+ }
+
+ }
+ else
+ OSL_ENSURE(false, "Invalid index or interface not set");
+
+ return 0;
+ }
+//-----------------------------------------------------------------------------
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ sal_Int32 SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::addSpecialListener( const Key_& aKey, const uno::Reference< lang::XEventListener > & xListener ) throw()
+ {
+ std::vector<BasicContainerInfo>::size_type nIndex = m_aMapper.findIndexForKey(aKey);
+ if ( nIndex < m_aContainers.size() && m_aContainers[nIndex].pInterface )
+ {
+ if ( isAlive() )
+ {
+ return m_aSpecialHelper.aLC.addInterface(aKey,xListener);
+ }
+
+ else if (xListener.is())
+ {
+ lang::EventObject aEvent(m_aContainers[nIndex].pInterface);
+ try { xListener->disposing(aEvent); } catch (uno::Exception & ) {}
+ }
+ }
+ else
+ OSL_ENSURE(false, "Invalid index or interface not set");
+
+ return 0;
+ }
+//-----------------------------------------------------------------------------
+
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ sal_Int32 SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::removeListener( std::vector<BasicContainerInfo>::size_type nIndex, const uno::Type& aType, const uno::Reference< lang::XEventListener > & xListener ) throw()
+ {
+ OSL_ENSURE( !isDisposed(), "object is disposed" );
+
+ if ( isAlive() )
+ {
+ if ( nIndex < m_aContainers.size() && m_aContainers[nIndex].pContainer )
+ {
+ return m_aContainers[nIndex].pContainer->removeInterface(aType,xListener);
+ }
+ }
+ return 0;
+ }
+//-----------------------------------------------------------------------------
+
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ sal_Int32 SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::removeSpecialListener( const Key_& aKey, const uno::Reference< lang::XEventListener > & xListener ) throw()
+ {
+ OSL_ENSURE( !isDisposed(), "object is disposed" );
+
+ if ( isAlive() )
+ return m_aSpecialHelper.aLC.removeInterface(aKey, xListener );
+
+ else
+ return 0;
+ }
+//-----------------------------------------------------------------------------
+ // relation function. Uses KeyToIndex
+/* template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::Index
+ SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::findIndexForKey(Key const& aKey)
+ {
+ m_aMapper.findIndexForKey(aKey);
+ }
+//-----------------------------------------------------------------------------
+ // relation function. Uses KeyToIndex
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ bool SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::findKeysForIndex(std::vector<BasicContainerInfo>::size_type nIndex, std::vector<Key_> & aKeys)
+ {
+ aKeys.clear();
+ m_aMapper.findKeysForIndex(nIndex,aKeys);
+ return !aKeys.empty();
+ }
+*///-----------------------------------------------------------------------------
+ // relation function. Uses KeyToIndex
+ template <class Key_, class KeyHash_, class KeyEq_, class KeyToIndex_>
+ void SpecialListenerContainer<Key_,KeyHash_,KeyEq_, KeyToIndex_>::implFillDisposer(DisposeNotifier& aNotifier, std::vector<BasicContainerInfo>::size_type nIndex)
+ {
+ if (cppu::OMultiTypeInterfaceContainerHelper* pMultiContainer = m_aContainers[nIndex].pContainer)
+ {
+ uno::Sequence< uno::Type > aTypes(pMultiContainer->getContainedTypes());
+ for (sal_Int32 ix = 0; ix < aTypes.getLength(); ++ix)
+ {
+ cppu::OInterfaceContainerHelper* pContainer = pMultiContainer->getContainer(aTypes[ix]);
+ OSL_ENSURE(pContainer,"No container, but the type ?");
+ if (pContainer)
+ aNotifier.appendAndClearContainer(pContainer);
+ }
+ }
+ std::vector<Key_> aKeys;
+ if (m_aMapper.findKeysForIndex(nIndex,aKeys))
+ {
+ for(typename std::vector<Key_>::iterator it = aKeys.begin(); it != aKeys.end(); ++it)
+ {
+ if (cppu::OInterfaceContainerHelper* pContainer = m_aSpecialHelper.aLC.getContainer(*it))
+ {
+ aNotifier.appendAndClearContainer(pContainer);
+ }
+ }
+ }
+ }
+//-----------------------------------------------------------------------------
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+ template <class Listener>
+ inline
+ void ListenerContainerIterator<Listener>::advance()
+ {
+ while (!m_xNext.is() && m_aIter.hasMoreElements())
+ {
+ m_xNext = m_xNext.query( m_aIter.next() );
+ }
+ }
+//-----------------------------------------------------------------------------
+
+ template <class Listener>
+ uno::Reference<Listener> ListenerContainerIterator<Listener>::next()
+ {
+ uno::Reference<Listener> xRet(m_xNext);
+ m_xNext.clear();
+ advance();
+ return xRet;
+ }
+//-----------------------------------------------------------------------------
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+ }
+}
+#endif // CONFIGMGR_API_LISTENERCONTAINER_HXX_
+
+
diff --git a/configmgr/source/api2/makefile.mk b/configmgr/source/api2/makefile.mk
new file mode 100644
index 000000000000..cb79cf0f3e5b
--- /dev/null
+++ b/configmgr/source/api2/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.11 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source$/inc
+PRJNAME=configmgr
+TARGET=api2
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/broadcaster.obj \
+ $(SLO)$/listenercontainer.obj \
+ $(SLO)$/provider.obj \
+ $(SLO)$/providerimpl.obj \
+ $(SLO)$/accessimpl.obj \
+ $(SLO)$/apiaccessobj.obj \
+ $(SLO)$/apiserviceinfo.obj \
+ $(SLO)$/apifactory.obj \
+ $(SLO)$/apifactoryimpl.obj \
+ $(SLO)$/apinodeaccess.obj \
+ $(SLO)$/apinodeupdate.obj \
+ $(SLO)$/apinotifierimpl.obj \
+ $(SLO)$/apitreeaccess.obj \
+ $(SLO)$/apitreeimplobj.obj \
+ $(SLO)$/confignotifier.obj \
+ $(SLO)$/committer.obj \
+ $(SLO)$/elementaccess.obj \
+ $(SLO)$/elementimpl.obj \
+ $(SLO)$/groupaccess.obj \
+ $(SLO)$/groupobjects.obj \
+ $(SLO)$/groupupdate.obj \
+ $(SLO)$/propertiesfilterednotifier.obj \
+ $(SLO)$/propertyinfohelper.obj \
+ $(SLO)$/propertysetaccess.obj \
+ $(SLO)$/propsetaccessimpl.obj \
+ $(SLO)$/setaccess.obj \
+ $(SLO)$/setobjects.obj \
+ $(SLO)$/setupdate.obj \
+ $(SLO)$/translatechanges.obj \
+ $(SLO)$/treeiterators.obj \
+ $(SLO)$/updateimpl.obj \
+
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/api2/notifierimpl.hxx b/configmgr/source/api2/notifierimpl.hxx
new file mode 100644
index 000000000000..c07ba10e3f9f
--- /dev/null
+++ b/configmgr/source/api2/notifierimpl.hxx
@@ -0,0 +1,241 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: notifierimpl.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_NOTIFIERIMPL_HXX_
+#define CONFIGMGR_API_NOTIFIERIMPL_HXX_
+
+#include "listenercontainer.hxx"
+
+#include "noderef.hxx"
+#include "valueref.hxx"
+
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/beans/XVetoableChangeListener.hpp>
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+#include <com/sun/star/beans/PropertyVetoException.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+
+#include "propertiesfilterednotifier.hxx"
+
+#include <vos/refernce.hxx>
+
+namespace configmgr
+{
+ namespace configapi
+ {
+// ---------------------------------------------------------------------------------------------------
+
+ struct SubNodeHash
+ {
+ size_t operator() (const configuration::SubNodeID& rKey) const {return rKey.hashCode();}
+ };
+ struct SubNodeEq
+ {
+ bool operator() (const configuration::SubNodeID& lhs,const configuration::SubNodeID& rhs) const {return lhs == rhs;}
+ };
+ struct SubNodeToIndex
+ {
+ rtl::Reference< configuration::Tree > aTree;
+
+ SubNodeToIndex( rtl::Reference< configuration::Tree > const& rTree ) : aTree(rTree) {}
+
+ bool findKeysForIndex(unsigned int nNode, std::vector<configuration::SubNodeID>& aList)
+ {
+ aList.clear();
+ configuration::getAllChildrenHelper(configuration::findNodeFromIndex(aTree,nNode), aList);
+ return !aList.empty();
+ }
+ unsigned int findIndexForKey(configuration::SubNodeID const& aNode)
+ {
+ return aNode.getParentID().toIndex();
+ }
+ };
+
+ /// manages collections of event listeners observing a whole config tree, thread-safe
+ class NotifierImpl : public vos::OReference
+ {
+ public:
+ SpecialListenerContainer <configuration::SubNodeID,SubNodeHash,SubNodeEq,SubNodeToIndex> m_aListeners;
+
+ public:
+ /// construct this around the given Implementation, for the given tree
+ explicit
+ NotifierImpl(rtl::Reference< configuration::Tree > const& aTree);
+ ~NotifierImpl();
+
+ /// Add a <type scope='com::sun::star::lang'>XEventListener</type> observing <var>aNode</var>.
+ void add(configuration::NodeID const& aNode, uno::Reference< css::lang::XEventListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+ /// Add a <type scope='com::sun::star::container'>XContainerListener</type> observing <var>aNode</var>.
+ void add(configuration::NodeID const& aNode, uno::Reference< css::container::XContainerListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+ /// Add a <type scope='com::sun::star::util'>XChangesListener</type> observing <var>aNode</var> and its descendants.
+ void add(configuration::NodeID const& aNode, uno::Reference< css::util::XChangesListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+ /// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
+ void addNamed(configuration::SubNodeID const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addSpecialListener(aNode,xListener.get());
+ }
+ /// Add a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
+ void addForAll(configuration::NodeID const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+ /// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void addNamed(configuration::SubNodeID const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addSpecialListener(aNode,xListener.get());
+ }
+ /// Add a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void addForAll(configuration::NodeID const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+ /** Add a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
+ observing all properties of <var>aNode</var>.
+ */
+ void add(configuration::NodeID const& aNode, uno::Reference< css::beans::XPropertiesChangeListener > const& xListener)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+
+ // ignore the names for now
+ m_aListeners.addListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+ /** Add a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
+ observing the properties of <var>aNode</var> (optimally only those given by <var>aNames</var>.
+ */
+ void add(configuration::NodeID const& aNode, uno::Reference< css::beans::XPropertiesChangeListener > const& xListener, uno::Sequence< rtl::OUString> const& aNames)
+ {
+ OSL_PRECOND(xListener.is(), "ERROR: Unexpected NULL listener");
+ OSL_PRECOND(aNames.getLength() > 0, "ERROR: Unexpected empty sequence");
+
+ uno::Reference< css::beans::XPropertiesChangeListener > xForwarder( new PropertiesFilteredNotifier(xListener,aNames) );
+ // ignore the names for now
+ add(aNode,xForwarder);
+ }
+
+ // ---------------------------------------------------------------------------------------------------
+ /// Remove a <type scope='com::sun::star::lang'>XEventListener</type> observing <var>aNode</var>.
+ void remove(configuration::NodeID const& aNode, uno::Reference< css::lang::XEventListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+ /// Remove a <type scope='com::sun::star::container'>XContainerListener</type> observing <var>aNode</var>.
+ void remove(configuration::NodeID const& aNode, uno::Reference< css::container::XContainerListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+ /// Remove a <type scope='com::sun::star::util'>XChangesListener</type> observing <var>aNode</var> and its descendants.
+ void remove(configuration::NodeID const& aNode, uno::Reference< css::util::XChangesListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+ /// Remove a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
+ void removeNamed(configuration::SubNodeID const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeSpecialListener(aNode,xListener.get());
+ }
+ /// Remove a <type scope='com::sun::star::beans'>XPropertyChangeListener</type> observing <var>aNode</var>.
+ void removeForAll(configuration::NodeID const& aNode, uno::Reference< css::beans::XPropertyChangeListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+ /// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void removeNamed(configuration::SubNodeID const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeSpecialListener(aNode,xListener.get());
+ }
+ /// Remove a <type scope='com::sun::star::beans'>XVetoableChangeListener</type> constraining <var>aNode</var>.
+ void removeForAll(configuration::NodeID const& aNode, uno::Reference< css::beans::XVetoableChangeListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+
+
+ /** Remove a <type scope='com::sun::star::beans'>XPropertiesChangeListener</type>
+ observing any properties of <var>aNode</var>.
+ */
+ void remove(configuration::NodeID const& aNode, uno::Reference< css::beans::XPropertiesChangeListener > const& xListener)
+ {
+ // ignore the names for now
+ m_aListeners.removeListener(aNode.toIndex(),getCppuType(&xListener),xListener.get());
+ }
+ // ---------------------------------------------------------------------------------------------------
+ };
+
+// ---------------------------------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_API_NOTIFIERIMPL_HXX_
diff --git a/configmgr/source/api2/objectregistry.hxx b/configmgr/source/api2/objectregistry.hxx
new file mode 100644
index 000000000000..4c159a4a7230
--- /dev/null
+++ b/configmgr/source/api2/objectregistry.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: objectregistry.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_OBJECTREGISTRY_HXX_
+#define CONFIGMGR_API_OBJECTREGISTRY_HXX_
+
+#include "noderef.hxx"
+
+#include <osl/mutex.hxx>
+#include <vos/refernce.hxx>
+
+#include <hash_map>
+#include "tracer.hxx"
+
+namespace configmgr
+{
+ namespace configapi
+ {
+
+ class NodeElement;
+
+ class ObjectRegistry : public vos::OReference
+ {
+ public:
+ static NodeElement* notFound() { return 0; }
+
+ struct KeyHash
+ {
+ size_t operator() (const configuration::NodeID& rKey) const {return rKey.hashCode();}
+ };
+ struct KeyEq
+ {
+ bool operator() (const configuration::NodeID& lhs,const configuration::NodeID& rhs) const {return lhs == rhs;}
+ };
+ typedef std::hash_map<configuration::NodeID,NodeElement*,KeyHash, KeyEq> ObjectMap;
+ public:
+ ObjectRegistry() {}
+ ~ObjectRegistry();
+
+ NodeElement* findElement(configuration::NodeID const& aNode) const
+ {
+ ObjectMap::const_iterator aFound = m_aMap.find(aNode);
+
+ return (aFound != m_aMap.end()) ? aFound->second : notFound();
+ }
+ void registerElement(configuration::NodeID const& aNode, NodeElement* aElement)
+ {
+ OSL_ENSURE(m_aMap.find(aNode) == m_aMap.end(), "ERROR: Node is already registered");
+
+ m_aMap[aNode] = aElement;
+ }
+ void revokeElement(configuration::NodeID const& aNode, NodeElement* aElement)
+ {
+ ObjectMap::iterator aFound = m_aMap.find(aNode);
+
+ if (aFound != m_aMap.end())
+ {
+ OSL_ENSURE(aFound->second == aElement,"Found unexpected element in map");
+
+ if (aFound->second == aElement)
+ m_aMap.erase(aFound);
+ }
+ }
+ private:
+ ObjectMap m_aMap;
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_API_FACTORY_HXX_
diff --git a/configmgr/source/api2/propertiesfilterednotifier.cxx b/configmgr/source/api2/propertiesfilterednotifier.cxx
new file mode 100644
index 000000000000..592e5be1c00b
--- /dev/null
+++ b/configmgr/source/api2/propertiesfilterednotifier.cxx
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertiesfilterednotifier.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "propertiesfilterednotifier.hxx"
+
+#include <cppuhelper/queryinterface.hxx>
+
+namespace configmgr
+{
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace beans = ::com::sun::star::beans;
+
+//-----------------------------------------------------------------------------
+// class PropertiesFilteredNotifier
+//-----------------------------------------------------------------------------
+
+PropertiesFilteredNotifier::PropertiesFilteredNotifier(
+ uno::Reference< beans::XPropertiesChangeListener >const& xTarget,
+ uno::Sequence< rtl::OUString > const& aFilterNames
+)
+: m_aRefCount()
+, m_xTarget(xTarget)
+, m_aFilterNames(aFilterNames)
+{
+ OSL_ENSURE(xTarget.is(),"PropertiesFilteredNotifier: FORWARDING TO NULL LISTENER");
+ OSL_ENSURE(aFilterNames.getLength() > 0,"PropertiesFilteredNotifier: FILTER IS EMPTY (no target)");
+}
+//-----------------------------------------------------------------------------
+
+PropertiesFilteredNotifier::~PropertiesFilteredNotifier()
+{
+}
+//-----------------------------------------------------------------------------
+
+void SAL_CALL PropertiesFilteredNotifier::acquire() throw()
+{
+ m_aRefCount.acquire();
+}
+//-----------------------------------------------------------------------------
+
+void SAL_CALL PropertiesFilteredNotifier::release( ) throw()
+{
+ if (m_aRefCount.release() == 0)
+ delete this;
+}
+//-----------------------------------------------------------------------------
+
+uno::Any SAL_CALL PropertiesFilteredNotifier::queryInterface( const uno::Type& aType )
+ throw(uno::RuntimeException)
+{
+ return cppu::queryInterface(aType
+ , static_cast< beans::XPropertiesChangeListener *>(this)
+ , static_cast< lang::XEventListener *>(this)
+ , static_cast< uno::XInterface *>(this)
+ );
+}
+//-----------------------------------------------------------------------------
+
+void SAL_CALL PropertiesFilteredNotifier::disposing( const lang::EventObject& Source )
+ throw(uno::RuntimeException)
+{
+ if (m_xTarget.is())
+ m_xTarget->disposing(Source);
+}
+//-----------------------------------------------------------------------------
+
+inline // private and only used twice
+bool PropertiesFilteredNotifier::implAccept(const ::com::sun::star::beans::PropertyChangeEvent& evt) const
+{
+ // todo: optimize by presorting and binary searching
+ sal_Int32 const nCount = m_aFilterNames.getLength();
+
+ for (sal_Int32 i = 0; i<nCount; ++i)
+ if (evt.PropertyName == m_aFilterNames[i])
+ return true;
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+// private and only used once
+uno::Sequence< beans::PropertyChangeEvent > PropertiesFilteredNotifier::implFilter(const uno::Sequence< beans::PropertyChangeEvent >& evt) const
+{
+ sal_Int32 const nSize = evt.getLength();
+ sal_Int32 nAccepted = 0;
+
+ while ( nAccepted < nSize && implAccept(evt[nAccepted]) )
+ ++nAccepted;
+
+ if (nAccepted == nSize) // all accepted
+ return evt;
+
+ // create a modified copy
+ uno::Sequence< beans::PropertyChangeEvent > aResult(evt);
+ for (sal_Int32 nCur = nAccepted+1; nCur<nSize; ++nCur)
+ {
+ if (implAccept(evt[nCur]))
+ {
+ aResult[nAccepted++] = evt[nCur];
+ }
+ }
+ aResult.realloc(nAccepted);
+ OSL_ASSERT(aResult.getLength() == nAccepted);
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+void SAL_CALL PropertiesFilteredNotifier::propertiesChange( const uno::Sequence< beans::PropertyChangeEvent >& evt )
+ throw(uno::RuntimeException)
+{
+ uno::Sequence< beans::PropertyChangeEvent > aFilteredEvt( implFilter(evt) );
+
+ if (aFilteredEvt.getLength() > 0)
+ {
+ if (m_xTarget.is())
+ m_xTarget->propertiesChange(aFilteredEvt);
+ }
+}
+//-----------------------------------------------------------------------------
+
+}
+
+
diff --git a/configmgr/source/api2/propertiesfilterednotifier.hxx b/configmgr/source/api2/propertiesfilterednotifier.hxx
new file mode 100644
index 000000000000..abda0df81114
--- /dev/null
+++ b/configmgr/source/api2/propertiesfilterednotifier.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertiesfilterednotifier.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_PROPERTIESFILTEREDNOTIFIER_HXX_
+#define CONFIGMGR_PROPERTIESFILTEREDNOTIFIER_HXX_
+
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+
+#include <vos/refernce.hxx>
+
+namespace configmgr
+{
+ class PropertiesFilteredNotifier
+ : public ::com::sun::star::beans::XPropertiesChangeListener
+ {
+ public:
+ PropertiesFilteredNotifier(
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener > const& xTarget,
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > const& aFilterNames
+ );
+ virtual ~PropertiesFilteredNotifier();
+
+ public:
+ virtual void SAL_CALL acquire( ) throw();
+ virtual void SAL_CALL release( ) throw();
+
+ virtual ::com::sun::star::uno::Any SAL_CALL
+ queryInterface( const ::com::sun::star::uno::Type& aType )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ disposing( const ::com::sun::star::lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException) ;
+
+ virtual void SAL_CALL
+ propertiesChange( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent >& evt )
+ throw(::com::sun::star::uno::RuntimeException);
+ private:
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent >
+ implFilter(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent >& evt)
+ const;
+
+ bool implAccept(const ::com::sun::star::beans::PropertyChangeEvent& evt) const;
+
+ ::vos::ORefCount m_aRefCount;
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener > m_xTarget;
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aFilterNames;
+ };
+}
+
+#endif // CONFIGMGR_PROPERTIESFILTEREDNOTIFIER_HXX_
+
diff --git a/configmgr/source/api2/propertyinfohelper.cxx b/configmgr/source/api2/propertyinfohelper.cxx
new file mode 100644
index 000000000000..b97b0362972d
--- /dev/null
+++ b/configmgr/source/api2/propertyinfohelper.cxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertyinfohelper.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "propertyinfohelper.hxx"
+#include "configpath.hxx"
+#include "attributes.hxx"
+
+#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HDL_
+#include <com/sun/star/beans/PropertyAttribute.hdl>
+#endif
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+ namespace beans = ::com::sun::star::beans;
+
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+beans::Property helperMakeProperty(rtl::OUString const& aName,
+ node::Attributes const aAttributes,
+ uno::Type const& aType,
+ bool bDefaultable )
+ throw(uno::RuntimeException)
+{
+ namespace PropertyAttribute = com::sun::star::beans::PropertyAttribute;
+
+ sal_Int16 nPropAttributes = 0;
+ if (aAttributes.isReadonly()) nPropAttributes |= PropertyAttribute::READONLY;
+ if (aAttributes.isNullable()) nPropAttributes |= PropertyAttribute::MAYBEVOID;
+ /*if ( aAttributes.bNotified)*/ nPropAttributes |= PropertyAttribute::BOUND;
+ /*if ( aAttributes.bConstrained)nPropAttributes |= PropertyAttribute::CONSTRAINED;*/
+
+ if ( aAttributes.isRemovable()) nPropAttributes |= PropertyAttribute::REMOVABLE;
+ if ( bDefaultable) nPropAttributes |= PropertyAttribute::MAYBEDEFAULT;
+
+ return beans::Property(aName, -1, aType, nPropAttributes);
+}
+//-----------------------------------------------------------------------------
+ }
+
+}
+
+
diff --git a/configmgr/source/api2/propertyinfohelper.hxx b/configmgr/source/api2/propertyinfohelper.hxx
new file mode 100644
index 000000000000..62476d1d73d8
--- /dev/null
+++ b/configmgr/source/api2/propertyinfohelper.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertyinfohelper.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_PROPERTYINFOIMPL_HXX_
+#define CONFIGMGR_API_PROPERTYINFOIMPL_HXX_
+
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+namespace configmgr
+{
+ namespace uno = ::com::sun::star::uno;
+ namespace beans = ::com::sun::star::beans;
+
+ /* implementations of the interfaces supported by a (parent) node
+ within the configuration tree.
+ (read-only operation)
+ */
+ namespace node { struct Attributes; }
+
+ namespace configapi
+ {
+ // translation helper
+ beans::Property helperMakeProperty( rtl::OUString const& aName, node::Attributes const aAttributes, uno::Type const& aType, bool bDefaultable )
+ throw(uno::RuntimeException);
+
+ }
+
+}
+#endif // CONFIGMGR_API_PROPERTYINFOIMPL_HXX_
+
+
diff --git a/configmgr/source/api2/propertysetaccess.cxx b/configmgr/source/api2/propertysetaccess.cxx
new file mode 100644
index 000000000000..b2954e03b1f5
--- /dev/null
+++ b/configmgr/source/api2/propertysetaccess.cxx
@@ -0,0 +1,278 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertysetaccess.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "propertysetaccess.hxx"
+#include "propsetaccessimpl.hxx"
+#include "apinotifierimpl.hxx"
+#include "apinodeaccess.hxx"
+#include "apinodeupdate.hxx"
+
+namespace configmgr
+{
+//////////////////////////////////////////////////////////////////////////////////
+// class BasicPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////
+// getting Property Metadata
+//////////////////////////////////////////////////////////////////////////////////
+
+// XPropertySet & XMultiPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+uno::Reference< beans::XPropertySetInfo > SAL_CALL BasicPropertySet::getPropertySetInfo( )
+ throw(uno::RuntimeException)
+{
+ return configapi::implGetPropertySetInfo( getNode(), NULL != maybeGetUpdateAccess() );
+}
+
+// XHierarchicalPropertySet & XHierarchicalMultiPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+uno::Reference< beans::XHierarchicalPropertySetInfo > SAL_CALL BasicPropertySet::getHierarchicalPropertySetInfo( )
+ throw(uno::RuntimeException)
+{
+ return configapi::implGetHierarchicalPropertySetInfo( getNode() );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// setting values - may all throw (PropertyVeto)Exceptions on read-only property sets
+//////////////////////////////////////////////////////////////////////////////////
+
+/// get the access for updating, check that it is present
+configapi::NodeGroupAccess& BasicPropertySet::getGroupNode()
+{
+ configapi::NodeGroupAccess* pAccess = maybeGetUpdateAccess();
+ OSL_ENSURE(pAccess, "Write operation invoked on a read-only node access - failing with PropertyVetoException");
+
+ if (!pAccess)
+ {
+ throw beans::PropertyVetoException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: INTERNAL VETO - Write operation invoked on a read-only node access")),
+ static_cast< beans::XPropertySet * >(this)
+ );
+ }
+ return *pAccess;
+}
+
+// XPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicPropertySet::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implSetPropertyValue( getGroupNode(), aPropertyName, aValue );
+}
+
+// XMultiPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicPropertySet::setPropertyValues( const uno::Sequence< rtl::OUString >& PropertyNames, const uno::Sequence< uno::Any >& Values )
+ throw(beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implSetPropertyValues( getGroupNode(), PropertyNames, Values );
+}
+
+// XHierarchicalPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicPropertySet::setHierarchicalPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implSetHierarchicalPropertyValue( getGroupNode(), aPropertyName, aValue );
+}
+
+// XMultiHierarchicalPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicPropertySet::setHierarchicalPropertyValues( const uno::Sequence< rtl::OUString >& PropertyNames, const uno::Sequence< uno::Any >& Values )
+ throw(beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implSetHierarchicalPropertyValues( getGroupNode(), PropertyNames, Values );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// getting values
+//////////////////////////////////////////////////////////////////////////////////
+// XPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+uno::Any SAL_CALL BasicPropertySet::getPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ return configapi::implGetPropertyValue( getNode(), aPropertyName );
+}
+
+// XMultiPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+uno::Sequence< uno::Any > SAL_CALL BasicPropertySet::getPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException)
+{
+ return configapi::implGetPropertyValues( getNode(), aPropertyNames );
+}
+
+// XHierarchicalPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+uno::Any SAL_CALL BasicPropertySet::getHierarchicalPropertyValue( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ return configapi::implGetHierarchicalPropertyValue( getNode(), aPropertyName );
+}
+
+// XMultiHierarchicalPropertySet
+//////////////////////////////////////////////////////////////////////////////////
+uno::Sequence< uno::Any > SAL_CALL BasicPropertySet::getHierarchicalPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException)
+{
+ return configapi::implGetHierarchicalPropertyValues( getNode(), aPropertyNames );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// adding/removing listeners
+//////////////////////////////////////////////////////////////////////////////////
+
+void SAL_CALL BasicPropertySet::addVetoableChangeListener( const rtl::OUString& aPropertyName, const uno::Reference< beans::XVetoableChangeListener >& xListener )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implAddListener( getNode(), xListener, aPropertyName );
+}
+
+void SAL_CALL BasicPropertySet::addPropertyChangeListener( const rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implAddListener( getNode(), xListener, aPropertyName );
+}
+
+void SAL_CALL BasicPropertySet::addPropertiesChangeListener( const uno::Sequence< rtl::OUString >& aPropertyNames, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implAddListener( getNode(), xListener, aPropertyNames );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicPropertySet::removeVetoableChangeListener( const rtl::OUString& aPropertyName, const uno::Reference< beans::XVetoableChangeListener >& xListener )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNode(), xListener, aPropertyName );
+}
+//---------------------------------------------------------------------------------
+
+void SAL_CALL BasicPropertySet::removePropertyChangeListener( const rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNode(), xListener, aPropertyName );
+}
+//---------------------------------------------------------------------------------
+
+void SAL_CALL BasicPropertySet::removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNode(), xListener );
+}
+//---------------------------------------------------------------------------------
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// SPECIAL: XMultiPropertySet::firePropertiesChangeEvent
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicPropertySet::firePropertiesChangeEvent( const uno::Sequence< rtl::OUString >& aPropertyNames, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implFirePropertiesChangeEvent( getNode(),aPropertyNames , xListener );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// XPropertyState / XMultiPropertyStates
+//////////////////////////////////////////////////////////////////////////////////
+
+// getting property states
+//////////////////////////////////////////////////////////////////////////////////
+
+beans::PropertyState SAL_CALL BasicPropertySet::getPropertyState( const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ return configapi::implGetPropertyState( getNode(), sPropertyName);
+}
+//---------------------------------------------------------------------------------
+
+uno::Sequence< beans::PropertyState > SAL_CALL BasicPropertySet::getPropertyStates( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ return configapi::implGetPropertyStates( getNode(), aPropertyNames );
+}
+//---------------------------------------------------------------------------------
+
+// setting to default state
+//////////////////////////////////////////////////////////////////////////////////
+
+void SAL_CALL BasicPropertySet::setPropertyToDefault( const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ configapi::implSetPropertyToDefault( getGroupNode(), sPropertyName);
+}
+//---------------------------------------------------------------------------------
+
+void SAL_CALL BasicPropertySet::setPropertiesToDefault( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw (beans::UnknownPropertyException, uno::RuntimeException)
+{
+ configapi::implSetPropertiesToDefault( getGroupNode(), aPropertyNames);
+}
+//---------------------------------------------------------------------------------
+
+void SAL_CALL BasicPropertySet::setAllPropertiesToDefault( )
+ throw (uno::RuntimeException)
+{
+ configapi::implSetAllPropertiesToDefault( getGroupNode() );
+}
+//---------------------------------------------------------------------------------
+
+// getting defaults
+//////////////////////////////////////////////////////////////////////////////////
+
+uno::Any SAL_CALL BasicPropertySet::getPropertyDefault( const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+
+{
+ return configapi::implGetPropertyDefault( getNode(), sPropertyName);
+}
+//---------------------------------------------------------------------------------
+
+uno::Sequence< uno::Any > SAL_CALL BasicPropertySet::getPropertyDefaults( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ return configapi::implGetPropertyDefaults( getNode(), aPropertyNames);
+}
+//---------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/propertysetaccess.hxx b/configmgr/source/api2/propertysetaccess.hxx
new file mode 100644
index 000000000000..7cf6356d3464
--- /dev/null
+++ b/configmgr/source/api2/propertysetaccess.hxx
@@ -0,0 +1,218 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertysetaccess.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_PROPERTYSET_HXX_
+#define CONFIGMGR_API_PROPERTYSET_HXX_
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/beans/XMultiPropertyStates.hpp>
+#include <cppuhelper/implbase6.hxx>
+
+namespace configmgr
+{
+/////////////////////////////////////////////////////////////////////////////////////////////
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+ namespace beans = css::beans;
+
+ namespace configapi
+ {
+ class NodeGroupAccess;
+ class NodeGroupInfoAccess;
+ }
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+/** implements the interfaces supported by a group node, viewed as a property set
+ within the configuration tree.
+ <p> Is an interface adapter around <type scope='configmgr::configapi'>NodeGroup(Info)Access</type>.</p>
+*/
+class BasicPropertySet
+: public ::cppu::ImplHelper6
+ < beans::XPropertySet
+ , beans::XMultiPropertySet
+ , beans::XHierarchicalPropertySet
+ , beans::XMultiHierarchicalPropertySet
+ , beans::XPropertyState
+ , beans::XMultiPropertyStates
+ >
+{
+protected:
+// Constructors & Destructors
+ virtual ~BasicPropertySet() {}
+
+public:
+// getting Property Metadata
+ // XPropertySet & XMultiPropertySet
+ virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo( )
+ throw(uno::RuntimeException);
+
+ // XHierarchicalPropertySet & XHierarchicalMultiPropertySet
+ virtual uno::Reference< beans::XHierarchicalPropertySetInfo > SAL_CALL
+ getHierarchicalPropertySetInfo( )
+ throw(uno::RuntimeException);
+
+// setting values - may all throw (PropertyVeto)Exceptions on read-only property sets
+ // XPropertySet
+ virtual void SAL_CALL
+ setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiPropertySet
+ virtual void SAL_CALL
+ setPropertyValues( const uno::Sequence< rtl::OUString >& PropertyNames, const uno::Sequence< uno::Any >& Values )
+ throw(beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XHierarchicalPropertySet
+ virtual void SAL_CALL
+ setHierarchicalPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiHierarchicalPropertySet
+ virtual void SAL_CALL
+ setHierarchicalPropertyValues( const uno::Sequence< rtl::OUString >& PropertyNames, const uno::Sequence< uno::Any >& Values )
+ throw(beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+// getting values
+ // XPropertySet
+ virtual uno::Any SAL_CALL
+ getPropertyValue( const rtl::OUString& PropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiPropertySet
+ virtual uno::Sequence< uno::Any > SAL_CALL
+ getPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException);
+
+ // XHierarchicalPropertySet
+ virtual uno::Any SAL_CALL
+ getHierarchicalPropertyValue( const rtl::OUString& PropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiHierarchicalPropertySet
+ virtual uno::Sequence< uno::Any > SAL_CALL
+ getHierarchicalPropertyValues( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException);
+
+// adding listeners
+ // XPropertySet
+ virtual void SAL_CALL
+ addPropertyChangeListener( const rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiPropertySet
+ virtual void SAL_CALL
+ addPropertiesChangeListener( const uno::Sequence< rtl::OUString >& aPropertyNames, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException);
+
+// removing listeners
+ // XPropertySet
+ virtual void SAL_CALL
+ removePropertyChangeListener( const rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiPropertySet
+ virtual void SAL_CALL
+ removePropertiesChangeListener( const uno::Reference< beans::XPropertiesChangeListener >& Listener )
+ throw(uno::RuntimeException);
+
+// SPECIAL: support for VetoableChangeListeners
+ // XPropertySet
+ virtual void SAL_CALL
+ addVetoableChangeListener( const rtl::OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeVetoableChangeListener( const rtl::OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+// SPECIAL: firePropertiesChangeEvent
+ // XMultiPropertySet
+ virtual void SAL_CALL
+ firePropertiesChangeEvent( const uno::Sequence< rtl::OUString >& aPropertyNames, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException);
+
+// XPropertyState
+ virtual beans::PropertyState SAL_CALL
+ getPropertyState( const rtl::OUString& PropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException);
+
+ // see below:
+ // virtual uno::Sequence< beans::PropertyState > SAL_CALL
+ // getPropertyStates( const uno::Sequence< rtl::OUString >& aPropertyName )
+ // throw(beans::UnknownPropertyException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyToDefault( const rtl::OUString& PropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException);
+
+ virtual uno::Any SAL_CALL
+ getPropertyDefault( const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+// XMultiPropertyStates
+ virtual uno::Sequence< beans::PropertyState > SAL_CALL
+ getPropertyStates( const uno::Sequence< rtl::OUString >& aPropertyName )
+ throw (beans::UnknownPropertyException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setAllPropertiesToDefault( )
+ throw (uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertiesToDefault( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw (beans::UnknownPropertyException, uno::RuntimeException);
+
+ virtual uno::Sequence< uno::Any > SAL_CALL
+ getPropertyDefaults( const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+protected:
+ virtual configapi::NodeGroupInfoAccess& getNode() = 0;
+ configapi::NodeGroupAccess& getGroupNode();
+ virtual configapi::NodeGroupAccess* maybeGetUpdateAccess() = 0;
+};
+
+//--------------------------------------------------------------------------
+
+}
+#endif // CONFIGMGR_API_PROPERTYSET_HXX_
+
+
diff --git a/configmgr/source/api2/propsetaccessimpl.cxx b/configmgr/source/api2/propsetaccessimpl.cxx
new file mode 100644
index 000000000000..b3cf5aa1a897
--- /dev/null
+++ b/configmgr/source/api2/propsetaccessimpl.cxx
@@ -0,0 +1,1287 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propsetaccessimpl.cxx,v $
+ * $Revision: 1.24.10.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "propsetaccessimpl.hxx"
+#include "propertyinfohelper.hxx"
+#include "apinodeaccess.hxx"
+#include "apinodeupdate.hxx"
+#include "noderef.hxx"
+#include "valueref.hxx"
+#include "anynoderef.hxx"
+#include "nodechange.hxx"
+#include "configgroup.hxx"
+#include "confignotifier.hxx"
+#include "broadcaster.hxx"
+#include "apitypes.hxx"
+#include "attributes.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <osl/diagnose.h>
+#include <cppuhelper/implbase1.hxx>
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+
+namespace configmgr
+{
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------------
+ namespace lang = css::lang;
+ namespace beans = css::beans;
+
+//-----------------------------------------------------------------------------------
+// a helper class
+//-----------------------------------------------------------------------------------
+
+class CollectProperties : configuration::NodeVisitor
+{
+ std::vector< beans::Property > m_aProperties;
+ sal_Bool m_bReadonly;
+public:
+ CollectProperties(sal_Bool _bReadonly)
+ : m_bReadonly(_bReadonly)
+ { }
+ CollectProperties(sal_Bool _bReadonly, sal_Int32 _nCount)
+ : m_bReadonly(_bReadonly)
+ { m_aProperties.reserve(_nCount); }
+
+ uno::Sequence<beans::Property> forChildren(rtl::Reference< configuration::Tree > const& _aPropertyTree, configuration::NodeRef const& _rNode)
+ {
+ OSL_ENSURE( _rNode.isValid() && _aPropertyTree->isValidNode(_rNode.getOffset()), "Node to retrieve properties from does not match tree");
+ reset();
+ _aPropertyTree->dispatchToChildren(_rNode, *this);
+ return makeSequence(m_aProperties);
+ }
+
+private:
+ void reset() { m_aProperties.clear(); }
+
+ node::Attributes adjustAttributes(node::Attributes nNodeAttr);
+
+ Result handle(rtl::Reference< configuration::Tree > const& _aTree, configuration::NodeRef const& _rValue);
+ Result handle(rtl::Reference< configuration::Tree > const& _aTree, configuration::ValueRef const& _rValue);
+};
+
+//-----------------------------------------------------------------------------------
+node::Attributes CollectProperties::adjustAttributes(node::Attributes nNodeAttr)
+{
+ if (m_bReadonly) nNodeAttr.markReadonly();
+
+ return nNodeAttr;
+}
+
+//-----------------------------------------------------------------------------------
+CollectProperties::Result CollectProperties::handle(rtl::Reference< configuration::Tree > const& _aTree, configuration::ValueRef const& _rValue)
+{
+ // can be default ?
+ m_aProperties.push_back(
+ helperMakeProperty( _rValue.m_sNodeName,
+ adjustAttributes(_aTree->getAttributes(_rValue)),
+ _aTree->getUnoType(_rValue),
+ _aTree->hasNodeDefault(_rValue)
+ )
+ );
+
+ return CONTINUE;
+}
+
+//-----------------------------------------------------------------------------------
+CollectProperties::Result CollectProperties::handle(rtl::Reference< configuration::Tree > const& _aTree, configuration::NodeRef const& _rNode)
+{
+ // can be default ?
+ OSL_ENSURE( configuration::isStructuralNode(_aTree,_rNode),
+ "Unexpected value element node. Cannot get proper type for this node as property" );
+
+ m_aProperties.push_back(
+ helperMakeProperty( _aTree->getSimpleNodeName(_rNode.getOffset()),
+ adjustAttributes(_aTree->getAttributes(_rNode)),
+ getUnoInterfaceType(),
+ _aTree->hasNodeDefault(_rNode)
+ )
+ );
+
+ return CONTINUE;
+}
+
+//-----------------------------------------------------------------------------------
+// yet another helper class (more robust, but can't well be extended to be a HierarchicalPropertySetInfo though)
+//-----------------------------------------------------------------------------------
+
+class NodePropertySetInfo
+ :public ::cppu::WeakImplHelper1< beans::XPropertySetInfo >
+{
+ uno::Sequence< beans::Property > const m_aProperties;
+
+public:
+ NodePropertySetInfo(uno::Sequence< beans::Property > const& _aProperties) throw(uno::RuntimeException)
+ : m_aProperties(_aProperties)
+ {
+ }
+
+ static NodePropertySetInfo* create(NodeGroupInfoAccess& _rNode, sal_Bool _bReadonly ) throw(uno::RuntimeException);
+ beans::Property const* begin() const throw() { return m_aProperties.getConstArray(); }
+ beans::Property const* end() const throw() { return m_aProperties.getConstArray() + m_aProperties.getLength(); }
+
+ beans::Property const* find(const rtl::OUString& _rPropertyName) const throw(uno::RuntimeException);
+
+ // XPropertySetInfo
+ virtual uno::Sequence< beans::Property > SAL_CALL getProperties() throw(uno::RuntimeException);
+ virtual beans::Property SAL_CALL getPropertyByName(const rtl::OUString& _rPropertyName) throw(beans::UnknownPropertyException, uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasPropertyByName(const rtl::OUString& _rPropertyName) throw(uno::RuntimeException);
+};
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+NodePropertySetInfo* NodePropertySetInfo::create(NodeGroupInfoAccess& _rNode, sal_Bool _bReadonly ) throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ rtl::Reference< configuration::Tree > aTree( _rNode.getTree() );
+ OSL_ENSURE( !configuration::isEmpty(aTree.get()), "WARNING: Getting Tree information requires a valid tree");
+ if (configuration::isEmpty(aTree.get())) return NULL;
+
+ configuration::NodeRef aNode( _rNode.getNodeRef() );
+ OSL_ENSURE( aNode.isValid() && aTree->isValidNode(aNode.getOffset()), "ERROR: Tree does not match node");
+
+ uno::Sequence< beans::Property > aProperties = CollectProperties(_bReadonly).forChildren(aTree,aNode);
+ OSL_ENSURE( aProperties.getLength() > 0, "ERROR: PropertySet (Configuration group) has no Properties");
+
+ return new NodePropertySetInfo( aProperties );
+}
+
+//-----------------------------------------------------------------------------------
+struct MatchName // : std::unary_function< beans::Property, bool >
+{
+ rtl::OUString sName;
+ MatchName(rtl::OUString const& _sName) throw(uno::RuntimeException)
+ : sName(_sName)
+ {
+ }
+
+ bool operator()(beans::Property const& _aProperty) const
+ {
+ return !!(_aProperty.Name == this->sName);
+ }
+};
+
+beans::Property const* NodePropertySetInfo::find(const rtl::OUString& _rPropertyName) const throw(uno::RuntimeException)
+{
+ beans::Property const* const first = this->begin();
+ beans::Property const* const last = this->end();
+
+ return std::find_if(first,last,MatchName(_rPropertyName));
+}
+
+//-----------------------------------------------------------------------------------
+uno::Sequence< beans::Property > SAL_CALL NodePropertySetInfo::getProperties() throw(uno::RuntimeException)
+{
+ return m_aProperties;
+}
+//-----------------------------------------------------------------------------------
+beans::Property SAL_CALL NodePropertySetInfo::getPropertyByName(const rtl::OUString& _rPropertyName)
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ beans::Property const* pFound = find(_rPropertyName);
+
+ if (pFound == this->end())
+ {
+ rtl::OUString sMessage = rtl::OUString::createFromAscii("Configuration - ");
+ sMessage += rtl::OUString::createFromAscii("No Property named '");
+ sMessage += _rPropertyName;
+ sMessage += rtl::OUString::createFromAscii("' in this PropertySetInfo");
+ throw beans::UnknownPropertyException(sMessage, static_cast<XPropertySetInfo*>(this));
+ }
+
+ return *pFound;
+}
+
+//-----------------------------------------------------------------------------------
+sal_Bool SAL_CALL NodePropertySetInfo::hasPropertyByName(const rtl::OUString& _rPropertyName)
+ throw(uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ beans::Property const* pFound = find(_rPropertyName);
+
+ return (pFound != this->end());
+}
+
+// Interface methods
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// getting Property Metadata
+//-----------------------------------------------------------------------------------
+
+// XPropertySet & XMultiPropertySet
+//-----------------------------------------------------------------------------------
+uno::Reference< beans::XPropertySetInfo > implGetPropertySetInfo( NodeGroupInfoAccess& rNode, sal_Bool _bWriteable )
+ throw(uno::RuntimeException)
+{
+ GuardedNodeData<NodeAccess> lock( rNode );
+ return NodePropertySetInfo::create(rNode, !_bWriteable);
+}
+
+// XHierarchicalPropertySet & XHierarchicalMultiPropertySet
+//-----------------------------------------------------------------------------------
+uno::Reference< beans::XHierarchicalPropertySetInfo > implGetHierarchicalPropertySetInfo( NodeGroupInfoAccess& /*rNode*/ )
+ throw(uno::RuntimeException)
+{
+ // TODO: Implement
+ return 0;
+}
+
+//-----------------------------------------------------------------------------------
+// setting values - may all throw (PropertyVeto)Exceptions on read-only property sets
+//-----------------------------------------------------------------------------------
+
+// XPropertySet
+//-----------------------------------------------------------------------------------
+void implSetPropertyValue( NodeGroupAccess& rNode, const rtl::OUString& sPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeGroupAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildName(sPropertyName,aTree,aNode);
+
+ configuration::ValueRef aChild( aTree->getChildValue(aNode, aChildName) );
+
+ if (!aChild.isValid())
+ {
+ if ( configuration::hasChildOrElement(aTree, aNode, aChildName) )
+ {
+ OSL_ENSURE(aTree->hasChildNode(aNode, aChildName),"ERROR: Configuration: Existing Property not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value.") );
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" Property '") );
+ sMessage += sPropertyName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' is not a simple value.") );
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::PropertyVetoException( sMessage, xContext );
+ }
+ else
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value.") );
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" Property '") );
+ sMessage += sPropertyName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+ }
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateSetValue( aChild, aValue );
+ if (aChange.test().isChange())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,true));
+
+ aSender.queryConstraints(aChange);
+
+ aTree->integrate(aChange, aNode, true);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::ConstraintViolation& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::PropertyVetoException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+// XMultiPropertySet
+//-----------------------------------------------------------------------------------
+void implSetPropertyValues( NodeGroupAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues )
+ throw(beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeGroupAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ configuration::NodeChanges aChanges;
+ for(sal_Int32 i = 0, count= aValues.getLength(); i < count; ++i)
+ {
+ rtl::OUString aChildName( aPropertyNames[i] ); // not validated
+
+ configuration::ValueRef aChild( aTree->getChildValue(aNode, aChildName) );
+
+ if (!aChild.isValid())
+ {
+ if ( configuration::hasChildOrElement(aTree, aNode, aChildName) )
+ {
+ OSL_ENSURE(aTree->hasChildNode(aNode, aChildName),"ERROR: Configuration: Existing Property not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Values.") );
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" Property '") );
+ sMessage += aChildName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' is not a simple value.") );
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::PropertyVetoException( sMessage, xContext );
+ }
+
+ OSL_TRACE("Configuration: MultiPropertySet: trying to set unknown property - ignored");
+ continue;
+ }
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateSetValue( aChild, aValues[i] );
+ if (aChange.maybeChange())
+ {
+ aChanges.add(aChange);
+ }
+ }
+
+ if (!aChanges.test().compact().isEmpty())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChanges,true));
+
+ aSender.queryConstraints(aChanges);
+
+ aTree->integrate(aChanges, aNode, true);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChanges, true);
+ }
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::ConstraintViolation& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::PropertyVetoException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+// XHierarchicalPropertySet
+//-----------------------------------------------------------------------------------
+void implSetHierarchicalPropertyValue( NodeGroupAccess& rNode, const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeGroupAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ configuration::RelativePath const aRelPath = configuration::validateRelativePath( aPropertyName, aTree, aNode );
+
+ configuration::AnyNodeRef aNestedValue = configuration::getLocalDescendant( aTree, aNode, aRelPath );
+
+ if (!aNestedValue.isValid())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value. Property '") );
+ sMessage += aRelPath.toString();
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' was not found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+ if (aNestedValue.isNode())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value. Property '") );
+ sMessage += aRelPath.toString();
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' is not a simple value property.") );
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::PropertyVetoException( sMessage, xContext );
+ }
+ OSL_ASSERT(aNode.isValid());
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateSetValue( aNestedValue.toValue(), aValue );
+ if (aChange.test().isChange())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,false));
+
+ aSender.queryConstraints(aChange);
+
+ aTree->integrate(aChange, aNode, false);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( e.message(), xContext );
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::ConstraintViolation& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::PropertyVetoException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+// XMultiHierarchicalPropertySet
+//-----------------------------------------------------------------------------------
+void implSetHierarchicalPropertyValues( NodeGroupAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames, const uno::Sequence< uno::Any >& aValues )
+ throw(beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeGroupAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ configuration::NodeChanges aChanges;
+ for(sal_Int32 i = 0, count= aValues.getLength(); i < count; ++i)
+ try
+ {
+ configuration::RelativePath aRelPath = configuration::validateRelativePath( aPropertyNames[i], aTree, aNode );
+
+ configuration::AnyNodeRef aNestedValue = configuration::getLocalDescendant( aTree, aNode, aRelPath );
+
+ if (!aNestedValue.isValid())
+ {
+ OSL_TRACE("Configuration: MultiPropertySet: trying to set unknown property - ignored");
+ continue;
+ }
+ if ( aNestedValue.isNode() )
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Values.") );
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" Property '") );
+ sMessage += aRelPath.toString();
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' is not a simple value property.") );
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::PropertyVetoException( sMessage, xContext );
+ }
+ OSL_ASSERT(aNode.isValid());
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateSetValue( aNestedValue.toValue(), aValues[i] );
+ if (aChange.maybeChange())
+ {
+ aChanges.add(aChange);
+ }
+ }
+ catch (configuration::InvalidName& )
+ {
+ OSL_TRACE("Configuration: MultiHierarchicalPropertySet: trying to set property <invalid path> - ignored");
+ continue;
+ }
+
+ if (!aChanges.test().compact().isEmpty())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChanges,false));
+
+ aSender.queryConstraints(aChanges);
+
+ aTree->integrate(aChanges, aNode, false);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChanges, true); // if we use 'false' we don't need 'Deep' change objects
+ }
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::ConstraintViolation& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Property Value: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::PropertyVetoException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// getting values
+//-----------------------------------------------------------------------------------
+
+// XPropertySet
+//-----------------------------------------------------------------------------------
+uno::Any implGetPropertyValue( NodeGroupInfoAccess& rNode,const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildName(aPropertyName,aTree,aNode);
+
+ configuration::AnyNodeRef aChild( aTree->getAnyChild(aNode, aChildName) );
+
+ if (!aChild.isValid())
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Property not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get Property Value. Property '") );
+ sMessage += aPropertyName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' could not be found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+
+ return configapi::makeElement( rNode.getFactory(), aTree, aChild );
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ // unreachable, but still there to make some compilers happy
+ OSL_ASSERT(!"Unreachable code");
+ return uno::Any();
+}
+
+// XMultiPropertySet
+//-----------------------------------------------------------------------------------
+uno::Sequence< uno::Any > implGetPropertyValues( NodeGroupInfoAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException)
+{
+ sal_Int32 const count = aPropertyNames.getLength();
+ uno::Sequence<uno::Any> aRet(count);
+
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ for(sal_Int32 i = 0; i < count; ++i)
+ {
+ rtl::OUString aChildName( aPropertyNames[i] ); // not validated
+
+ configuration::AnyNodeRef aChild( aTree->getAnyChild(aNode, aChildName) );
+
+ if (aChild.isValid())
+ {
+ aRet[i] = configapi::makeElement( rNode.getFactory(), aTree, aChild );
+ }
+ else
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Property not found by implementation");
+ OSL_TRACE("Configuration: MultiPropertySet: trying to get unknown property - returning void");
+ }
+ }
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return aRet;
+}
+
+// XHierarchicalPropertySet
+//-----------------------------------------------------------------------------------
+uno::Any implGetHierarchicalPropertyValue( NodeGroupInfoAccess& rNode, const rtl::OUString& aPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ configuration::RelativePath aRelPath = configuration::validateRelativePath( aPropertyName, aTree, aNode );
+
+ configuration::AnyNodeRef aNestedNode = configuration::getLocalDescendant( aTree, aNode, aRelPath );
+
+ if (!aNestedNode.isValid())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get Property Value. Property '") );
+ sMessage += aRelPath.toString();
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' could not be found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+ OSL_ASSERT(aNode.isValid());
+
+ return configapi::makeElement( rNode.getFactory(), aTree, aNestedNode );
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ // unreachable, but still there to make some compilers happy
+ OSL_ASSERT(!"Unreachable code");
+ return uno::Any();
+}
+
+// XMultiHierarchicalPropertySet
+//-----------------------------------------------------------------------------------
+uno::Sequence< uno::Any > implGetHierarchicalPropertyValues( NodeGroupInfoAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException)
+{
+ sal_Int32 const count = aPropertyNames.getLength();
+ uno::Sequence<uno::Any> aRet(count);
+
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ for(sal_Int32 i = 0; i < count; ++i)
+ try
+ {
+ configuration::RelativePath aRelPath = configuration::validateRelativePath( aPropertyNames[i], aTree, aNode );
+
+ configuration::AnyNodeRef aNestedValue = configuration::getLocalDescendant( aTree, aNode, aRelPath );
+
+ if (aNestedValue.isValid())
+ {
+ aRet[i] = configapi::makeElement( rNode.getFactory(), aTree, aNestedValue );
+ }
+ else
+ {
+ OSL_TRACE("Configuration: MultiPropertySet: trying to get unknown property - returning void");
+ }
+ }
+ catch (configuration::InvalidName& )
+ {
+ OSL_TRACE("Configuration: MultiPropertySet: trying to get property from unknown path - returning void");
+ OSL_ASSERT(!aRet[i].hasValue());
+ }
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return aRet;
+}
+
+//------------------------------------------------------------------------------------------------------------------
+// SPECIAL: XMultiPropertySet::firePropertiesChangeEvent
+//------------------------------------------------------------------------------------------------------------------
+
+void implFirePropertiesChangeEvent( NodeGroupInfoAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ OSL_ENSURE(xListener.is(), "ERROR: requesting to fire Events to a NULL listener.");
+ if (!xListener.is())
+ {
+ return; // should this be an exception ??
+ }
+
+ sal_Int32 const count = aPropertyNames.getLength();
+ uno::Sequence<beans::PropertyChangeEvent> aEvents(count);
+
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+ configapi::Factory& rFactory = rNode.getFactory();
+
+ sal_Int32 nFire = 0;
+
+ for(sal_Int32 i = 0; i < count; ++i)
+ {
+ rtl::OUString aChildName( aPropertyNames[i] ); // not validated
+
+ configuration::AnyNodeRef aChild( aTree->getAnyChild(aNode, aChildName) );
+
+ if (aChild.isValid())
+ {
+ aEvents[nFire].Source = rNode.getUnoInstance();
+ aEvents[nFire].PropertyName = aChildName;
+ aEvents[nFire].PropertyHandle = -1;
+
+ aEvents[nFire].NewValue = aEvents[nFire].OldValue = configapi::makeElement( rFactory, aTree, aChild );
+ nFire++;
+ }
+ else
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Property not found by implementation");
+ OSL_TRACE("Configuration: MultiPropertySet: request to fire unknown property - skipping");
+ }
+ }
+
+ if (nFire < count) aEvents.realloc(nFire);;
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ xListener->propertiesChange(aEvents);
+}
+
+//------------------------------------------------------------------------------------------------------------------
+// XPropertyState
+//------------------------------------------------------------------------------------------------------------------
+
+beans::PropertyState implGetPropertyState( NodeAccess& rNode, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildOrElementName(sPropertyName,aTree,aNode);
+
+ configuration::AnyNodeRef aChild = configuration::getChildOrElement(aTree,aNode,aChildName);
+ if (!aChild.isValid())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get PropertyState. Property '") );
+ sMessage += sPropertyName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+ OSL_ASSERT(aNode.isValid());
+
+ return aTree->isNodeDefault(aChild) ? beans::PropertyState_DEFAULT_VALUE :
+ aChild.isNode() ? beans::PropertyState_AMBIGUOUS_VALUE :
+ beans::PropertyState_DIRECT_VALUE;
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ // unreachable, but still there to make some compilers happy
+ OSL_ASSERT(!"Unreachable code");
+ return beans::PropertyState_AMBIGUOUS_VALUE;
+}
+
+//-----------------------------------------------------------------------------------
+uno::Sequence< beans::PropertyState > implGetPropertyStates( NodeAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ sal_Int32 const count = aPropertyNames.getLength();
+ uno::Sequence<beans::PropertyState> aRet(count);
+
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ for(sal_Int32 i = 0; i < count; ++i)
+ {
+ rtl::OUString aChildName = configuration::validateChildOrElementName(aPropertyNames[i],aTree,aNode);
+
+ rtl::Reference< configuration::Tree > aChildTree( aTree);
+
+ configuration::AnyNodeRef aChildNode = configuration::getChildOrElement(aChildTree,aNode,aChildName);
+ if (!aChildNode.isValid())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get PropertyStates. Property '") );
+ sMessage += aPropertyNames[i];
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' could not be found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+ OSL_ASSERT(aChildNode.isValid());
+
+ aRet[i] = aChildTree->isNodeDefault(aChildNode) ? beans::PropertyState_DEFAULT_VALUE :
+ aChildNode.isNode() ? beans::PropertyState_AMBIGUOUS_VALUE :
+ beans::PropertyState_DIRECT_VALUE;
+ }
+
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return aRet;
+}
+
+//-----------------------------------------------------------------------------------
+static inline configuration::NodeChange validateSetToDefaultHelper(configuration::GroupDefaulter& _rDefaulter, configuration::AnyNodeRef _aNode)
+{
+ if (!_aNode.isNode())
+ return _rDefaulter.validateSetToDefaultValue( _aNode.toValue() );
+
+ else
+ return _rDefaulter.validateSetToDefaultState( _aNode.toNode() );
+}
+//-----------------------------------------------------------------------------------
+void implSetPropertyToDefault( NodeGroupAccess& rNode, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ try
+ {
+ UnoApiLock aWithDefaultLock;
+ GuardedNodeUpdate<NodeGroupAccess> lock( withDefaultData( rNode ) );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ configuration::GroupDefaulter aDefaulter = lock.getNodeDefaulter();
+
+ rtl::OUString aChildName = configuration::validateChildName(sPropertyName,aTree,aNode);
+
+ configuration::AnyNodeRef aChild( aTree->getAnyChild(aNode, aChildName) );
+
+ configuration::NodeChange aChange = validateSetToDefaultHelper( aDefaulter, aChild );
+
+ const bool bLocal = !aDefaulter.hasDoneSet();
+
+ if (aChange.test().isChange() )
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,bLocal));
+
+ aSender.queryConstraints(aChange);
+
+ aTree->integrate(aChange, aNode, bLocal);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Default: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::ConstraintViolation & ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Default: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+//-----------------------------------------------------------------------------------
+void implSetPropertiesToDefault( NodeGroupAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException)
+{
+ try
+ {
+ UnoApiLock aWithDefaultLock;
+ GuardedNodeUpdate<NodeGroupAccess> lock( withDefaultData( rNode ) );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ configuration::GroupDefaulter aDefaulter = lock.getNodeDefaulter();
+
+ configuration::NodeChanges aChanges;
+ for(sal_Int32 i = 0, count= aPropertyNames.getLength(); i < count; ++i)
+ {
+ rtl::OUString aChildName = configuration::validateChildName( aPropertyNames[i], aTree, aNode ); // validated
+
+ configuration::AnyNodeRef aChild( aTree->getAnyChild(aNode, aChildName) );
+
+ if (!aChild.isValid())
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree, aNode, aChildName),"ERROR: Configuration: Existing Property not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Default.") );
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" Property '") );
+ sMessage += aChildName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+ OSL_ASSERT(aNode.isValid());
+
+ if (!aTree->hasNodeDefault(aChild))
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Default.") );
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" Property '") );
+ sMessage += aChildName;
+
+ if (aChild.isNode())
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' is not a simple value.") );
+
+ else
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' does not have a default value.") );
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+
+ configuration::NodeChange aChildChange = validateSetToDefaultHelper(aDefaulter, aChild );
+ if (aChildChange.maybeChange())
+ aChanges.add(aChildChange);
+ }
+
+ const bool bLocal = !aDefaulter.hasDoneSet();
+
+ if (!aChanges.test().compact().isEmpty())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChanges,bLocal));
+
+ aSender.queryConstraints(aChanges);
+
+ aTree->integrate(aChanges, aNode, bLocal);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChanges, bLocal);
+ }
+
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Defaults: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::ConstraintViolation & ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Defaults: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+//-----------------------------------------------------------------------------------
+void implSetAllPropertiesToDefault( NodeGroupAccess& rNode )
+ throw(uno::RuntimeException)
+{
+ try
+ {
+ UnoApiLock aWithDefaultLock;
+ GuardedNodeUpdate<NodeGroupAccess> lock( withDefaultData( rNode ) );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ configuration::GroupDefaulter aDefaulter = lock.getNodeDefaulter();
+
+ configuration::NodeChanges aChanges = aDefaulter.validateSetAllToDefault( );
+
+ const bool bLocal = !aDefaulter.hasDoneSet();
+
+ if (!aChanges.test().compact().isEmpty())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChanges,bLocal));
+
+ aSender.queryConstraints(aChanges);
+
+ aTree->integrate(aChanges, aNode, bLocal);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChanges, bLocal);
+ }
+
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Defaults: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::ConstraintViolation & ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Defaults: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+//-----------------------------------------------------------------------------------
+uno::Any implGetPropertyDefault( NodeGroupInfoAccess& rNode, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ uno::Any aDefault;
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildName(sPropertyName,aTree,aNode);
+
+ configuration::AnyNodeRef aChildNode = aTree->getAnyChild(aNode, aChildName);
+ if (!aChildNode.isValid())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get Default. Property '") );
+ sMessage += sPropertyName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+ OSL_ASSERT(aNode.isValid());
+
+ if (!aChildNode.isNode())
+ {
+ aDefault = aTree->getNodeDefaultValue(aChildNode.toValue());
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( e.message(), xContext );
+ }
+ catch (configuration::ConstraintViolation & ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get Default: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return aDefault;
+}
+
+//-----------------------------------------------------------------------------------
+uno::Sequence< uno::Any > implGetPropertyDefaults( NodeGroupInfoAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ sal_Int32 const count = aPropertyNames.getLength();
+ uno::Sequence<uno::Any> aDefaults(count);
+
+ try
+ {
+ GuardedNodeData<NodeAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ for(sal_Int32 i = 0; i < count; ++i)
+ {
+ rtl::OUString aChildName = configuration::validateChildName(aPropertyNames[i],aTree,aNode);
+
+ configuration::AnyNodeRef aChildNode = aTree->getAnyChild(aNode, aChildName);
+ if (!aChildNode.isValid())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get Default. Property '") );
+ sMessage += aPropertyNames[i];
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage, xContext );
+ }
+ OSL_ASSERT(aNode.isValid());
+
+ if (!aChildNode.isNode())
+ {
+ aDefaults[i] = aTree->getNodeDefaultValue(aChildNode.toValue());
+ }
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( e.message(), xContext );
+ }
+ catch (configuration::ConstraintViolation & ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot get Default: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw beans::UnknownPropertyException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return aDefaults;
+}
+
+//-----------------------------------------------------------------------------------
+ } // namespace configapi
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/propsetaccessimpl.hxx b/configmgr/source/api2/propsetaccessimpl.hxx
new file mode 100644
index 000000000000..6ad0fab4dd72
--- /dev/null
+++ b/configmgr/source/api2/propsetaccessimpl.hxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propsetaccessimpl.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_PROPERTYSETIMPL_HXX_
+#define CONFIGMGR_API_PROPERTYSETIMPL_HXX_
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
+
+#ifndef CONFIGMGR_NO_PROPERTYSTATE
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
+#include <com/sun/star/beans/XPropertyState.hpp>
+#endif
+#endif
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace beans = ::com::sun::star::beans;
+
+ /* implementations of the interfaces supported by a (parent) node
+ within the configuration tree.
+ (read-only operation)
+ */
+ namespace configapi
+ {
+ class NodeAccess;
+ class NodeGroupInfoAccess;
+ class NodeGroupAccess;
+
+ // getting Property Metadata
+ // XPropertySet & XMultiPropertySet
+ uno::Reference< beans::XPropertySetInfo > implGetPropertySetInfo( NodeGroupInfoAccess& rNode, sal_Bool _bWriteable )
+ throw(uno::RuntimeException);
+
+ // XHierarchicalPropertySet & XHierarchicalMultiPropertySet
+ uno::Reference< beans::XHierarchicalPropertySetInfo > implGetHierarchicalPropertySetInfo( NodeGroupInfoAccess& rNode )
+ throw(uno::RuntimeException);
+
+ // setting values - may all throw (PropertyVeto)Exceptions on read-only property sets
+ // XPropertySet
+ void implSetPropertyValue( NodeGroupAccess& rNode, const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiPropertySet
+ void implSetPropertyValues( NodeGroupAccess& rNode, const uno::Sequence< rtl::OUString >& PropertyNames, const uno::Sequence< uno::Any >& Values )
+ throw(beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XHierarchicalPropertySet
+ void implSetHierarchicalPropertyValue( NodeGroupAccess& rNode, const rtl::OUString& aPropertyName, const uno::Any& aValue )
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiHierarchicalPropertySet
+ void implSetHierarchicalPropertyValues( NodeGroupAccess& rNode, const uno::Sequence< rtl::OUString >& PropertyNames, const uno::Sequence< uno::Any >& Values )
+ throw(beans::PropertyVetoException, lang::IllegalArgumentException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // getting values
+ // XPropertySet
+ uno::Any implGetPropertyValue( NodeGroupInfoAccess& rNode,const rtl::OUString& PropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiPropertySet
+ uno::Sequence< uno::Any > implGetPropertyValues( NodeGroupInfoAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException);
+
+ // XHierarchicalPropertySet
+ uno::Any implGetHierarchicalPropertyValue( NodeGroupInfoAccess& rNode, const rtl::OUString& PropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiHierarchicalPropertySet
+ uno::Sequence< uno::Any > implGetHierarchicalPropertyValues( NodeGroupInfoAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(uno::RuntimeException);
+
+ // SPECIAL: firePropertiesChangeEvent
+ // XMultiPropertySet
+ void implFirePropertiesChangeEvent( NodeGroupInfoAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames, const uno::Reference< beans::XPropertiesChangeListener >& xListener )
+ throw(uno::RuntimeException);
+
+ // XPropertyState
+ beans::PropertyState implGetPropertyState( NodeAccess& rNode, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException);
+
+ void implSetPropertyToDefault( NodeGroupAccess& rNode, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException);
+
+ uno::Any implGetPropertyDefault( NodeGroupInfoAccess& rNode, const rtl::OUString& sPropertyName )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XMultiPropertyState
+ uno::Sequence< beans::PropertyState > implGetPropertyStates( NodeAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyName )
+ throw(beans::UnknownPropertyException, uno::RuntimeException);
+
+ void implSetPropertiesToDefault( NodeGroupAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(beans::UnknownPropertyException, uno::RuntimeException);
+
+ void implSetAllPropertiesToDefault( NodeGroupAccess& rNode )
+ throw(uno::RuntimeException);
+
+ uno::Sequence< uno::Any > implGetPropertyDefaults( NodeGroupInfoAccess& rNode, const uno::Sequence< rtl::OUString >& aPropertyNames )
+ throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException);
+ }
+
+}
+#endif // CONFIGMGR_API_PROPERTYSETIMPL_HXX_
+
+
diff --git a/configmgr/source/api2/provider.cxx b/configmgr/source/api2/provider.cxx
new file mode 100644
index 000000000000..0e81f3cf83ce
--- /dev/null
+++ b/configmgr/source/api2/provider.cxx
@@ -0,0 +1,714 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: provider.cxx,v $
+ * $Revision: 1.19 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "apiserviceinfo.hxx"
+#include "confapifactory.hxx"
+#include "configpath.hxx"
+#include "datalock.hxx"
+#include "provider.hxx"
+#include "providerimpl.hxx"
+#include "tracer.hxx"
+#include "bootstrap.hxx"
+#include "wrapexception.hxx"
+#include <osl/mutex.hxx>
+#include <rtl/ustrbuf.hxx>
+#ifndef __SGI_STL_ALGORITHM
+#include <algorithm>
+#endif
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <cppuhelper/typeprovider.hxx>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+ namespace beans = css::beans;
+
+ namespace
+ {
+ //------------------------------------------------------------------------
+ sal_Char const * const aConfigProviderServices[] =
+ {
+ "com.sun.star.configuration.ConfigurationProvider",
+ 0
+ };
+ sal_Char const * const aAdminProviderServices[] =
+ {
+ "com.sun.star.configuration.AdministrationProvider",
+ 0
+ };
+ //------------------------------------------------------------------------
+
+ ServiceImplementationInfo const aConfigProviderInfo =
+ {
+ "com.sun.star.comp.configuration.ConfigurationProvider",
+ aConfigProviderServices,
+ 0
+ };
+ ServiceImplementationInfo const aAdminProviderInfo =
+ {
+ "com.sun.star.comp.configuration.AdministrationProvider",
+ aAdminProviderServices,
+ aConfigProviderServices
+ };
+ //------------------------------------------------------------------------
+
+ sal_Char const * const
+ aDefaultProviderServiceAndImplName = A_DefaultProviderServiceAndImplName;
+
+ //------------------------------------------------------------------------
+
+ sal_Char const * const aDefaultProviderServices[] =
+ {
+ aDefaultProviderServiceAndImplName,
+ 0
+ };
+ //------------------------------------------------------------------------
+
+ ServiceRegistrationInfo const aDefaultProviderInfo =
+ {
+ aDefaultProviderServiceAndImplName,
+ aDefaultProviderServices
+ };
+ SingletonRegistrationInfo const aDefaultProviderSingletonInfo =
+ {
+ A_DefaultProviderSingletonName,
+ aDefaultProviderServiceAndImplName,
+ aDefaultProviderServiceAndImplName,
+ 0
+ };
+ //------------------------------------------------------------------------
+ typedef uno::Reference< uno::XInterface > (OProviderImpl::*CreatorFunc)(const uno::Sequence< uno::Any >& aArguments);
+ struct ServiceCreationInfo
+ {
+ ServiceRegistrationInfo const* info;
+ CreatorFunc create;
+ };
+
+ static sal_Int32 getCreateServiceDataCount()
+ {
+ return 2;
+ }
+
+ static const ServiceCreationInfo* getCreateServiceData()
+ {
+ static ServiceCreationInfo const createServiceData[] =
+ {
+ { &configapi::aCreateReadAccessSI, &OProviderImpl::createReadAccess },
+ { &configapi::aCreateUpdateAccessSI, &OProviderImpl::createUpdateAccess },
+ };
+ OSL_ENSURE(sizeof(createServiceData)/sizeof(createServiceData[0]) == getCreateServiceDataCount(),
+ "getCreateServiceData : inconsistent data !");
+ return createServiceData;
+ }
+ //------------------------------------------------------------------------
+ }
+
+ static ServiceCreationInfo const* findCreationInfo( const rtl::OUString& aServiceSpecifier )
+ {
+ for (int i= 0; i<getCreateServiceDataCount(); ++i)
+ {
+ ServiceCreationInfo const& rCreationInfo = getCreateServiceData()[i];
+
+ ServiceRegistrationInfo const* pInfo = rCreationInfo.info;
+ if (!pInfo)
+ continue;
+
+ if (sal_Char const * pImplName = pInfo->implementationName)
+ {
+ if (0 == aServiceSpecifier.compareToAscii(pImplName))
+ return &rCreationInfo;
+ }
+
+ if (sal_Char const * const* pNames = pInfo->registeredServiceNames)
+ {
+ while(*pNames)
+ {
+ if (0 == aServiceSpecifier.compareToAscii(*pNames))
+ return &rCreationInfo;
+
+ ++pNames;
+ }
+ }
+ }
+ // not found
+ return 0;
+ }
+
+ //#define ID_PREFETCH 1
+ static const int ID_PREFETCH=1;
+ static const int ID_ENABLEASYNC=2;
+
+ static inline
+ rtl::OUString getPrefetchPropName() { return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PrefetchNodes") ); }
+ static inline
+ rtl::OUString getEnableAsyncPropName() { return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("EnableAsync") ); }
+ //=============================================================================
+ //= OProvider
+ //=============================================================================
+ // service info export
+ const ServiceRegistrationInfo* getConfigurationProviderServiceInfo()
+ {
+ return getRegistrationInfo(&aConfigProviderInfo);
+ }
+
+ const ServiceRegistrationInfo* getAdminProviderServiceInfo()
+ {
+ return getRegistrationInfo(&aAdminProviderInfo);
+ }
+
+ const ServiceRegistrationInfo* getDefaultProviderServiceInfo()
+ {
+ return &aDefaultProviderInfo;
+ }
+
+ const SingletonRegistrationInfo* getDefaultProviderSingletonInfo()
+ {
+ return &aDefaultProviderSingletonInfo;
+ }
+
+ //-----------------------------------------------------------------------------
+ uno::Reference<uno::XInterface> SAL_CALL
+ getDefaultConfigProviderSingleton( uno::Reference< uno::XComponentContext > const& xContext )
+ {
+ OSL_ENSURE( xContext.is(), "ERROR: NULL context has no singletons" );
+
+ UnoContextTunnel aTunnel;
+ aTunnel.passthru( xContext );
+
+ uno::Reference<uno::XInterface> xResult;
+
+ if (xContext.is())
+ try
+ {
+ rtl::OUString aSingletonName = SINGLETON(A_DefaultProviderSingletonName);
+ uno::Any aResult = xContext->getValueByName(aSingletonName);
+ aResult >>= xResult;
+ }
+ catch (uno::Exception & )
+ {
+ // to do: really use the tunneled failure when that is set properly
+ if ( aTunnel.recoverFailure(true).hasValue() )
+ {
+ // have a failure, but can't recover it
+ // -> try to regenerate
+ instantiateDefaultProvider(xContext);
+
+ OSL_ENSURE(false, "Cannot recreate configuration backend instantiation failure - using generic error");
+ }
+ // cannot recover any failure
+ throw;
+ }
+
+ return xResult;
+ }
+ // ------------------------------------------------------------------------
+ // ----------------------------------------------------------------------------
+ #define TUNNEL_ALL_EXCEPTIONS() \
+ WRAP_CONFIGBACKEND_CREATION_EXCEPTIONS1( UnoContextTunnel::tunnelFailure, true)
+
+ // ----------------------------------------------------------------------------
+ // ------------------------------------------------------------------------
+
+ uno::Reference< uno::XInterface > SAL_CALL instantiateDefaultProvider( uno::Reference< uno::XComponentContext > const & xTargetContext )
+ {
+ uno::Reference< uno::XComponentContext > xContext = UnoContextTunnel::recoverContext(xTargetContext);
+
+ ServiceImplementationInfo const * pProviderInfo =
+ ContextReader::testAdminService(xContext,true) ? &aAdminProviderInfo : &aConfigProviderInfo;
+
+ OProvider* pNewProvider = new OProvider(xContext,pProviderInfo);
+ uno::Reference< lang::XMultiServiceFactory > aRet( pNewProvider );
+
+ try
+ {
+ pNewProvider->connect();
+ }
+ TUNNEL_ALL_EXCEPTIONS()
+
+ return uno::Reference< uno::XInterface >( aRet, uno::UNO_QUERY );
+ }
+
+ // -----------------------------------------------------------------------------
+ class OProviderDisposingListener : public cppu::WeakImplHelper1<lang::XEventListener>
+ {
+ OProvider* m_pProvider;
+
+ public:
+ OProviderDisposingListener(OProvider* pProvider)
+ :m_pProvider(pProvider){}
+
+ virtual void SAL_CALL disposing(com::sun::star::lang::EventObject const& rEvt) throw()
+ {
+ CFG_TRACE_INFO("Service Manager or context disposed, disposing the provider");
+ if (OProvider* pProvider = m_pProvider)
+ {
+ m_pProvider = NULL;
+ pProvider->disposing(rEvt);
+ }
+ }
+ };
+
+ //=============================================================================
+ //= OProvider
+ //=============================================================================
+ //-----------------------------------------------------------------------------
+ OProvider::OProvider(uno::Reference< uno::XComponentContext > const & xContext, ServiceImplementationInfo const* pInfo)
+ :ServiceComponentImpl(pInfo)
+ ,OPropertyContainer(ServiceComponentImpl::rBHelper)
+ ,m_xContext(xContext)
+ ,m_pImpl(NULL)
+ ,m_bEnableAsync(false)
+ {
+ OSL_ENSURE(m_xContext.is(), "Creating a provider without a context");
+ attachToContext();
+ registerProperty(getPrefetchPropName(), ID_PREFETCH, 0,&m_aPrefetchNodes, ::getCppuType(&m_aPrefetchNodes));
+ registerProperty(getEnableAsyncPropName(), ID_ENABLEASYNC, 0, &m_bEnableAsync, ::getBooleanCppuType());
+ }
+
+ //-----------------------------------------------------------------------------
+ OProvider::~OProvider()
+ {
+ delete m_pImpl;
+ discardContext(releaseContext());
+ }
+
+ //-----------------------------------------------------------------------------
+ void OProvider::connect() throw (uno::Exception)
+ {
+ OSL_ENSURE( m_pImpl == NULL, "Error: Configuration Provider already is connected");
+
+ std::auto_ptr<OProviderImpl> pNewImpl( new OProviderImpl(this, m_xContext) );
+
+ implConnect(*pNewImpl,ContextReader(m_xContext));
+
+ m_pImpl = pNewImpl.release();
+ if (m_pImpl)
+ {
+ sal_Bool isEnabled = m_pImpl->getDefaultOptions().isAsyncEnabled();
+ this->setPropertyValue( getEnableAsyncPropName(), uno::makeAny(isEnabled) );
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ void OProvider::attachToContext()
+ {
+ UnoApiLock aLock;
+ ::osl::MutexGuard aGuard(ServiceComponentImpl::rBHelper.rMutex);
+ OSL_ASSERT(!m_xDisposeListener.is());
+ if (m_xContext.is())
+ {
+ uno::Reference< lang::XComponent > xContextComp(m_xContext, uno::UNO_QUERY);
+ uno::Reference< lang::XComponent > xServiceMgrComp(m_xContext->getServiceManager(), uno::UNO_QUERY);
+
+ m_xDisposeListener = new OProviderDisposingListener(this);
+
+ if (xContextComp.is()) xContextComp ->addEventListener(m_xDisposeListener);
+ if (xServiceMgrComp.is()) xServiceMgrComp->addEventListener(m_xDisposeListener);
+
+ OSL_ENSURE(xServiceMgrComp.is() || xContextComp.is(),
+ "Provider cannot detect shutdown -> no XComponent found");
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ uno::Reference< lang::XComponent > OProvider::releaseContext()
+ {
+ UnoApiLock aLock;
+ ::osl::MutexGuard aGuard(ServiceComponentImpl::rBHelper.rMutex);
+
+ uno::Reference< lang::XComponent > xContextComp(m_xContext, uno::UNO_QUERY);
+ if (m_xDisposeListener.is() && m_xContext.is())
+ {
+ uno::Reference< lang::XComponent > xServiceMgrComp(m_xContext->getServiceManager(), uno::UNO_QUERY);
+
+ if (xContextComp.is())
+ {
+ try { xContextComp ->removeEventListener(m_xDisposeListener); }
+ catch (uno::Exception & ) {}
+ }
+
+ if (xServiceMgrComp.is())
+ {
+ try { xServiceMgrComp->removeEventListener(m_xDisposeListener); }
+ catch (uno::Exception & ) {}
+ }
+ }
+ m_xDisposeListener = NULL;
+ m_xContext = NULL;
+
+ return xContextComp;
+ }
+ //-----------------------------------------------------------------------------
+
+ void OProvider::discardContext(uno::Reference< lang::XComponent > const & xContext)
+ {
+ UnoApiLock aLock;
+ if (xContext.is())
+ {
+ uno::Reference< uno::XComponentContext > xCC(xContext,uno::UNO_QUERY);
+ OSL_ASSERT(xCC.is());
+
+ if (BootstrapContext::isWrapper(xCC))
+ {
+ try { xContext->dispose(); }
+ catch (uno::Exception & ) {}
+ }
+ }
+ }
+ //-----------------------------------------------------------------------------
+ // XTypeProvider
+ //-----------------------------------------------------------------------------
+ uno::Sequence< uno::Type > SAL_CALL OProvider::getTypes( ) throw(uno::RuntimeException)
+ {
+ cppu::OTypeCollection aCollection(::getCppuType( (const uno::Reference< beans::XPropertySet > *)0 ),
+ ::getCppuType( (const uno::Reference< beans::XFastPropertySet > *)0 ),
+ ::getCppuType( (const uno::Reference< beans::XMultiPropertySet > *)0 ),
+ ::comphelper::concatSequences(ServiceComponentImpl::getTypes(), cppu::ImplHelper4< lang::XMultiServiceFactory, lang::XLocalizable, util::XRefreshable, util::XFlushable >::getTypes()));
+ return aCollection.getTypes();
+ }
+
+ // XPropertySet
+ //-----------------------------------------------------------------------------
+ uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OProvider::getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException)
+ {
+ return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
+ }
+
+ //-----------------------------------------------------------------------------
+ uno::Reference< uno::XInterface > SAL_CALL OProvider::createInstance( const rtl::OUString& aServiceSpecifier )
+ throw(uno::Exception, uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+ // same as creating with empty sequence of arguments
+ return this->createInstanceWithArguments( aServiceSpecifier, uno::Sequence< uno::Any >() );
+ }
+
+ //-----------------------------------------------------------------------------
+ uno::Reference< uno::XInterface > SAL_CALL
+ OProvider::createInstanceWithArguments( const rtl::OUString& aServiceSpecifier, const uno::Sequence< uno::Any >& aArguments )
+ throw(uno::Exception, uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+
+ OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
+
+ if (ServiceCreationInfo const* pInfo = findCreationInfo(aServiceSpecifier))
+ {
+ // it's a known service name - try to create without args
+ if (CreatorFunc create = pInfo->create)
+ {
+ return (m_pImpl->*create)(aArguments);
+ }
+ }
+
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("ConfigurationProvider: Cannot create view - ");
+ sMsg.append( aServiceSpecifier ) .appendAscii(" is not a valid configuration access service. ");
+
+ throw lang::ServiceNotRegisteredException(sMsg.makeStringAndClear(),*this);
+ }
+
+ //-----------------------------------------------------------------------------
+ uno::Sequence< rtl::OUString > SAL_CALL OProvider::getAvailableServiceNames( )
+ throw(uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+
+ sal_Int32 nCount = 0;
+ {
+ for (int i= 0; i< getCreateServiceDataCount(); ++i)
+ nCount += countServices(getCreateServiceData()[i].info);
+ }
+
+ uno::Sequence< rtl::OUString > aNames(nCount);
+ if (nCount > 0)
+ {
+ sal_Int32 n = 0;
+ for (int i= 0; i<getCreateServiceDataCount(); ++i)
+ {
+ ServiceRegistrationInfo const* pInfo = getCreateServiceData()[i].info;
+ sal_Char const * const* pNames = pInfo ? pInfo->registeredServiceNames : 0;
+
+ if (pNames)
+ {
+ while(*pNames)
+ {
+ aNames[n] = rtl::OUString::createFromAscii(*pNames);
+ ++n;
+ ++pNames;
+ }
+ }
+ }
+ }
+
+ return aNames;
+ }
+
+ // XLocalizable
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::setLocale( const lang::Locale& eLocale )
+ throw (uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+
+ OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
+
+ m_pImpl->setDefaultLocale( eLocale );
+ }
+
+ //-----------------------------------------------------------------------------
+ lang::Locale SAL_CALL OProvider::getLocale()
+ throw (uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+
+ OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
+
+ return m_pImpl->getDefaultOptions().getUnoLocale();
+ }
+
+ //XRefreshable
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::refresh()
+ throw (uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+
+ OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
+
+ try
+ {
+ m_pImpl->refreshAll();
+ }
+ catch (uno::RuntimeException& ) { throw; }
+ catch (uno::Exception& e)
+ {
+ // FIXME: use getCaughtException()
+ throw lang::WrappedTargetRuntimeException(e.Message, *this, uno::makeAny(e));
+ }
+ //Broadcast the changes
+ uno::Reference< css::util::XRefreshListener > const * const pRefresh = 0;
+ cppu::OInterfaceContainerHelper * aInterfaceContainer=
+ getBroadcastHelper().getContainer (::getCppuType(pRefresh));
+
+ if(aInterfaceContainer)
+ {
+ lang::EventObject aEventObject(*this);
+
+ cppu::OInterfaceIteratorHelper aIterator(*aInterfaceContainer);
+ while(aIterator.hasMoreElements())
+ {
+ uno::Reference< uno::XInterface > xIface = aIterator.next();
+ uno::Reference< util::XRefreshListener > xRefresh (xIface, uno::UNO_QUERY);
+ if (xRefresh.is())
+ {
+ xRefresh->refreshed(aEventObject);
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::addRefreshListener(
+ const uno::Reference< util::XRefreshListener >& aListener )
+ throw (uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+ getBroadcastHelper().addListener(::getCppuType(&aListener), aListener);
+ }
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::removeRefreshListener(
+ const uno::Reference< util::XRefreshListener >& aListener )
+ throw (uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+ getBroadcastHelper().removeListener(::getCppuType(&aListener), aListener);
+ }
+ //XFlushable
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::flush( )
+ throw (uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+ OSL_ENSURE(m_pImpl, "OProvider: no implementation available");
+ m_pImpl->flushAll();
+
+ //Broadcast the changes
+ uno::Reference< css::util::XFlushListener > const * const pFlush = 0;
+ cppu::OInterfaceContainerHelper * aInterfaceContainer=
+ getBroadcastHelper().getContainer(::getCppuType(pFlush));
+
+ if(aInterfaceContainer)
+ {
+ lang::EventObject aEventObject(*this);
+
+ cppu::OInterfaceIteratorHelper aIterator(*aInterfaceContainer);
+ while(aIterator.hasMoreElements())
+ {
+ uno::Reference< uno::XInterface > xIface = aIterator.next();
+ uno::Reference< util::XFlushListener > xFlush (xIface, uno::UNO_QUERY);
+ if (xFlush.is())
+ {
+ xFlush->flushed(aEventObject);
+ }
+ }
+ }
+ }
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::addFlushListener(
+ const uno::Reference< util::XFlushListener >& aListener )
+ throw (uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+ getBroadcastHelper().addListener(::getCppuType(&aListener), aListener);
+ }
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::removeFlushListener(
+ const uno::Reference< util::XFlushListener >& aListener )
+ throw (uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+ getBroadcastHelper().removeListener(::getCppuType(&aListener), aListener);
+ }
+
+ // XInterface
+ //-----------------------------------------------------------------------------
+ uno::Any SAL_CALL OProvider::queryInterface(uno::Type const& rType) throw(uno::RuntimeException)
+ {
+ UnoApiLock aLock;
+ uno::Any aRet( ServiceComponentImpl::queryInterface(rType) );
+ if ( !aRet.hasValue() )
+ aRet = cppu::ImplHelper4< lang::XMultiServiceFactory, lang::XLocalizable, util::XRefreshable, util::XFlushable >::queryInterface(rType);
+ if ( !aRet.hasValue() )
+ aRet = queryPropertyInterface(rType);
+ return aRet;
+ }
+
+ //-----------------------------------------------------------------------------
+ void OProvider::implConnect(OProviderImpl& _rFreshProviderImpl, const ContextReader& _rSettings) throw(uno::Exception)
+ {
+ UnoApiLock aLock;
+ if (!_rFreshProviderImpl.initSession(_rSettings))
+ throw uno::Exception(::rtl::OUString::createFromAscii("Could not connect to the configuration. Please check your settings."), static_cast< ::cppu::OWeakObject* >(this) );
+ }
+
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::disposing(com::sun::star::lang::EventObject const& /*rEvt*/) throw()
+ {
+ UnoApiLock aLock;
+ releaseContext();
+ this->dispose();
+ }
+
+ //-----------------------------------------------------------------------------
+ void SAL_CALL OProvider::disposing()
+ {
+ UnoApiLock aLock;
+
+ if (m_pImpl)
+ m_pImpl->dispose();
+
+ uno::Reference< lang::XComponent > xComp = releaseContext();
+
+ ServiceComponentImpl::disposing();
+ OPropertyContainer::disposing();
+
+ discardContext( xComp );
+ }
+
+ // OPropertyArrayUsageHelper
+ // -------------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper* OProvider::createArrayHelper( ) const
+ {
+ UnoApiLock aLock;
+ uno::Sequence< beans::Property > aProps;
+ describeProperties(aProps);
+ return new ::cppu::OPropertyArrayHelper(aProps);
+ }
+ // -------------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper & OProvider::getInfoHelper()
+ {
+ UnoApiLock aLock;
+ return *getArrayHelper();
+ }
+
+ void SAL_CALL OProvider::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue)
+ throw (::com::sun::star::uno::Exception)
+ {
+ UnoApiLock aLock;
+
+ OPropertyContainer::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+
+ switch(nHandle)
+ {
+ case ID_PREFETCH:
+ {
+ uno::Sequence< rtl::OUString > aNodeList;
+ rValue >>= aNodeList;
+
+ RequestOptions const aOptions = m_pImpl->getDefaultOptions();
+
+ for (sal_Int32 i = 0; i < aNodeList.getLength(); i++)
+ {
+ configuration::AbsolutePath aModulePath = configuration::AbsolutePath::makeModulePath(aNodeList[i]);
+ m_pImpl->fetchSubtree(aModulePath , aOptions);
+ }
+ }break;
+
+ case ID_ENABLEASYNC:
+ {
+ //Forward to TreeManager
+ sal_Bool bAsync;
+ if (rValue >>= bAsync)
+ {
+ m_pImpl->enableAsync(bAsync);
+ if (!bAsync)
+ this->flush();
+ }
+ else
+ OSL_ENSURE(false, "Unexpected type of new property value");
+ }
+ break;
+ default:
+ {
+ OSL_ENSURE(false, "OProvider::setFastPropertyValue_NoBroadcast -unknown property");
+ }
+
+ }
+ }
+} // namespace configmgr
diff --git a/configmgr/source/api2/provider.hxx b/configmgr/source/api2/provider.hxx
new file mode 100644
index 000000000000..ab49b2d37ff7
--- /dev/null
+++ b/configmgr/source/api2/provider.hxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: provider.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_PROVIDER_HXX_
+#define CONFIGMGR_API_PROVIDER_HXX_
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/util/XRefreshable.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HDL_
+#include <com/sun/star/lang/IllegalArgumentException.hdl>
+#endif
+#include "confsvccomponent.hxx"
+#include <rtl/ustring.hxx>
+#include <vos/ref.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <comphelper/proparrhlp.hxx>
+#include <comphelper/propertycontainer.hxx>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+ namespace beans = css::beans;
+ namespace util = css::util;
+
+ class Module;
+ class ContextReader;
+ class OProviderImpl;
+
+ //==========================================================================
+ //= OProvider
+ //==========================================================================
+ /** Base class to receive access to the configuration data. A provider for configuration is
+ a factory for service which allow a readonly or update access to the configuration trees.
+ */
+ class OProvider:
+ private ServiceComponentImpl, private comphelper::OPropertyContainer,
+ public comphelper::OPropertyArrayUsageHelper< OProvider >
+ // don't want to allow our derivees to access the mutex of ServiceComponentImpl
+ // (this helps to prevent deadlocks: The mutex of the base class is used by the OComponentHelper to
+ // protect addEvenetListener calls. Unfortunately these calls are made from within API object we create,
+ // too, which can lead do deadlocks ....)
+ , public cppu::ImplHelper4< lang::XMultiServiceFactory, lang::XLocalizable, util::XRefreshable, util::XFlushable >
+ {
+ private:
+ friend class OProviderDisposingListener;
+
+ uno::Reference< uno::XComponentContext > m_xContext;
+ uno::Reference< lang::XEventListener > m_xDisposeListener;
+ OProviderImpl * m_pImpl;
+ uno::Sequence< ::rtl::OUString > m_aPrefetchNodes;
+ sal_Bool m_bEnableAsync;
+
+ public:
+ // make ServiceComponentImpl allocation functions public
+ static void * SAL_CALL operator new( size_t nSize ) throw()
+ { return ServiceComponentImpl::operator new( nSize ); }
+ static void SAL_CALL operator delete( void * pMem ) throw()
+ { ServiceComponentImpl::operator delete( pMem ); }
+
+ OProvider(uno::Reference< uno::XComponentContext > const & xContext, ServiceImplementationInfo const* pInfo);
+ virtual ~OProvider();
+
+ void connect() throw (uno::Exception);
+
+ /// XTypeOProvider
+ virtual uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw(uno::RuntimeException);
+
+ /// XInterface
+ virtual void SAL_CALL acquire() throw() { ServiceComponentImpl::acquire(); }
+ virtual void SAL_CALL release() throw() { ServiceComponentImpl::release(); }
+ virtual uno::Any SAL_CALL queryInterface(uno::Type const& rType) throw (uno::RuntimeException);
+
+ // XPropertySet
+ virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(uno::RuntimeException);
+
+ /// XMultiServiceFactory
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstance( const rtl::OUString& aServiceSpecifier )
+ throw(uno::Exception, uno::RuntimeException);
+
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const uno::Sequence< uno::Any >& Arguments )
+ throw(uno::Exception, uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getAvailableServiceNames( )
+ throw(uno::RuntimeException);
+
+ /// XLocalizable
+ virtual void SAL_CALL
+ setLocale( const lang::Locale& eLocale )
+ throw (uno::RuntimeException);
+
+ virtual lang::Locale SAL_CALL
+ getLocale( )
+ throw (uno::RuntimeException);
+
+
+ //XRefreshable
+ virtual void SAL_CALL
+ refresh( )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL
+ addRefreshListener(
+ const uno::Reference< util::XRefreshListener >& aListener )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL
+ removeRefreshListener(
+ const uno::Reference< util::XRefreshListener >& aListener )
+ throw (uno::RuntimeException);
+ //XFlushable
+ virtual void SAL_CALL
+ flush( )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL
+ addFlushListener(
+ const uno::Reference< util::XFlushListener >& aListener )
+ throw (uno::RuntimeException);
+ virtual void SAL_CALL
+ removeFlushListener(
+ const uno::Reference< util::XFlushListener >& aListener )
+ throw (uno::RuntimeException);
+
+ // OPropertSetHelper
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle, const uno::Any& rValue) throw (uno::Exception);
+
+ static sal_Int32 countServices(ServiceRegistrationInfo const* aInfo) { return ServiceRegistrationHelper(aInfo).countServices(); }
+
+ private:
+ // creates a new session
+ void implConnect(OProviderImpl& rFreshProviderImpl, const ContextReader& _rSettings) throw (uno::Exception);
+
+ // disambuiguated access
+ cppu::OBroadcastHelper & getBroadcastHelper()
+ { return ServiceComponentImpl::rBHelper; }
+
+ /// Component Helper override
+ virtual void SAL_CALL disposing();
+ virtual void SAL_CALL disposing(lang::EventObject const& rEvt) throw();
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // OPropertySetHelper
+ virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();
+
+ // OPropertyContainer
+ void registerProperty(const rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes,
+ void* _pPointerToMember, const uno::Type& _rMemberType)
+ { OPropertyContainer::registerProperty(_rName, _nHandle, _nAttributes, _pPointerToMember, _rMemberType);}
+
+ void describeProperties(uno::Sequence< beans::Property >& /* [out] */ _rProps) const
+ { OPropertyContainer::describeProperties(_rProps);}
+
+
+ uno::Any SAL_CALL queryPropertyInterface(uno::Type const& rType) throw (uno::RuntimeException)
+ { return OPropertyContainer::queryInterface(rType);}
+
+ void attachToContext();
+ uno::Reference< lang::XComponent > releaseContext();
+ void discardContext(uno::Reference< lang::XComponent > const & xContext);
+ };
+
+} // namespace configmgr
+
+#endif // CONFIGMGR_API_PROVIDER_HXX_
+
+
diff --git a/configmgr/source/api2/providerimpl.cxx b/configmgr/source/api2/providerimpl.cxx
new file mode 100644
index 000000000000..b13b392f74d4
--- /dev/null
+++ b/configmgr/source/api2/providerimpl.cxx
@@ -0,0 +1,896 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: providerimpl.cxx,v $
+ * $Revision: 1.69 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+#include "providerimpl.hxx"
+#include "options.hxx"
+#include "apifactoryimpl.hxx"
+#include "apitreeimplobj.hxx"
+#include "apitreeaccess.hxx"
+#include "roottree.hxx"
+#include "node.hxx"
+#include "noderef.hxx"
+#include "objectregistry.hxx"
+#include "bootstrap.hxx"
+#include "cachefactory.hxx"
+#include "provider.hxx"
+#include "treemanager.hxx"
+#include "tracer.hxx"
+#include <osl/interlck.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+
+#define RTL_LOGFILE_OU2A(rtlOUString) (::rtl::OUStringToOString((rtlOUString), RTL_TEXTENCODING_ASCII_US).getStr())
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace beans = css::beans;
+
+ namespace configapi
+ {
+
+ class ApiProviderInstances
+ {
+ rtl::Reference<ObjectRegistry> m_aObjectRegistry;
+ ReadOnlyObjectFactory m_aReaderFactory;
+ UpdateObjectFactory m_aWriterFactory;
+ ApiProvider m_aReaderProvider;
+ ApiProvider m_aWriterProvider;
+ public:
+ ApiProviderInstances(OProviderImpl& rProviderImpl)
+ : m_aObjectRegistry(new ObjectRegistry())
+ , m_aReaderFactory(m_aReaderProvider,m_aObjectRegistry)
+ , m_aWriterFactory(m_aWriterProvider,m_aObjectRegistry)
+ , m_aReaderProvider(m_aReaderFactory,rProviderImpl)
+ , m_aWriterProvider(m_aWriterFactory,rProviderImpl)
+ {
+ }
+
+ ~ApiProviderInstances()
+ {}
+
+ ApiProvider& getReaderProvider() { return m_aReaderProvider; }
+ ApiProvider& getWriterProvider() { return m_aWriterProvider; }
+ Factory& getReaderFactory() { return m_aReaderFactory; }
+ Factory& getWriterFactory() { return m_aWriterFactory; }
+ };
+ }
+
+ //=============================================================================
+
+ //=============================================================================
+ //= OProviderImpl
+ //=============================================================================
+ //-----------------------------------------------------------------------------
+ OProviderImpl::OProviderImpl(OProvider* _pProvider, uno::Reference< uno::XComponentContext > const & _xContext)
+ :m_pProvider(_pProvider)
+ ,m_xTypeConverter()
+ ,m_aDefaultOptions()
+ ,m_pNewProviders(NULL)
+ ,m_aTreeManagerMutex()
+ ,m_pTreeManager(NULL)
+ {
+ OSL_ENSURE(_xContext.is(), "OProviderImpl : NULL context !");
+
+ uno::Reference< lang::XMultiComponentFactory > xFactory = _xContext->getServiceManager();
+ OSL_ENSURE(xFactory.is(), "OProviderImpl : missing service factory !");
+
+ m_xTypeConverter = m_xTypeConverter.query(
+ xFactory->createInstanceWithContext( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" )),
+ _xContext));
+
+ OSL_ENSURE(m_xTypeConverter.is(), "Module::Module : could not create an instance of the type converter !");
+ }
+ //-----------------------------------------------------------------------------
+ rtl::Reference< TreeManager > OProviderImpl::maybeGetTreeManager() const SAL_THROW(())
+ {
+ osl::MutexGuard aGuard(m_aTreeManagerMutex);
+ rtl::Reference< TreeManager > xResult(m_pTreeManager);
+ return xResult;
+ }
+ //-----------------------------------------------------------------------------
+ rtl::Reference< TreeManager > OProviderImpl::getTreeManager() const SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ osl::MutexGuard aGuard(m_aTreeManagerMutex);
+ if (m_pTreeManager == NULL)
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("OProviderImpl: No cache available - provider was already disposed.");
+ throw com::sun::star::lang::DisposedException(sMsg,static_cast<lang::XMultiServiceFactory*>(m_pProvider));
+ }
+ rtl::Reference< TreeManager > xResult(m_pTreeManager);
+ return xResult;
+ }
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::setTreeManager(TreeManager * pTreeManager) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ osl::MutexGuard aGuard(m_aTreeManagerMutex);
+
+ OSL_PRECOND(m_pTreeManager == NULL, "OProviderImpl: TreeManager is already set");
+ OSL_PRECOND(pTreeManager != NULL, "OProviderImpl: Trying to set a NULL TreeManager");
+
+ if (pTreeManager == NULL)
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("OProviderImpl: No cache available - cache creation failed.");
+ throw com::sun::star::uno::RuntimeException(sMsg,NULL);
+ }
+
+ (m_pTreeManager = pTreeManager) -> acquire();
+ }
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::clearTreeManager() SAL_THROW(())
+ {
+ osl::ClearableMutexGuard aGuard(m_aTreeManagerMutex);
+ if (TreeManager * pTM = m_pTreeManager)
+ {
+ m_pTreeManager = NULL;
+ pTM->release();
+ }
+ }
+ //-----------------------------------------------------------------------------
+ bool OProviderImpl::initSession(const ContextReader& _rSettings)
+ {
+ bool bNeedProfile = false;
+ rtl::Reference< TreeManager > xNewTreeManager;
+ if (_rSettings.isUnoBackend())
+ {
+ this->implInitFromSettings(_rSettings,bNeedProfile);
+
+ xNewTreeManager = CacheFactory::instance().createCacheManager(_rSettings.getBaseContext());
+ }
+ else
+ {
+ throw com::sun::star::uno::RuntimeException(rtl::OUString::createFromAscii("OProviderImpl: Only UNO Backends Supported"),NULL);
+ }
+
+ setTreeManager( xNewTreeManager.get() );
+ OSL_ASSERT( xNewTreeManager.get() );
+
+ // put out of line to get rid of the order dependency (and to have a acquired configuration)
+ m_pNewProviders = new configapi::ApiProviderInstances(*this);
+
+ // now complete our state from the user's profile, if necessary
+ if (bNeedProfile)
+ try
+ {
+ static ::rtl::OUString ssUserProfile(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup"));
+ configuration::AbsolutePath aProfileModule = configuration::AbsolutePath::makeModulePath(ssUserProfile);
+
+ sharable::Node * profileTree = xNewTreeManager->requestSubtree(aProfileModule, m_aDefaultOptions);
+ if (profileTree != 0)
+ {
+ implInitFromProfile(profileTree);
+
+ // should we clean this up ?
+ // xNewTreeManager->releaseSubtree(aProfileModule, xTempOptions);
+ }
+ }
+ catch (uno::Exception& e)
+ {
+ // could not read profile
+ (void)e;
+ CFG_TRACE_ERROR_NI("Provider bootstrapping: Caught an exception trying to get 'Setup' data: %s", OUSTRING2ASCII(e.Message));
+ }
+
+ return true;
+ }
+ //-----------------------------------------------------------------------------
+
+ // these can be overridden. default does nothing
+ void OProviderImpl::initFromSettings(const ContextReader& , bool& )
+ {
+ }
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::initFromProfile(sharable::Node *)
+ {
+ }
+ //-----------------------------------------------------------------------------
+ // these implement the base class behavior
+ void OProviderImpl::implInitFromSettings(const ContextReader& _rSettings, bool& rNeedProfile)
+ {
+ bool bIntrinsicNeedProfile = true;
+
+ if (_rSettings.hasLocale())
+ {
+ bIntrinsicNeedProfile = false;
+ rtl::OUString sDefaultLocale = _rSettings.getLocale();
+ m_aDefaultOptions.setIsoLocale(sDefaultLocale);
+ }
+ else if (_rSettings.isAdminService())
+ {
+ bIntrinsicNeedProfile = false;
+ m_aDefaultOptions.setAllLocales();
+ }
+ else
+ OSL_ASSERT(!m_aDefaultOptions.hasLocale());
+
+ if (_rSettings.hasAsyncSetting())
+ {
+ m_aDefaultOptions.enableAsync( !!_rSettings.getAsyncSetting() );
+ }
+
+
+ // call the template method
+ this->initFromSettings(_rSettings, rNeedProfile);
+
+ if (bIntrinsicNeedProfile)
+ rNeedProfile = true; // to get locale
+ }
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::implInitFromProfile(sharable::Node * profile)
+ {
+ OSL_ASSERT(profile != 0);
+
+ sharable::GroupNode * profileNode = sharable::GroupNode::from(profile);
+
+ OSL_ASSERT(profileNode != 0);
+
+ // read the default locale for the user
+ if (!m_aDefaultOptions.hasLocale())
+ {
+ static rtl::OUString ssSubGroup(RTL_CONSTASCII_USTRINGPARAM("L10N"));
+ static rtl::OUString ssLocale(RTL_CONSTASCII_USTRINGPARAM("ooLocale"));
+
+ sharable::GroupNode * l10nNode = sharable::GroupNode::from(profileNode->getChild(ssSubGroup));
+ if (l10nNode != 0)
+ {
+ sharable::ValueNode * value = sharable::ValueNode::from(l10nNode->getChild(ssLocale));
+
+ if (value != 0)
+ {
+ rtl::OUString sDefaultLocale;
+ if (value->getValue() >>= sDefaultLocale)
+ {
+ m_aDefaultOptions.setIsoLocale(sDefaultLocale);
+ }
+ else
+ OSL_ENSURE(false, "Could not extract locale parameter into string");
+ }
+ }
+ }
+
+ // call the template method
+ this->initFromProfile(profile);
+
+ // last fallback, if there is no locale - even in ooLocale
+ m_aDefaultOptions.ensureLocaleSet();
+ }
+
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::setDefaultLocale( com::sun::star::lang::Locale const & aLocale )
+ {
+ m_aDefaultOptions.setLocale( aLocale );
+ // ensure that the locale is never cleared to 'empty'
+ m_aDefaultOptions.ensureLocaleSet();
+ }
+
+ //-----------------------------------------------------------------------------
+ OProviderImpl::~OProviderImpl()
+ {
+ UnoApiLock aLock; // hmm...
+ clearTreeManager();
+
+ delete m_pNewProviders;
+ }
+
+ // --------------------------------- disposing ---------------------------------
+ void SAL_CALL OProviderImpl::dispose() throw()
+ {
+ try
+ {
+ rtl::Reference< TreeManager > xTM = maybeGetTreeManager();
+
+ if (xTM.is())
+ xTM->dispose();
+
+ clearTreeManager();
+ }
+ catch (uno::Exception& e)
+ {
+ (void)e;
+ CFG_TRACE_ERROR("Disposing the TreeManager or closing the session caused an exception: %s", OUSTRING2ASCII(e.Message));
+ clearTreeManager();
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ // access to the raw notifications
+ TreeManager * OProviderImpl::getNotifier() SAL_THROW(())
+ {
+ rtl::Reference< TreeManager > xTM = maybeGetTreeManager();
+ return xTM.get();
+ }
+
+ // DefaultProvider access
+ //-----------------------------------------------------------------------------
+ rtl::Reference< TreeManager > OProviderImpl::getDefaultProvider() const SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ return getTreeManager().get();
+ }
+
+ //-----------------------------------------------------------------------------
+ sharable::Node * OProviderImpl::requestSubtree( configuration::AbsolutePath const& aSubtreePath,
+ RequestOptions const & _aOptions
+ ) SAL_THROW((com::sun::star::uno::Exception))
+ {
+ rtl::Reference< TreeManager > xTreeManager = getTreeManager();
+
+ sharable::Node * tree = 0;
+ try
+ {
+ tree = xTreeManager->requestSubtree(aSubtreePath, _aOptions);
+ }
+ catch(uno::Exception&e)
+ {
+ ::rtl::OUString sMessage = getErrorMessage(aSubtreePath, _aOptions);
+ // append the error message given by the tree provider
+ sMessage += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n\nThe backend returned the following error:\n"));
+ sMessage += e.Message;
+
+ throw lang::WrappedTargetException(sMessage, getProviderInstance(), uno::makeAny(e));
+ }
+
+ if (tree == 0)
+ {
+ ::rtl::OUString sMessage = getErrorMessage(aSubtreePath, _aOptions);
+
+ sMessage += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\n\nNo backend error message available\n"));
+
+ throw uno::Exception(sMessage, getProviderInstance());
+ }
+
+ return tree;
+ }
+
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::updateTree(TreeChangeList& aChanges) SAL_THROW((com::sun::star::uno::Exception))
+ {
+ getTreeManager()->updateTree(aChanges);
+ }
+
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::releaseSubtree( configuration::AbsolutePath const& aSubtreePath, RequestOptions const& _aOptions ) SAL_THROW(())
+ {
+ rtl::Reference< TreeManager > xTM = maybeGetTreeManager();
+ if (xTM.is())
+ xTM->releaseSubtree(aSubtreePath, _aOptions);
+ }
+
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::saveAndNotifyUpdate(TreeChangeList const& aChanges) SAL_THROW((com::sun::star::uno::Exception))
+ {
+ getTreeManager()->saveAndNotifyUpdate(aChanges);
+ }
+
+ //-----------------------------------------------------------------------------
+ void OProviderImpl::fetchSubtree(configuration::AbsolutePath const& aSubtreePath, RequestOptions const& _aOptions) SAL_THROW(())
+ {
+ rtl::Reference< TreeManager > xTM = maybeGetTreeManager();
+ if (xTM.is())
+ xTM->fetchSubtree(aSubtreePath, _aOptions);
+ }
+
+ //-----------------------------------------------------------------------------
+ sal_Bool OProviderImpl::fetchDefaultData(configuration::AbsolutePath const& aSubtreePath, RequestOptions const& _aOptions) SAL_THROW((com::sun::star::uno::Exception))
+ {
+ return getTreeManager()->fetchDefaultData(aSubtreePath, _aOptions);
+ }
+ //-----------------------------------------------------------------------------------
+ void OProviderImpl::refreshAll()SAL_THROW((com::sun::star::uno::Exception))
+ {
+ m_pTreeManager->refreshAll();
+ }
+ //-----------------------------------------------------------------------------------
+ void OProviderImpl::flushAll()SAL_THROW(())
+ {
+ m_pTreeManager->flushAll();
+ }
+ //-----------------------------------------------------------------------------------
+ void OProviderImpl::enableAsync(const sal_Bool& bEnableAsync) SAL_THROW(())
+ {
+ m_pTreeManager->enableAsync(bEnableAsync);
+ }
+ //-----------------------------------------------------------------------------
+ uno::XInterface* OProviderImpl::getProviderInstance()
+ {
+ return static_cast<com::sun::star::lang::XMultiServiceFactory*>(m_pProvider);
+ }
+
+ //-----------------------------------------------------------------------------------
+ rtl::OUString OProviderImpl::getErrorMessage(configuration::AbsolutePath const& _rAccessor, RequestOptions const& _aOptions)
+ {
+ rtl::OUString const sAccessor = _rAccessor.toString();
+
+ CFG_TRACE_ERROR("config provider: the cache manager could not provide the tree (neither from the cache nor from the session)");
+ ::rtl::OUString sMessage;
+ ::rtl::OUString sEntity(_aOptions.getEntity());
+ ::rtl::OUString sLocale(_aOptions.getLocale());
+ CFG_TRACE_INFO_NI("config provider: the entity we tried this for is \"%s\", the locale \"%s\", the path \"%s\"", OUSTRING2ASCII(sEntity), OUSTRING2ASCII(sLocale), OUSTRING2ASCII(sAccessor));
+ sMessage += sAccessor;
+
+ if (sEntity.getLength())
+ {
+ sMessage += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (and for entity "));
+ sMessage += sEntity;
+ sMessage += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ }
+
+ if (sLocale.getLength())
+ {
+ sMessage += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (and for locale "));
+ sMessage += sLocale;
+ sMessage += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
+ }
+
+ sMessage += ::rtl::OUString::createFromAscii(" could not be created. Unable to retrieve the node from the configuration server.");
+ return sMessage;
+ }
+
+ // actual factory methods
+ //-----------------------------------------------------------------------------------
+ configapi::NodeElement* OProviderImpl::buildReadAccess(rtl::OUString const& _rAccessor, RequestOptions const& _aOptions, sal_Int32 nMinLevels) SAL_THROW((com::sun::star::uno::Exception))
+ {
+ CFG_TRACE_INFO("config provider: requesting the tree from the cache manager");
+
+ OSL_ASSERT(sal_Int16(nMinLevels) == nMinLevels);
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::OProviderImpl", "jb99855", "configmgr::OProviderImpl::buildReadAccess()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "request path: %s", RTL_LOGFILE_OU2A(_rAccessor) );
+
+ try
+ {
+ configuration::AbsolutePath aAccessorPath = configuration::AbsolutePath::parse(_rAccessor);
+
+ sharable::Node * tree = requestSubtree(aAccessorPath,_aOptions);
+
+ RTL_LOGFILE_CONTEXT_TRACE(aLog, "data loaded" );
+
+ unsigned int nDepth = (nMinLevels == treeop::ALL_LEVELS) ? configuration::C_TreeDepthAll : (unsigned int)(nMinLevels);
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog2, "configmgr::OProviderImpl", "jb99855", "configmgr: createReadOnlyTree()");
+
+ rtl::Reference< configuration::Tree > aRootTree( configuration::createReadOnlyTree(
+ aAccessorPath, tree, nDepth,
+ configuration::TemplateProvider( getTreeManager(), _aOptions )
+ ));
+
+ return m_pNewProviders->getReaderFactory().makeAccessRoot(aRootTree, _aOptions);
+ }
+ catch (configuration::Exception& e)
+ {
+ configapi::ExceptionMapper ec(e);
+ ec.setContext(this->getProviderInstance());
+ //ec.unhandled();
+ throw lang::WrappedTargetException(ec.message(), ec.context(), uno::Any());
+ }
+ }
+
+
+ //-----------------------------------------------------------------------------------
+ configapi::NodeElement* OProviderImpl::buildUpdateAccess(rtl::OUString const& _rAccessor, RequestOptions const& _aOptions,
+ sal_Int32 nMinLevels) SAL_THROW((com::sun::star::uno::Exception))
+ {
+ CFG_TRACE_INFO("config provider: requesting the tree from the cache manager");
+ OSL_ASSERT(sal_Int16(nMinLevels) == nMinLevels);
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::OProviderImpl", "jb99855", "configmgr: buildUpdateAccess()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "request path: %s", RTL_LOGFILE_OU2A(_rAccessor) );
+
+ try
+ {
+ configuration::AbsolutePath aAccessorPath = configuration::AbsolutePath::parse(_rAccessor);
+
+ sharable::Node * tree = requestSubtree(aAccessorPath, _aOptions);
+
+ RTL_LOGFILE_CONTEXT_TRACE(aLog, "data loaded" );
+
+ unsigned int nDepth = (nMinLevels == treeop::ALL_LEVELS) ? configuration::C_TreeDepthAll : (unsigned int)(nMinLevels);
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog2, "configmgr::OProviderImpl", "jb99855", "createUpdatableTree()");
+
+ rtl::Reference< configuration::Tree > aRootTree( configuration::createUpdatableTree(
+ aAccessorPath, tree, nDepth,
+ configuration::TemplateProvider( getTreeManager(), _aOptions )
+ ));
+
+
+ return m_pNewProviders->getWriterFactory().makeAccessRoot(aRootTree, _aOptions);
+ }
+ catch (configuration::Exception& e)
+ {
+ configapi::ExceptionMapper ec(e);
+ ec.setContext(this->getProviderInstance());
+ //ec.unhandled();
+ throw lang::WrappedTargetException(ec.message(), ec.context(), uno::Any());
+ }
+ }
+
+ //=============================================================================
+ //= OProvider::FactoryArguments
+ //=============================================================================
+
+ sal_Char const * const OProviderImpl::FactoryArguments::asciiArgumentNames[] =
+ {
+ "nodepath", // ARG_NODEPATH, // requested node path
+ "depth", // ARG_DEPTH, // depth of the tree
+ "user", // ARG_USER_DEPRECATED, // name of the user - only for admin
+ "locale", // ARG_LOCALE, // desired locale
+ "nocache", // ARG_NOCACHE_OBSOLETE, // cache disabling
+ "lazywrite", // ARG_ASYNC_DEPRECATED, // lasy write data
+ "enableasync", // ARG_ASYNC, // lasy write data
+ "entity", // ARG_ENTITY, // name of the entity to be manipulated - only for admin
+ "reload", //ARG_REFRESH // refresh component
+
+ };
+
+ OProviderImpl::FactoryArguments::Argument
+ OProviderImpl::FactoryArguments::lookupArgument(const rtl::OUString& rName)
+ SAL_THROW(())
+ {
+ rtl::OUString sCheck( rName.toAsciiLowerCase() );
+
+ sal_Char const * const * const pFirst = asciiArgumentNames;
+ sal_Char const * const * const pLast = pFirst + _arg_count;
+
+ sal_Char const * const * it = pFirst;
+
+ for(; it != pLast; ++it)
+ {
+ if (0 == sCheck.compareToAscii(*it))
+ {
+ break;
+ }
+ }
+
+ OSL_ASSERT( Argument(pLast-pFirst) == ARG_NOT_FOUND );
+ return static_cast<Argument>(it - pFirst);
+ }
+
+ //-----------------------------------------------------------------------------------
+ bool OProviderImpl::FactoryArguments::extractOneArgument(
+ rtl::OUString const& aName, uno::Any const& aValue,
+ rtl::OUString& /* [out] */ _rNodeAccessor,
+ sal_Int32& /* [out] */ _nLevels,
+ RequestOptions& /* [in/out] */ _rOptions )
+ SAL_THROW(())
+ {
+ switch ( lookupArgument(aName) )
+ {
+ case ARG_NODEPATH:
+ {
+ rtl::OUString sStringVal;
+ if (aValue >>= sStringVal)
+ _rNodeAccessor = sStringVal;
+ else
+ return false;
+ }
+ break;
+
+ case ARG_DEPTH:
+ {
+ sal_Int32 nIntVal = 0;
+ if (aValue >>= nIntVal)
+ _nLevels = nIntVal;
+ else
+ return false;
+ }
+ break;
+
+ case ARG_ENTITY:
+ case ARG_USER_DEPRECATED:
+ {
+ rtl::OUString sStringVal;
+ if (aValue >>= sStringVal)
+ _rOptions.setEntity(sStringVal);
+ else
+ return false;
+ }
+ break;
+
+ case ARG_LOCALE:
+ {
+ rtl::OUString sStringVal;
+ if (aValue >>= sStringVal)
+ {
+ _rOptions.setIsoLocale(sStringVal);
+ break;
+ }
+
+ lang::Locale aLocale;
+ if (aValue >>= aLocale)
+ {
+ _rOptions.setLocale(aLocale);
+ break;
+ }
+
+ return false;
+ }
+
+ case ARG_NOCACHE_OBSOLETE:
+ {
+ sal_Bool bBoolVal;
+ if (aValue >>= bBoolVal)
+ OSL_ENSURE(false,"ConfigurationProvider: Parameter \"nocache\" is obsolete and has no effect");
+ else
+ return false;
+ }
+ break;
+
+ case ARG_ASYNC:
+ case ARG_ASYNC_DEPRECATED:
+ {
+ sal_Bool bBoolVal = sal_False;
+ if (aValue >>= bBoolVal)
+ _rOptions.enableAsync(!!bBoolVal);
+ else
+ return false;
+ }
+ break;
+ case ARG_REFRESH:
+ {
+ sal_Bool bBoolVal = sal_False;
+ if (aValue >>= bBoolVal)
+ _rOptions.forceRefresh(!!bBoolVal);
+ else
+ return false;
+ }
+ break;
+
+ case ARG_NOT_FOUND:
+ {
+ rtl::OString sMessage(RTL_CONSTASCII_STRINGPARAM("Unknown argument \""));
+ sMessage += rtl::OUStringToOString(aName, RTL_TEXTENCODING_ASCII_US);
+ sMessage += rtl::OString(RTL_CONSTASCII_STRINGPARAM("\" !\n- Parameter will be ignored -\n"));
+ CFG_TRACE_WARNING( "provider: %s", sMessage.getStr() );
+ #ifdef DBG_UTIL
+ OSL_ENSURE(false, sMessage.getStr());
+ #endif
+ }
+ break;
+
+ default:
+ CFG_TRACE_ERROR( "Known argument is not handled" );
+ OSL_ENSURE(false, "Known argument is not handled");
+ break;
+ }
+ return true;
+ }
+
+ //-----------------------------------------------------------------------------------
+ static
+ void failInvalidArg(uno::Any const & aArg, sal_Int32 _nArg = -1)
+ SAL_THROW((lang::IllegalArgumentException))
+ {
+ OSL_ENSURE( sal_Int16(_nArg) == _nArg, "Argument number out of range. Raising imprecise exception.");
+
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("Configuration Provider: An argument");
+ sMessage.appendAscii(" has the wrong type.");
+ sMessage.appendAscii("\n- Expected a NamedValue or PropertyValue");
+ sMessage.appendAscii("\n- Found type ").append( aArg.getValueType().getTypeName() );
+
+ throw lang::IllegalArgumentException( sMessage.makeStringAndClear(),
+ uno::Reference<uno::XInterface>(),
+ sal_Int16(_nArg+1));
+ }
+
+ //-----------------------------------------------------------------------------------
+ static
+ void failInvalidArgValue(rtl::OUString const & aName, uno::Any const & aValue, sal_Int32 _nArg = -1)
+ SAL_THROW((lang::IllegalArgumentException))
+ {
+ OSL_ENSURE( sal_Int16(_nArg) == _nArg, "Argument number out of range. Raising imprecise exception.");
+
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("Configuration Provider: The argument ").append(aName);
+ sMessage.appendAscii(" has the wrong type.");
+ sMessage.appendAscii("\n- Found type ").append( aValue.getValueType().getTypeName() );
+
+ throw lang::IllegalArgumentException( sMessage.makeStringAndClear(),
+ uno::Reference<uno::XInterface>(),
+ sal_Int16(_nArg+1));
+ }
+
+ //-----------------------------------------------------------------------------------
+ static
+ bool extractLegacyArguments( const uno::Sequence<uno::Any>& _rArgs,
+ rtl::OUString& /* [out] */ _rNodeAccessor,
+ sal_Int32& /* [out] */ _nLevels )
+ SAL_THROW((lang::IllegalArgumentException))
+ {
+ OSL_ASSERT( _rArgs.getLength() != 0 );
+
+ // compatibility : formerly, you could specify the node path as first arg and the (optional) depth
+ // as second arg
+ if (! (_rArgs[0] >>= _rNodeAccessor) )
+ return false;
+
+ switch (_rArgs.getLength() )
+ {
+ case 1:
+ // valid single argument
+ return true;
+
+ case 2:
+ // valid second argument
+ if (_rArgs[1] >>= _nLevels)
+ return true;
+
+ break;
+
+ default:
+ if (_rArgs[1] >>= _nLevels)
+ {
+ // valid second argument, but too many arguments altogether
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Configuration Provider: Too many arguments. "
+ "Additional arguments are not supported when passing the node path as string (deprecated convention).")),
+ uno::Reference<uno::XInterface>(),
+ sal_Int16(3)
+ );
+ }
+
+ break;
+
+ }
+ // here we have an invalid second argument
+
+ if (_rArgs[1].getValueTypeClass() != uno::TypeClass_STRUCT)
+ {
+ // completely invalid second argument
+ failInvalidArgValue(rtl::OUString::createFromAscii("<depth>"),_rArgs[1],1);
+ }
+
+ // Assume PropertyValue or NamedValue,
+ // which should be handled consistently by caller
+ return false;
+ }
+
+ //-----------------------------------------------------------------------------------
+ void OProviderImpl::FactoryArguments::extractArgs( const uno::Sequence<uno::Any>& _rArgs,
+ rtl::OUString& /* [out] */ _rNodeAccessor,
+ sal_Int32& /* [out] */ _nLevels,
+ RequestOptions & /* [in/out] */ _aOptions )
+ SAL_THROW((lang::IllegalArgumentException))
+ {
+ UnoApiLock aLock;
+
+ _nLevels = treeop::ALL_LEVELS; // setting a fallback
+
+ // the args have to be a sequence of property or named values
+ beans::NamedValue aNV;
+ beans::PropertyValue aPV;
+ for (sal_Int32 i=0; i<_rArgs.getLength(); ++i)
+ {
+ if (_rArgs[i] >>= aPV)
+ {
+ if ( !extractOneArgument(aPV.Name,aPV.Value,_rNodeAccessor,_nLevels,_aOptions) )
+ failInvalidArgValue(aPV.Name,aPV.Value,i);
+ }
+ else if (_rArgs[i] >>= aNV)
+ {
+ if ( !extractOneArgument(aNV.Name,aNV.Value,_rNodeAccessor,_nLevels,_aOptions) )
+ failInvalidArgValue(aNV.Name,aNV.Value,i);
+ }
+ else
+ {
+ if (i == 0)// try compatibility format
+ if ( extractLegacyArguments(_rArgs,_rNodeAccessor,_nLevels))
+ break;
+
+ failInvalidArg(_rArgs[i],i);
+ OSL_ASSERT(false);
+ }
+ }
+
+ if (_rNodeAccessor.getLength() == 0)
+ {
+ rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM("Configuration Provider: Missing argument: no nodepath was provided"));
+ throw lang::IllegalArgumentException(sMessage,uno::Reference<uno::XInterface>(),0);
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ uno::Reference<uno::XInterface> OProviderImpl::createReadAccess( uno::Sequence<uno::Any> const& aArgs)
+ SAL_THROW((com::sun::star::uno::Exception))
+ {
+ CFG_TRACE_INFO("config provider: going to create a read access instance");
+
+ // extract the args
+ rtl::OUString sPath;
+ sal_Int32 nLevels;
+
+ RequestOptions aOptions = getDefaultOptions();
+
+ OProviderImpl::FactoryArguments::extractArgs(aArgs, sPath, nLevels, aOptions);
+
+ CFG_TRACE_INFO_NI("config provider: node accessor extracted from the args is %s", OUSTRING2ASCII(sPath));
+ CFG_TRACE_INFO_NI("config provider: level depth extracted from the args is %i", nLevels);
+
+ // create the access object
+ uno::Reference< uno::XInterface > xReturn;
+
+ configapi::NodeElement* pElement = buildReadAccess(sPath, aOptions, nLevels);
+ if (pElement != 0)
+ {
+ xReturn = pElement->getUnoInstance();
+ if (xReturn.is())
+ // acquired once by buildReadAccess
+ xReturn->release();
+ }
+
+ return xReturn;
+ }
+
+ //-----------------------------------------------------------------------------------
+ uno::Reference<uno::XInterface> OProviderImpl::createUpdateAccess( uno::Sequence<uno::Any> const& aArgs)
+ SAL_THROW((com::sun::star::uno::Exception))
+ {
+ CFG_TRACE_INFO("config provider: going to create an update access instance");
+
+ // extract the args
+ rtl::OUString sPath;
+ sal_Int32 nLevels;
+
+ RequestOptions aOptions = getDefaultOptions();
+
+ OProviderImpl::FactoryArguments::extractArgs(aArgs, sPath, nLevels, aOptions);
+
+ CFG_TRACE_INFO_NI("config provider: node accessor extracted from the args is %s", OUSTRING2ASCII(sPath));
+ CFG_TRACE_INFO_NI("config provider: level depth extracted from the args is %i", nLevels);
+
+ // create the access object
+ uno::Reference< uno::XInterface > xReturn;
+
+ configapi::NodeElement* pElement = buildUpdateAccess(sPath, aOptions, nLevels);
+ if (pElement != 0)
+ {
+ xReturn = pElement->getUnoInstance();
+ if (xReturn.is())
+ // acquired once by buildReadAccess
+ xReturn->release();
+ }
+
+ return xReturn;
+ }
+//-----------------------------------------------------------------------------------
+
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/providerimpl.hxx b/configmgr/source/api2/providerimpl.hxx
new file mode 100644
index 000000000000..62d0f6cd0b86
--- /dev/null
+++ b/configmgr/source/api2/providerimpl.hxx
@@ -0,0 +1,231 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: providerimpl.hxx,v $
+ * $Revision: 1.21 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_PROVIDERIMPL_HXX_
+#define CONFIGMGR_API_PROVIDERIMPL_HXX_
+
+#include "defaultprovider.hxx"
+#include "requestoptions.hxx"
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <osl/mutex.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace uno
+ {
+ class Any;
+ class XInterface;
+ template <class> class Sequence;
+ template <class> class Reference;
+ }
+ namespace beans
+ {
+ struct PropertyValue;
+ }
+} } }
+
+namespace rtl
+{
+ class OUString;
+ template <class RCType> class Reference;
+}
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace script = css::script;
+ namespace lang = css::lang;
+ namespace beans = css::beans;
+
+ class ISubtree;
+ struct TreeChangeList;
+ class TreeManager;
+ class ContextReader;
+ class OProvider;
+
+ namespace configapi
+ {
+ class NodeElement;
+ class ApiProviderInstances;
+ class Factory;
+ }
+ namespace sharable { union Node; }
+
+ // -----------------------------------------------------------------------------
+ class OProviderImpl : public IDefaultableTreeManager
+ {
+ friend class OProvider;
+ public:
+ //==========================================================================
+ //= FactoryArguments
+ //==========================================================================
+ /** Helper class for evaluation of the arguments for creating a service instance.*/
+ struct FactoryArguments
+ {
+ /// possible arguments, given only in small letters.
+ enum Argument
+ {
+ ARG_NODEPATH, // requested node path
+ ARG_DEPTH, // depth of the tree
+ ARG_USER_DEPRECATED, // name of the entity to be manipulated - deprecated version
+ ARG_LOCALE, // desired locale
+ ARG_NOCACHE_OBSOLETE, // cache disabling - obsolete and nonfunctional
+ ARG_ASYNC_DEPRECATED, // lasy write data - deprecated version
+ ARG_ASYNC, // lazy write data
+ ARG_ENTITY, // name of the entity to be manipulated - only for admin
+ ARG_REFRESH, // force refresh of data into cache
+
+ _arg_count,
+ ARG_NOT_FOUND = _arg_count
+ };
+ static sal_Char const * const asciiArgumentNames[];
+
+ static Argument lookupArgument(rtl::OUString const& sArgumentName) SAL_THROW(());
+ public:
+ /** extracts arguments from the argument sequence into to the parameter variables
+
+ <p>unknown arguments are ignored</p>
+
+ @throws com::sun::star::lang::IllegalArgumentException
+ if an element of _rArgs had the wrong type or
+ if the value of a known argument has the wrong type or
+ if the value of a known argument is out of range (sometimes)
+ or if no non-empty node path argument could be extracted,
+ */
+ static void extractArgs( const uno::Sequence<uno::Any>& _rArgs,
+ rtl::OUString& /* [out] */ _rNodeAccessor,
+ sal_Int32& /* [out] */ _nLevels,
+ RequestOptions& /* [in/out] */ xOptions)
+ SAL_THROW((lang::IllegalArgumentException));
+
+ static bool extractOneArgument( rtl::OUString const& aName, uno::Any const& aValue,
+ rtl::OUString& /* [out] */ _rNodeAccessor,
+ sal_Int32& /* [out] */ _nLevels,
+ RequestOptions& /* [in/out] */ xOptions
+ ) SAL_THROW(());
+
+ };
+
+ private:
+ OProvider* m_pProvider; /// used for ref counting, uno representation
+
+ uno::Reference< script::XTypeConverter > m_xTypeConverter;
+ RequestOptions m_aDefaultOptions;
+ configapi::ApiProviderInstances* m_pNewProviders;
+ mutable osl::Mutex m_aTreeManagerMutex;
+ TreeManager* m_pTreeManager; /// the tree cache. Will hold a reference to us as long as it life
+
+ rtl::Reference< TreeManager > maybeGetTreeManager() const SAL_THROW(());
+ rtl::Reference< TreeManager > getTreeManager() const SAL_THROW((com::sun::star::uno::RuntimeException));
+ void setTreeManager(TreeManager * pTreeManager) SAL_THROW((com::sun::star::uno::RuntimeException));
+ void clearTreeManager() SAL_THROW(());
+
+ OProviderImpl(OProvider* _pProvider,
+ uno::Reference< uno::XComponentContext > const & xContext);
+
+ public:
+ virtual ~OProviderImpl();
+
+ /** request that the tree named by a path is added to the collection of managed trees
+ respecting certain options and requiring a specific loading depth.
+ Return a reference to that managed tree.
+ The reference must later be released by calling releaseSubtree with the same path and options.
+ */
+ sharable::Node * requestSubtree(configuration::AbsolutePath const& aSubtreePath, const RequestOptions& _aOptions) SAL_THROW((com::sun::star::uno::Exception));
+
+ /// update the managed data according to a changes list - update the changes list accordingly with old values
+ void updateTree(TreeChangeList& aChanges) SAL_THROW((com::sun::star::uno::Exception));
+
+ // bookkeeping support
+ void releaseSubtree( configuration::AbsolutePath const& aSubtreePath, const RequestOptions& _aOptions ) SAL_THROW(());
+
+ // notification
+ void saveAndNotifyUpdate(TreeChangeList const& aChanges) SAL_THROW((com::sun::star::uno::Exception));
+
+ /** request that the tree named by a path is added to the collection of managed trees
+ respecting certain options and requiring a specific loading depth.
+ */
+ void fetchSubtree(configuration::AbsolutePath const& aSubtreePath, const RequestOptions& _aOptions) SAL_THROW(());
+
+ //Refresh all components in the cache
+ void refreshAll() SAL_THROW((com::sun::star::uno::Exception));
+
+ //Flush all components in the cache
+ void flushAll() SAL_THROW(());
+
+ //Enable/Disable Asynchronous write-back to cache
+ void enableAsync(const sal_Bool& bEnableAsync) SAL_THROW(());
+
+ /// IDefaultableTreeManager
+ virtual sal_Bool fetchDefaultData(configuration::AbsolutePath const& aSubtreePath, const RequestOptions& _aOptions
+ ) SAL_THROW((com::sun::star::uno::Exception));
+
+ // DefaultProvider access
+ rtl::Reference< TreeManager > getDefaultProvider() const SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ protected:
+ static rtl::OUString getErrorMessage(configuration::AbsolutePath const& _rAccessor, const RequestOptions& _aOptions);
+
+ void SAL_CALL dispose() throw();
+ public:
+ void setDefaultLocale( com::sun::star::lang::Locale const & aLocale );
+
+ RequestOptions const& getDefaultOptions() const {return m_aDefaultOptions;}
+ uno::Reference< script::XTypeConverter > getTypeConverter() const {return m_xTypeConverter;}
+ TreeManager * getNotifier() SAL_THROW(());
+ uno::XInterface* getProviderInstance();
+
+ // actual factory methods
+ // the returned object (if any) has to be acquired once)
+ configapi::NodeElement* buildReadAccess( rtl::OUString const& _rAccessor, const RequestOptions& _aOptions, sal_Int32 nMinLevels) SAL_THROW((com::sun::star::uno::Exception));
+ // the returned object (if any) has to be acquired once)
+ configapi::NodeElement* buildUpdateAccess(rtl::OUString const& _rAccessor, const RequestOptions& _aOptions, sal_Int32 nMinLevels) SAL_THROW((com::sun::star::uno::Exception));
+ // factory methods
+ uno::Reference<uno::XInterface> createReadAccess( uno::Sequence<uno::Any> const& aArgs) SAL_THROW((com::sun::star::uno::Exception));
+ uno::Reference<uno::XInterface> createUpdateAccess( uno::Sequence<uno::Any> const& aArgs) SAL_THROW((com::sun::star::uno::Exception));
+
+ private:
+ bool initSession(const ContextReader& _rSettings);
+ private:
+ void implInitFromSettings(const ContextReader& _rSettings, bool& rNeedProfile);
+ void implInitFromProfile(sharable::Node * aProfile);
+
+ void initFromSettings(const ContextReader& _rSettings, bool& rNeedProfile);
+ void initFromProfile(sharable::Node * aProfile);
+ };
+} // namespace configmgr
+
+#endif // CONFIGMGR_API_PROVIDERIMPL_HXX_
+
+
diff --git a/configmgr/source/api2/setaccess.cxx b/configmgr/source/api2/setaccess.cxx
new file mode 100644
index 000000000000..b792fe9af419
--- /dev/null
+++ b/configmgr/source/api2/setaccess.cxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: setaccess.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "setaccess.hxx"
+#include "accessimpl.hxx"
+#include "apinotifierimpl.hxx"
+#include "apinodeaccess.hxx"
+
+namespace configmgr
+{
+
+// XHierarchicalName
+//------------------------------------------------------------------------------------------------------------------
+rtl::OUString SAL_CALL BasicSetAccess::getHierarchicalName( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetHierarchicalName( getNode() );
+}
+
+//------------------------------------------------------------------------------------------------------------------
+rtl::OUString SAL_CALL BasicSetAccess::composeHierarchicalName( const rtl::OUString& sRelativeName )
+ throw(css::lang::IllegalArgumentException, css::lang::NoSupportException, uno::RuntimeException)
+{
+ return configapi::implComposeHierarchicalName( getNode(), sRelativeName );
+}
+
+//------------------------------------------------------------------------------------------------------------------
+
+// XElementAccess, base class of XNameAccess (and XHierarchicalNameAccess ? )
+//-----------------------------------------------------------------------------------
+
+uno::Type SAL_CALL BasicSetAccess::getElementType( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetElementType( getNode() );
+}
+
+//-----------------------------------------------------------------------------------
+sal_Bool SAL_CALL BasicSetAccess::hasElements( ) throw(uno::RuntimeException)
+{
+ return configapi::implHasElements( getNode() );
+}
+
+// XExactName
+//-----------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BasicSetAccess::getExactName( const rtl::OUString& rApproximateName ) throw(uno::RuntimeException)
+{
+ return configapi::implGetExactName( getNode(), rApproximateName);
+}
+
+// XProperty
+//-----------------------------------------------------------------------------------
+
+css::beans::Property SAL_CALL BasicSetAccess::getAsProperty( ) throw(uno::RuntimeException)
+{
+ return configapi::implGetAsProperty( getNode() );
+}
+
+// XPropertySetInfo
+//-----------------------------------------------------------------------------------
+
+uno::Sequence< css::beans::Property > SAL_CALL BasicSetAccess::getProperties( ) throw (uno::RuntimeException)
+{
+ return configapi::implGetProperties( getNode() );
+}
+
+css::beans::Property SAL_CALL BasicSetAccess::getPropertyByName( const rtl::OUString& aName )
+ throw (css::beans::UnknownPropertyException, uno::RuntimeException)
+{
+ return configapi::implGetPropertyByName( getNode(), aName );
+}
+
+sal_Bool SAL_CALL BasicSetAccess::hasPropertyByName( const rtl::OUString& name ) throw (uno::RuntimeException)
+{
+ return configapi::implHasPropertyByName( getNode(), name );
+}
+
+
+// XNameAccess
+//-----------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL BasicSetAccess::hasByName( const rtl::OUString& sName ) throw(uno::RuntimeException)
+{
+ return configapi::implHasByName( getNode(), sName);
+}
+
+//-----------------------------------------------------------------------------------
+uno::Any SAL_CALL BasicSetAccess::getByName( const rtl::OUString& sName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ return configapi::implGetByName( getNode(), sName );
+}
+
+//-----------------------------------------------------------------------------------
+uno::Sequence< rtl::OUString > SAL_CALL BasicSetAccess::getElementNames( ) throw( uno::RuntimeException)
+{
+ return configapi::implGetElementNames( getNode() );
+}
+
+// XHierarchicalNameAccess
+//-----------------------------------------------------------------------------------
+sal_Bool SAL_CALL BasicSetAccess::hasByHierarchicalName( const rtl::OUString& sName ) throw(uno::RuntimeException)
+{
+ return configapi::implHasByHierarchicalName( getNode(), sName);
+}
+
+//-----------------------------------------------------------------------------------
+uno::Any SAL_CALL BasicSetAccess::getByHierarchicalName( const rtl::OUString& sName )
+ throw(css::container::NoSuchElementException, uno::RuntimeException)
+{
+ return configapi::implGetByHierarchicalName( getNode(), sName );
+}
+
+
+// XContainer
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicSetAccess::addContainerListener( const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implAddListener( getNode(), xListener );
+}
+
+void SAL_CALL BasicSetAccess::removeContainerListener( const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException)
+{
+ configapi::implRemoveListener( getNode(), xListener );
+}
+
+//-----------------------------------------------------------------------------------
+// Set-specific interfaces
+//-----------------------------------------------------------------------------------
+
+// XTemplateContainer
+//-----------------------------------------------------------------------------------
+rtl::OUString SAL_CALL BasicSetAccess::getElementTemplateName( )
+ throw(uno::RuntimeException)
+{
+ return configapi::implGetElementTemplateName( getNode() );
+}
+
+// XStringEscape
+//-----------------------------------------------------------------------------------
+rtl::OUString SAL_CALL BasicSetAccess::escapeString( const rtl::OUString& aString )
+ throw(css::lang::IllegalArgumentException, uno::RuntimeException)
+{
+ return aString;
+}
+
+rtl::OUString SAL_CALL BasicSetAccess::unescapeString( const rtl::OUString& aEscapedString )
+ throw(css::lang::IllegalArgumentException, uno::RuntimeException)
+{
+ return aEscapedString;
+}
+
+//-----------------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/setaccess.hxx b/configmgr/source/api2/setaccess.hxx
new file mode 100644
index 000000000000..f3159c58e7a3
--- /dev/null
+++ b/configmgr/source/api2/setaccess.hxx
@@ -0,0 +1,170 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: setaccess.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_SETACCESS_HXX_
+#define CONFIGMGR_API_SETACCESS_HXX_
+
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XContainer.hpp>
+#include <com/sun/star/configuration/XTemplateContainer.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XProperty.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/util/XStringEscape.hpp>
+#include <cppuhelper/implbase9.hxx>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+
+ namespace configapi { class NodeSetInfoAccess; }
+
+ /** implements the (read-only) interfaces supported by a set node
+ within the configuration tree.
+ <p> Is an interface adapter around <type scope='configmgr::configapi'>NodeAccess</type>.</p>
+ */
+ class BasicSetAccess
+ : public ::cppu::ImplHelper9
+ < css::container::XNameAccess
+ , css::container::XHierarchicalName
+ , css::container::XHierarchicalNameAccess
+ , css::container::XContainer
+ , css::beans::XExactName
+ , css::beans::XProperty
+ , css::beans::XPropertySetInfo
+ , css::configuration::XTemplateContainer
+ , css::util::XStringEscape
+ >
+ {
+ protected:
+ // Destructors
+ virtual ~BasicSetAccess() {}
+
+ public:
+ // Interface methods
+ // XHierarchicalName
+ virtual rtl::OUString SAL_CALL
+ getHierarchicalName( )
+ throw(uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ composeHierarchicalName( const rtl::OUString& aRelativeName )
+ throw(css::lang::IllegalArgumentException, css::lang::NoSupportException,
+ uno::RuntimeException);
+
+ // XElementAccess, base class of XNameAccess
+ virtual uno::Type SAL_CALL
+ getElementType( )
+ throw(uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasElements( )
+ throw(uno::RuntimeException);
+
+ // XNameAccess
+ virtual uno::Any SAL_CALL
+ getByName( const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getElementNames( )
+ throw( uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasByName( const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XHierarchicalNameAccess
+ virtual uno::Any SAL_CALL
+ getByHierarchicalName( const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasByHierarchicalName( const rtl::OUString& aName )
+ throw(uno::RuntimeException);
+
+ // XContainer
+ virtual void SAL_CALL
+ addContainerListener( const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeContainerListener( const uno::Reference< css::container::XContainerListener >& xListener )
+ throw(uno::RuntimeException);
+
+ // XExactName
+ virtual rtl::OUString SAL_CALL
+ getExactName( const rtl::OUString& aApproximateName )
+ throw(uno::RuntimeException);
+
+ // XProperty
+ virtual css::beans::Property SAL_CALL
+ getAsProperty( )
+ throw(uno::RuntimeException);
+
+ // XPropertySetInfo
+ virtual uno::Sequence< css::beans::Property > SAL_CALL
+ getProperties( )
+ throw (uno::RuntimeException);
+
+ virtual css::beans::Property SAL_CALL
+ getPropertyByName( const rtl::OUString& aName )
+ throw (css::beans::UnknownPropertyException, uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ hasPropertyByName( const rtl::OUString& name )
+ throw (uno::RuntimeException);
+
+ // XTemplateContainer
+ rtl::OUString SAL_CALL
+ getElementTemplateName( )
+ throw(uno::RuntimeException);
+
+ // XStringEscape
+ rtl::OUString SAL_CALL
+ escapeString( const rtl::OUString& aString )
+ throw(css::lang::IllegalArgumentException, uno::RuntimeException);
+
+ rtl::OUString SAL_CALL
+ unescapeString( const rtl::OUString& aEscapedString )
+ throw(css::lang::IllegalArgumentException, uno::RuntimeException);
+
+ protected:
+ virtual configapi::NodeSetInfoAccess& getNode() = 0;
+ };
+
+}
+#endif // CONFIGMGR_API_SETACCESS_HXX_
+
+
diff --git a/configmgr/source/api2/setobjects.cxx b/configmgr/source/api2/setobjects.cxx
new file mode 100644
index 000000000000..17282f3c2369
--- /dev/null
+++ b/configmgr/source/api2/setobjects.cxx
@@ -0,0 +1,550 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: setobjects.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "setobjects.hxx"
+#include "comphelper/sequence.hxx"
+
+//........................................................................
+namespace configmgr
+{
+
+//==========================================================================
+//= OInnerSetInfo
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OInnerSetInfo::acquire( ) throw ()
+{
+ BasicInnerElement::acquire();
+}
+
+void SAL_CALL OInnerSetInfo::release( ) throw ()
+{
+ BasicInnerElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OInnerSetInfo::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicInnerElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicSetAccess::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OInnerSetInfo::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicInnerElement::getTypes(),BasicSetAccess::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OInnerSetInfo::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicInnerElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OInnerSetInfo::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& OInnerSetInfo::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::InnerElement& OInnerSetInfo::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= OInnerTreeSetUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OInnerTreeSetUpdate::acquire( ) throw ()
+{
+ BasicInnerElement::acquire();
+}
+
+void SAL_CALL OInnerTreeSetUpdate::release( ) throw ()
+{
+ BasicInnerElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OInnerTreeSetUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicInnerElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicSet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OInnerTreeSetUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicInnerElement::getTypes(),BasicSet::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OInnerTreeSetUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicInnerElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OInnerTreeSetUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& OInnerTreeSetUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeTreeSetAccess* OInnerTreeSetUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::InnerElement& OInnerTreeSetUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= OInnerValueSetUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OInnerValueSetUpdate::acquire( ) throw ()
+{
+ BasicInnerElement::acquire();
+}
+
+void SAL_CALL OInnerValueSetUpdate::release( ) throw ()
+{
+ BasicInnerElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OInnerValueSetUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicInnerElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicValueSet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OInnerValueSetUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicInnerElement::getTypes(),BasicValueSet::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OInnerValueSetUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicInnerElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OInnerValueSetUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& OInnerValueSetUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeValueSetAccess* OInnerValueSetUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::InnerElement& OInnerValueSetUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= OSetElementSetInfo
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OSetElementSetInfo::acquire( ) throw ()
+{
+ BasicSetElement::acquire();
+}
+
+void SAL_CALL OSetElementSetInfo::release( ) throw ()
+{
+ BasicSetElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OSetElementSetInfo::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicSetElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicSetAccess::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OSetElementSetInfo::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicSetElement::getTypes(),BasicSetAccess::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OSetElementSetInfo::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicSetElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OSetElementSetInfo::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& OSetElementSetInfo::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::SetElement& OSetElementSetInfo::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= OSetElementTreeSetUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OSetElementTreeSetUpdate::acquire( ) throw ()
+{
+ BasicSetElement::acquire();
+}
+
+void SAL_CALL OSetElementTreeSetUpdate::release( ) throw ()
+{
+ BasicSetElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OSetElementTreeSetUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicSetElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicSet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OSetElementTreeSetUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicSetElement::getTypes(),BasicSet::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OSetElementTreeSetUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicSetElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OSetElementTreeSetUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& OSetElementTreeSetUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeTreeSetAccess* OSetElementTreeSetUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::SetElement& OSetElementTreeSetUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= OSetElementValueSetUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL OSetElementValueSetUpdate::acquire( ) throw ()
+{
+ BasicSetElement::acquire();
+}
+
+void SAL_CALL OSetElementValueSetUpdate::release( ) throw ()
+{
+ BasicSetElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL OSetElementValueSetUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicSetElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicValueSet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL OSetElementValueSetUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicSetElement::getTypes(),BasicValueSet::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL OSetElementValueSetUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicSetElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& OSetElementValueSetUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& OSetElementValueSetUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeValueSetAccess* OSetElementValueSetUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::SetElement& OSetElementValueSetUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= ORootElementSetInfo
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL ORootElementSetInfo::acquire( ) throw ()
+{
+ BasicRootElement::acquire();
+}
+
+void SAL_CALL ORootElementSetInfo::release( ) throw ()
+{
+ BasicRootElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL ORootElementSetInfo::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicRootElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicSetAccess::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL ORootElementSetInfo::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicRootElement::getTypes(),BasicSetAccess::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL ORootElementSetInfo::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicRootElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& ORootElementSetInfo::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& ORootElementSetInfo::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::RootElement& ORootElementSetInfo::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= ORootElementTreeSetUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL ORootElementTreeSetUpdate::acquire( ) throw ()
+{
+ BasicUpdateElement::acquire();
+}
+
+void SAL_CALL ORootElementTreeSetUpdate::release( ) throw ()
+{
+ BasicUpdateElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL ORootElementTreeSetUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicUpdateElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicSet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL ORootElementTreeSetUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicUpdateElement::getTypes(),BasicSet::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL ORootElementTreeSetUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicUpdateElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& ORootElementTreeSetUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& ORootElementTreeSetUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeTreeSetAccess* ORootElementTreeSetUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::UpdateRootElement& ORootElementTreeSetUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+
+//==========================================================================
+//= ORootElementValueSetUpdate
+//==========================================================================
+
+// XInterface refcounting
+void SAL_CALL ORootElementValueSetUpdate::acquire( ) throw ()
+{
+ BasicUpdateElement::acquire();
+}
+
+void SAL_CALL ORootElementValueSetUpdate::release( ) throw ()
+{
+ BasicUpdateElement::release();
+}
+
+// XInterface joining
+uno::Any SAL_CALL ORootElementValueSetUpdate::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicUpdateElement::queryInterface(rType);
+
+ if (!aRet.hasValue())
+ aRet = BasicValueSet::queryInterface(rType);
+
+ return aRet;
+}
+
+// XTypeProvider joining
+uno::Sequence< uno::Type > SAL_CALL ORootElementValueSetUpdate::getTypes( ) throw (uno::RuntimeException )
+{
+ return comphelper::concatSequences(BasicUpdateElement::getTypes(),BasicValueSet::getTypes() );
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL ORootElementValueSetUpdate::getImplementationId( ) throw (uno::RuntimeException )
+{
+ return BasicUpdateElement::getImplementationId();
+}
+
+
+configapi::NodeAccess& ORootElementValueSetUpdate::getNodeAccess()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeSetInfoAccess& ORootElementValueSetUpdate::getNode()
+{
+ return m_aAccessElement;
+}
+
+configapi::NodeValueSetAccess* ORootElementValueSetUpdate::maybeGetUpdateAccess()
+{
+ return &m_aAccessElement;
+}
+
+configapi::UpdateRootElement& ORootElementValueSetUpdate::getElementClass()
+{
+ return m_aAccessElement;
+}
+//........................................................................
+} // namespace configmgr
+//........................................................................
+
diff --git a/configmgr/source/api2/setobjects.hxx b/configmgr/source/api2/setobjects.hxx
new file mode 100644
index 000000000000..a7c4b49cdfd0
--- /dev/null
+++ b/configmgr/source/api2/setobjects.hxx
@@ -0,0 +1,361 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: setobjects.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_SETOBJECTS_HXX_
+#define CONFIGMGR_API_SETOBJECTS_HXX_
+
+#include "setaccess.hxx"
+#include "setupdate.hxx"
+#include "elementaccess.hxx"
+
+#include "apiaccessobj.hxx"
+
+//........................................................................
+namespace configmgr
+{
+//........................................................................
+
+//==========================================================================
+//= Inner Set Instances
+//==========================================================================
+
+/** read-only access class for configuration nodes which are inner nodes and dynamic sets
+*/
+ class OInnerSetInfo
+ : public BasicInnerElement
+ , public BasicSetAccess
+ {
+ public:
+ // Construction/Destruction
+ OInnerSetInfo(configapi::ApiTreeImpl& rTree, configuration::NodeRef const& aNode)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),rTree,aNode)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::InnerElement& getElementClass();
+ private:
+ configapi::OInnerElement<configapi::NodeSetInfoAccess> m_aAccessElement;
+ };
+
+/** updating access class for configuration nodes which are inner nodes and dynamic sets of complex types (trees)
+*/
+ class OInnerTreeSetUpdate
+ : public BasicInnerElement
+ , public BasicSet
+ {
+ public:
+ // Construction/Destruction
+ OInnerTreeSetUpdate(configapi::ApiTreeImpl& rTree, configuration::NodeRef const& aNode)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),rTree,aNode)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::NodeTreeSetAccess* maybeGetUpdateAccess();
+ virtual configapi::InnerElement& getElementClass();
+ private:
+ configapi::OInnerElement<configapi::NodeTreeSetAccess> m_aAccessElement;
+ };
+
+
+/** update access class for configuration nodes which are inner nodes and dynamic sets of simple types (values)
+*/
+ class OInnerValueSetUpdate
+ : public BasicInnerElement
+ , public BasicValueSet
+ {
+ public:
+ // Construction/Destruction
+ OInnerValueSetUpdate(configapi::ApiTreeImpl& rTree, configuration::NodeRef const& aNode)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),rTree,aNode)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::NodeValueSetAccess* maybeGetUpdateAccess();
+ virtual configapi::InnerElement& getElementClass();
+ private:
+ configapi::OInnerElement<configapi::NodeValueSetAccess> m_aAccessElement;
+ };
+
+//==========================================================================
+//= Set Element Set Instances
+//==========================================================================
+
+/** read-only access class for configuration nodes which are set elements and dynamic sets
+*/
+ class OSetElementSetInfo
+ : public BasicSetElement
+ , public BasicSetAccess
+ {
+ public:
+ // Construction/Destruction
+ OSetElementSetInfo(rtl::Reference< configuration::Tree > const& aTree, configapi::ApiProvider& rProvider, configapi::ApiTreeImpl* pParentTree = 0)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),aTree,rProvider,pParentTree)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::SetElement& getElementClass();
+ private:
+ configapi::OSetElement<configapi::NodeSetInfoAccess> m_aAccessElement;
+ };
+
+/** updating access class for configuration nodes which are set elements and dynamic sets of complex types (trees)
+*/
+ class OSetElementTreeSetUpdate
+ : public BasicSetElement
+ , public BasicSet
+ {
+ public:
+ // Construction/Destruction
+ OSetElementTreeSetUpdate(rtl::Reference< configuration::Tree > const& aTree, configapi::ApiProvider& rProvider, configapi::ApiTreeImpl* pParentTree = 0)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),aTree,rProvider,pParentTree)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::NodeTreeSetAccess* maybeGetUpdateAccess();
+ virtual configapi::SetElement& getElementClass();
+ private:
+ configapi::OSetElement<configapi::NodeTreeSetAccess> m_aAccessElement;
+ };
+
+
+/** update access class for configuration nodes which are set elements and dynamic sets of simple types (values)
+*/
+ class OSetElementValueSetUpdate
+ : public BasicSetElement
+ , public BasicValueSet
+ {
+ public:
+ // Construction/Destruction
+ OSetElementValueSetUpdate(rtl::Reference< configuration::Tree > const& aTree, configapi::ApiProvider& rProvider, configapi::ApiTreeImpl* pParentTree = 0)
+ : m_aAccessElement(static_cast<css::container::XChild*>(this),aTree,rProvider,pParentTree)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::NodeValueSetAccess* maybeGetUpdateAccess();
+ virtual configapi::SetElement& getElementClass();
+ private:
+ configapi::OSetElement<configapi::NodeValueSetAccess> m_aAccessElement;
+ };
+
+//==========================================================================
+//= Root Element Set Instances
+//==========================================================================
+
+/** read-only access class for configuration nodes which are root nodes and dynamic sets
+*/
+ class ORootElementSetInfo
+ : public BasicRootElement
+ , public BasicSetAccess
+ {
+ public:
+ // Construction/Destruction
+ ORootElementSetInfo(configapi::ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions >const& _xOptions)
+ : m_aAccessElement(static_cast<css::lang::XComponent*>(this),rProvider,aTree,_xOptions)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::RootElement& getElementClass();
+ private:
+ configapi::OReadRootElement<configapi::NodeSetInfoAccess> m_aAccessElement;
+ };
+
+/** updating access class for configuration nodes which are root nodes and dynamic sets of complex types (trees)
+*/
+ class ORootElementTreeSetUpdate
+ : public BasicUpdateElement
+ , public BasicSet
+ {
+ public:
+ // Construction/Destruction
+ ORootElementTreeSetUpdate(configapi::ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions >const& _xOptions)
+ : m_aAccessElement(static_cast<css::lang::XComponent*>(this),rProvider,aTree, _xOptions)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::NodeTreeSetAccess* maybeGetUpdateAccess();
+ virtual configapi::UpdateRootElement& getElementClass();
+ private:
+ configapi::OUpdateRootElement<configapi::NodeTreeSetAccess> m_aAccessElement;
+ };
+
+
+/** update access class for configuration nodes which are root nodes and dynamic sets of simple types (values)
+*/
+ class ORootElementValueSetUpdate
+ : public BasicUpdateElement
+ , public BasicValueSet
+ {
+ public:
+ // Construction/Destruction
+ ORootElementValueSetUpdate(configapi::ApiProvider& rProvider, rtl::Reference< configuration::Tree > const& aTree, vos::ORef< OOptions >const& _xOptions)
+ : m_aAccessElement(static_cast<css::lang::XComponent*>(this),rProvider,aTree,_xOptions)
+ {
+ }
+
+ // XInterface refcounting
+ void SAL_CALL acquire( ) throw ();
+ void SAL_CALL release( ) throw ();
+
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException );
+
+ // Base class implementation
+ virtual configapi::NodeAccess& getNodeAccess();
+ virtual configapi::NodeSetInfoAccess& getNode();
+ virtual configapi::NodeValueSetAccess* maybeGetUpdateAccess();
+ virtual configapi::UpdateRootElement& getElementClass();
+ private:
+ configapi::OUpdateRootElement<configapi::NodeValueSetAccess> m_aAccessElement;
+ };
+
+
+//........................................................................
+} // namespace configmgr
+//........................................................................
+
+#endif // CONFIGMGR_API_SETOBJECTS_HXX_
+
+
diff --git a/configmgr/source/api2/setupdate.cxx b/configmgr/source/api2/setupdate.cxx
new file mode 100644
index 000000000000..8c19dcb0435d
--- /dev/null
+++ b/configmgr/source/api2/setupdate.cxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: setupdate.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "setupdate.hxx"
+#include "accessimpl.hxx"
+#include "updateimpl.hxx"
+#include "apinodeupdate.hxx"
+#include "apitypes.hxx"
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+namespace configmgr
+{
+//////////////////////////////////////////////////////////////////////////////////
+// classes BasicSet / BasicValueSet
+//////////////////////////////////////////////////////////////////////////////////
+
+// XInterface joining
+//////////////////////////////////////////////////////////////////////////////////
+uno::Any SAL_CALL BasicSet::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicSetAccess::queryInterface( rType );
+ if (!aRet.hasValue())
+ {
+ aRet = cppu::queryInterface(rType
+ , static_cast< css::container::XNameContainer *>(this)
+ , static_cast< css::container::XNameReplace *>(this)
+ , static_cast< css::beans::XPropertyWithState *>(this)
+ , static_cast< css::lang::XSingleServiceFactory *>(this)
+ );
+ }
+ return aRet;
+}
+//..............................................................................
+
+uno::Any SAL_CALL BasicValueSet::queryInterface( uno::Type const& rType ) throw (uno::RuntimeException )
+{
+ uno::Any aRet = BasicSetAccess::queryInterface( rType );
+ if (!aRet.hasValue())
+ {
+ aRet = cppu::queryInterface(rType
+ , static_cast< css::container::XNameContainer *>(this)
+ , static_cast< css::container::XNameReplace *>(this)
+ , static_cast< css::beans::XPropertyWithState *>(this)
+ );
+ }
+ return aRet;
+}
+
+// XTypeProvider joining
+//////////////////////////////////////////////////////////////////////////////////
+uno::Sequence< uno::Type > SAL_CALL BasicSet::getTypes( ) throw (uno::RuntimeException )
+{
+ /*static ?*/
+ cppu::OTypeCollection aTypes(
+ configapi::getReferenceType(static_cast< css::container::XNameContainer *>(this)),
+ configapi::getReferenceType(static_cast< css::container::XNameReplace *>(this)),
+ configapi::getReferenceType(static_cast< css::beans::XPropertyWithState *>(this)),
+ configapi::getReferenceType(static_cast< css::lang::XSingleServiceFactory *>(this)),
+ BasicSetAccess::getTypes());
+
+ return aTypes.getTypes();
+}
+//..............................................................................
+
+uno::Sequence< uno::Type > SAL_CALL BasicValueSet::getTypes( ) throw (uno::RuntimeException )
+{
+ /*static ?*/
+ cppu::OTypeCollection aTypes(
+ configapi::getReferenceType(static_cast< css::container::XNameContainer *>(this)),
+ configapi::getReferenceType(static_cast< css::container::XNameReplace *>(this)),
+ configapi::getReferenceType(static_cast< css::beans::XPropertyWithState *>(this)),
+ BasicSetAccess::getTypes());
+
+ return aTypes.getTypes();
+}
+
+//uno::Sequence< sal_Int8 > SAL_CALL BasicSet::getImplementationId( ) throw (uno::RuntimeException ) = 0;
+//uno::Sequence< sal_Int8 > SAL_CALL BasicValueSet::getImplementationId( ) throw (uno::RuntimeException ) = 0;
+
+// safe write access
+//////////////////////////////////////////////////////////////////////////////////
+configapi::NodeTreeSetAccess& BasicSet::getSetNode()
+{
+ configapi::NodeTreeSetAccess* pAccess = maybeGetUpdateAccess();
+ OSL_ENSURE(pAccess, "Write operation invoked on a read-only node access - failing with RuntimeException");
+
+ if (!pAccess)
+ {
+ throw uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: Invalid Object - internal update-interface missing.")),
+ static_cast< css::container::XNameReplace * >(this)
+ );
+ }
+ return *pAccess;
+}
+
+configapi::NodeValueSetAccess& BasicValueSet::getSetNode()
+{
+ configapi::NodeValueSetAccess* pAccess = maybeGetUpdateAccess();
+ OSL_ENSURE(pAccess, "Write operation invoked on a read-only node access - failing with RuntimeException");
+
+ if (!pAccess)
+ {
+ throw uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Configuration: Invalid Object - internal update-interface missing.")),
+ static_cast< css::container::XNameReplace* >(this)
+ );
+ }
+ return *pAccess;
+}
+
+// New Interface methods
+// XNameReplace
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicSet::replaceByName( const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implReplaceByName( getSetNode(), rName, rElement );
+}
+//..............................................................................
+
+void SAL_CALL BasicValueSet::replaceByName( const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implReplaceByName( getSetNode(), rName, rElement );
+}
+
+// XNameContainer
+//////////////////////////////////////////////////////////////////////////////////
+void SAL_CALL BasicSet::insertByName( const rtl::OUString& rName, const uno::Any& rElement)
+ throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implInsertByName( getSetNode(), rName, rElement );
+}
+//..............................................................................
+
+void SAL_CALL BasicValueSet::insertByName( const rtl::OUString& rName, const uno::Any& rElement)
+ throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implInsertByName( getSetNode(), rName, rElement );
+}
+
+//----------------------------------------------------------------------------------
+void SAL_CALL BasicSet::removeByName( const rtl::OUString& rName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implRemoveByName( getSetNode(), rName );
+}
+//..............................................................................
+
+void SAL_CALL BasicValueSet::removeByName( const rtl::OUString& rName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implRemoveByName( getSetNode(), rName );
+}
+
+// XPropertyWithState
+//////////////////////////////////////////////////////////////////////////////////
+
+css::beans::PropertyState SAL_CALL BasicSet::getStateAsProperty() throw (uno::RuntimeException)
+{
+ return configapi::implGetStateAsProperty( getSetNode() );
+}
+//..............................................................................
+
+css::beans::PropertyState SAL_CALL BasicValueSet::getStateAsProperty() throw (uno::RuntimeException)
+{
+ return configapi::implGetStateAsProperty( getSetNode() );
+}
+//-----------------------------------------------------------------------------------
+
+void SAL_CALL BasicSet::setToDefaultAsProperty() throw (css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implSetToDefaultAsProperty( getSetNode() );
+}
+//..............................................................................
+
+void SAL_CALL BasicValueSet::setToDefaultAsProperty() throw (css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ configapi::implSetToDefaultAsProperty( getSetNode() );
+}
+//-----------------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > SAL_CALL BasicSet::getDefaultAsProperty() throw (css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ return configapi::implGetDefaultAsProperty( getSetNode() );
+}
+//..............................................................................
+
+uno::Reference< uno::XInterface > SAL_CALL BasicValueSet::getDefaultAsProperty() throw (css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ return configapi::implGetDefaultAsProperty( getSetNode() );
+}
+
+// XSingleServiceFactory (not for ValueSet)
+//////////////////////////////////////////////////////////////////////////////////
+uno::Reference< uno::XInterface > SAL_CALL BasicSet::createInstance( )
+ throw(uno::Exception, uno::RuntimeException)
+{
+ return configapi::implCreateElement( getSetNode() );
+}
+
+//----------------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL BasicSet::createInstanceWithArguments( const uno::Sequence< uno::Any >& aArguments )
+ throw(uno::Exception, uno::RuntimeException)
+{
+ return configapi::implCreateElement( getSetNode(), aArguments );
+}
+
+//-----------------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/setupdate.hxx b/configmgr/source/api2/setupdate.hxx
new file mode 100644
index 000000000000..fd04639da95f
--- /dev/null
+++ b/configmgr/source/api2/setupdate.hxx
@@ -0,0 +1,211 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: setupdate.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_SETUPDATE_HXX_
+#define CONFIGMGR_API_SETUPDATE_HXX_
+
+#include "setaccess.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertyWithState.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+//........................................................................
+namespace configmgr
+{
+//........................................................................
+ namespace configapi { class NodeTreeSetAccess; class NodeValueSetAccess; }
+
+//==========================================================================
+//= BasicSet
+//==========================================================================
+
+/** base class for configuration nodes which are dynamic sets of complex types (trees)
+*/
+ class BasicSet
+ : public BasicSetAccess
+ , public css::container::XNameContainer
+ , public css::beans::XPropertyWithState
+ , public css::lang::XSingleServiceFactory
+ {
+ protected:
+ // Destructors
+ virtual ~BasicSet() {}
+
+ public:
+ // Base class Interface methods
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException ) = 0;
+
+ // XElementAccess forwarding
+ virtual uno::Type SAL_CALL getElementType( ) throw(uno::RuntimeException)
+ { return BasicSetAccess::getElementType(); }
+
+ virtual sal_Bool SAL_CALL hasElements( ) throw(uno::RuntimeException)
+ { return BasicSetAccess::hasElements(); }
+
+ // XNameAccess forwarding
+ virtual uno::Any SAL_CALL getByName( const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+ { return BasicSetAccess::getByName(aName); }
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL getElementNames( ) throw( uno::RuntimeException)
+ { return BasicSetAccess::getElementNames(); }
+
+ virtual sal_Bool SAL_CALL hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+ { return BasicSetAccess::hasByName(aName); }
+
+ // New Interface methods
+ // XNameReplace
+ virtual void SAL_CALL
+ replaceByName( const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XNameContainer
+ virtual void SAL_CALL
+ insertByName( const rtl::OUString& rName, const uno::Any& rElement)
+ throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeByName( const rtl::OUString& rName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XPropertyWithState
+ virtual css::beans::PropertyState SAL_CALL
+ getStateAsProperty( )
+ throw (uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setToDefaultAsProperty( )
+ throw (css::lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ getDefaultAsProperty( )
+ throw (css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XSingleServiceFactory
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstance( )
+ throw(uno::Exception, uno::RuntimeException);
+
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const uno::Sequence< uno::Any >& aArguments )
+ throw(uno::Exception, uno::RuntimeException);
+
+ protected:
+ configapi::NodeTreeSetAccess& getSetNode();
+ virtual configapi::NodeTreeSetAccess* maybeGetUpdateAccess() = 0;
+ };
+
+//==========================================================================
+//= BasicValueSet
+//==========================================================================
+
+/** class for configuration nodes which are dynamic sets of simple types (values)
+*/
+ class BasicValueSet
+ : public BasicSetAccess
+ , public css::beans::XPropertyWithState
+ , public css::container::XNameContainer
+ {
+ protected:
+ // Destructors
+ virtual ~BasicValueSet() {}
+
+ public:
+ // Base class Interface methods
+ // XInterface joining
+ uno::Any SAL_CALL queryInterface( uno::Type const& rType ) throw (uno::RuntimeException );
+
+ // XTypeProvider joining
+ uno::Sequence< uno::Type > SAL_CALL getTypes( ) throw (uno::RuntimeException );
+ uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw (uno::RuntimeException ) = 0;
+
+ // XElementAccess forwarding
+ virtual uno::Type SAL_CALL getElementType( ) throw(uno::RuntimeException)
+ { return BasicSetAccess::getElementType(); }
+
+ virtual sal_Bool SAL_CALL hasElements( ) throw(uno::RuntimeException)
+ { return BasicSetAccess::hasElements(); }
+
+ // XNameAccess forwarding
+ virtual uno::Any SAL_CALL getByName( const rtl::OUString& aName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException)
+ { return BasicSetAccess::getByName(aName); }
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL getElementNames( ) throw( uno::RuntimeException)
+ { return BasicSetAccess::getElementNames(); }
+
+ virtual sal_Bool SAL_CALL hasByName( const rtl::OUString& aName ) throw(uno::RuntimeException)
+ { return BasicSetAccess::hasByName(aName); }
+
+ // New Interface methods
+ // XNameReplace
+ virtual void SAL_CALL
+ replaceByName( const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XNameContainer
+ virtual void SAL_CALL
+ insertByName( const rtl::OUString& rName, const uno::Any& rElement)
+ throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeByName( const rtl::OUString& rName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XPropertyWithState
+ virtual css::beans::PropertyState SAL_CALL
+ getStateAsProperty( )
+ throw (uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setToDefaultAsProperty( )
+ throw (css::lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ getDefaultAsProperty( )
+ throw (css::lang::WrappedTargetException, uno::RuntimeException);
+
+ protected:
+ configapi::NodeValueSetAccess& getSetNode();
+ virtual configapi::NodeValueSetAccess* maybeGetUpdateAccess() = 0;
+ };
+
+//........................................................................
+} // namespace configmgr
+//........................................................................
+
+#endif // CONFIGMGR_API_VALUESETACCESS_HXX_
+
+
diff --git a/configmgr/source/api2/translatechanges.cxx b/configmgr/source/api2/translatechanges.cxx
new file mode 100644
index 000000000000..1be732d3868a
--- /dev/null
+++ b/configmgr/source/api2/translatechanges.cxx
@@ -0,0 +1,286 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: translatechanges.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "translatechanges.hxx"
+#include "noderef.hxx"
+#include "nodechange.hxx"
+#include "nodechangeinfo.hxx"
+#include "apifactory.hxx"
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------------------------------
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+ namespace util = css::util;
+ namespace beans = css::beans;
+ namespace container = css::container;
+// ---------------------------------------------------------------------------------------------------
+
+ namespace configuration
+ {
+ class NodeChange;
+ class NodeChanges;
+ class NodeRef;
+ class NodeID;
+ }
+// ---------------------------------------------------------------------------------------------------
+
+ namespace configapi
+ {
+// ---------------------------------------------------------------------------------------------------
+ //interpreting NodeChanges
+// resolve the relative path from a given base to the changed node
+bool resolveChangeLocation(configuration::RelativePath& aPath, configuration::NodeChangeLocation const& aChange, rtl::Reference< configuration::Tree > const& aBaseTree, configuration::NodeRef const& aBaseNode)
+{
+ OSL_ENSURE(aChange.isValidLocation(), "Trying to resolve against change location that wasn't set up properly");
+
+ namespace Path = configuration::Path;
+
+ rtl::Reference< configuration::Tree > aChangeBaseTree = aChange.getBaseTree();
+
+ configuration::AbsolutePath aOuterBasePath = aBaseTree->getAbsolutePath(aBaseNode);
+ configuration::AbsolutePath aChangeBasePath = aChangeBaseTree->getAbsolutePath(aChange.getBaseNode());
+
+ std::vector<configuration::Path::Component>::const_reverse_iterator aChangeIt = aChangeBasePath.begin(), aChangeEnd = aChangeBasePath.end();
+ std::vector<configuration::Path::Component>::const_reverse_iterator aOuterIt = aOuterBasePath.begin(), aOuterEnd = aOuterBasePath.end();
+
+ // First by resolve the base node pathes
+ while (aOuterIt != aOuterEnd && aChangeIt != aChangeEnd)
+ {
+ if ( ! Path::matches(*aOuterIt,*aChangeIt) ) return false; // mismatch
+ ++aOuterIt;
+ ++aChangeIt;
+ }
+
+ // Next consider the stored accessor
+ if (aChangeIt != aChangeEnd) // stepping outward - prepend
+ {
+ Path::Rep aRemaining(aChangeIt, aChangeEnd);
+
+ aPath = configuration::RelativePath(aRemaining).compose(aChange.getAccessor());
+ }
+ else if (aOuterIt == aOuterEnd) // exact match outside
+ {
+ aPath = aChange.getAccessor();
+ }
+ else //(aChangeIt == aChangeEnd) but outer left
+ {
+ configuration::RelativePath aAccessor = aChange.getAccessor();
+ aChangeIt = aAccessor.begin();
+ aChangeEnd = aAccessor.end();
+
+ // resolve the outer path against the change accessor
+ while (aOuterIt != aOuterEnd && aChangeIt != aChangeEnd)
+ {
+ if ( ! Path::matches(*aOuterIt,*aChangeIt) ) return false; // mismatch
+ ++aOuterIt;
+ ++aChangeIt;
+ }
+
+ if (aOuterIt == aOuterEnd)
+ {
+ Path::Rep aRemaining(aChangeIt, aChangeEnd);
+
+ aPath = configuration::RelativePath( aRemaining );
+ }
+ }
+
+ return (aOuterIt == aOuterEnd); // resolved completely and assigned ??
+
+}
+
+// ---------------------------------------------------------------------------------------------------
+// change path and base settings to start from the given base
+bool rebaseChange(configuration::NodeChangeLocation& aChange, rtl::Reference< configuration::Tree > const& _aBaseTreeRef)
+{
+ return rebaseChange(aChange,_aBaseTreeRef,_aBaseTreeRef->getRootNode());
+}
+bool rebaseChange(configuration::NodeChangeLocation& aChange, rtl::Reference< configuration::Tree > const& _aBaseTreeRef, configuration::NodeRef const& aBaseNode)
+{
+ OSL_ENSURE(aChange.isValidLocation(), "Trying to rebase change location that wasn't set up properly");
+
+ rtl::Reference< configuration::Tree > aBaseTree(_aBaseTreeRef);
+
+ configuration::RelativePath aNewPath;
+ if (resolveChangeLocation(aNewPath,aChange,aBaseTree,aBaseNode))
+ {
+ aChange.setBase( aBaseTree, aBaseNode);
+ aChange.setAccessor( aNewPath );
+ return true;
+ }
+ else
+ return false;
+}
+// ---------------------------------------------------------------------------------------------------
+// resolve non-uno elements to Uno Objects
+bool resolveUnoObjects(UnoChange& aUnoChange, configuration::NodeChangeData const& aChange,
+ Factory& rFactory)
+{
+ if (aChange.isSetChange())
+ {
+ //Check we have ElementTree
+ if ((aChange.element.newValue == NULL) &&
+ (aChange.element.oldValue == NULL))
+ {
+ if( ( aChange.unoData.newValue.getValue()!=NULL) ||
+ ( aChange.unoData.newValue.getValue()!=NULL))
+ {
+ return true;
+ }
+ else return false;
+ }
+
+ //Check if complex or simple type
+ rtl::Reference< configuration::Tree > aTree = aChange.isRemoveSetChange()?
+ aChange.getOldElementTree():
+ aChange.getNewElementTree();
+
+ configuration::NodeRef aNodeRef = aTree->getRootNode();
+
+ if (configuration::isStructuralNode(aTree, aNodeRef))
+ {
+ uno::Reference<uno::XInterface> aNewUnoObject = rFactory.findUnoElement(aChange.getNewElementNodeID());
+ uno::Reference<uno::XInterface> aOldUnoObject = rFactory.findUnoElement(aChange.getOldElementNodeID());
+
+ bool bFound = aNewUnoObject.is() || aOldUnoObject.is();
+ aUnoChange.newValue <<= aNewUnoObject;
+ aUnoChange.oldValue <<= aOldUnoObject;
+ return bFound;
+ }
+ else
+ {
+ aUnoChange.newValue = configuration::getSimpleElementValue(aTree, aNodeRef);
+
+ if (aChange.isReplaceSetChange() )
+ {
+ rtl::Reference< configuration::Tree > aOldTree = aChange.getOldElementTree();
+
+ aNodeRef = aOldTree->getRootNode();
+ OSL_ENSURE(!configuration::isStructuralNode(aOldTree, aNodeRef), "resolveUnoObject types mismatch");
+ aUnoChange.oldValue = configuration::getSimpleElementValue(aOldTree, aNodeRef);
+ }
+ bool bFound = aUnoChange.newValue.hasValue() || aUnoChange.oldValue.hasValue();
+ return bFound;
+ }
+ }
+ else if (aChange.isValueChange())
+ {
+ aUnoChange.newValue = aChange.unoData.newValue;
+ aUnoChange.oldValue = aChange.unoData.oldValue;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+// ---------------------------------------------------------------------------------------------------
+// resolve non-uno elements to Uno Objects inplace
+bool resolveToUno(configuration::NodeChangeData& aChange, Factory& rFactory)
+{
+ struct UnoChange aUnoChange;
+ if (resolveUnoObjects(aUnoChange,aChange, rFactory))
+ {
+ aChange.unoData.newValue = aUnoChange.newValue;
+ aChange.unoData.oldValue = aUnoChange.oldValue;
+ return true;
+ }
+ else
+ return false;
+}
+// ---------------------------------------------------------------------------------------------------
+
+/// fill a change info from a NodeChangeInfo
+void fillChange(util::ElementChange& rChange, configuration::NodeChangeInformation const& aInfo, rtl::Reference< configuration::Tree > const& aBaseTree, Factory& rFactory)
+{
+ fillChange(rChange,aInfo,aBaseTree,aBaseTree->getRootNode(),rFactory);
+}
+/// fill a change info from a NodeChangeInfo
+void fillChange(util::ElementChange& rChange, configuration::NodeChangeInformation const& aInfo, rtl::Reference< configuration::Tree > const& aBaseTree, configuration::NodeRef const& aBaseNode, Factory& rFactory)
+{
+ configuration::RelativePath aRelativePath;
+ if (!resolveChangeLocation(aRelativePath, aInfo.location, aBaseTree, aBaseNode))
+ OSL_ENSURE(false, "WARNING: Change is not part of the given Tree");
+
+ UnoChange aUnoChange;
+
+ if (!resolveUnoObjects(aUnoChange, aInfo.change, rFactory))
+ OSL_ENSURE(false, "WARNING: Cannot find out old/new UNO objects involved in change");
+
+ rChange.Accessor <<= aRelativePath.toString();
+ rChange.Element = aUnoChange.newValue;
+ rChange.ReplacedElement = aUnoChange.oldValue;
+}
+// ---------------------------------------------------------------------------------------------------
+/// fill a change info from a NodeChangeInfo (base,path and uno objects are assumed to be resolved already)
+void fillChangeFromResolved(util::ElementChange& rChange, configuration::NodeChangeInformation const& aInfo)
+{
+ rChange.Accessor <<= aInfo.location.getAccessor().toString();
+ rChange.Element = aInfo.change.unoData.newValue;
+ rChange.ReplacedElement = aInfo.change.unoData.oldValue;
+}
+// ---------------------------------------------------------------------------------------------------
+/// fill a event from a NodeChangeInfo (uno objects are assumed to be resolved already)
+bool fillEventDataFromResolved(container::ContainerEvent& rEvent, configuration::NodeChangeInformation const& aInfo)
+{
+ rEvent.Accessor <<= aInfo.location.getAccessor().getLocalName().getName();
+ rEvent.Element = aInfo.change.unoData.newValue;
+ rEvent.ReplacedElement = aInfo.change.unoData.oldValue;
+
+ return !aInfo.isEmptyChange();
+}
+// ---------------------------------------------------------------------------------------------------
+/// fill a event from a NodeChangeInfo(uno objects are assumed to be resolved already)
+bool fillEventDataFromResolved(beans::PropertyChangeEvent& rEvent, configuration::NodeChangeInformation const& aInfo, bool bMore)
+{
+ if (!aInfo.isValueChange())
+ return false;
+
+ rEvent.PropertyName = aInfo.location.getAccessor().getLocalName().getName();
+
+ rEvent.NewValue = aInfo.change.unoData.newValue;
+ rEvent.OldValue = aInfo.change.unoData.oldValue;
+
+ rEvent.PropertyHandle = -1;
+ rEvent.Further = bMore;
+
+ return !aInfo.isEmptyChange();
+}
+// ---------------------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------------------
+ }
+// ---------------------------------------------------------------------------------------------------
+}
+
diff --git a/configmgr/source/api2/translatechanges.hxx b/configmgr/source/api2/translatechanges.hxx
new file mode 100644
index 000000000000..a4cf2ae4bbe7
--- /dev/null
+++ b/configmgr/source/api2/translatechanges.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: translatechanges.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_TRANSLATECHANGES_HXX_
+#define CONFIGMGR_API_TRANSLATECHANGES_HXX_
+
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/beans/XVetoableChangeListener.hpp>
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+#include "rtl/ref.hxx"
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------------------------------
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+ namespace util = css::util;
+ namespace beans = css::beans;
+ namespace container = css::container;
+// ---------------------------------------------------------------------------------------------------
+
+ namespace configuration
+ {
+ class NodeChangeInformation;
+ class NodeChangeData;
+ class NodeChangeLocation;
+
+ //class NodeChange;
+ //class NodeChanges;
+ class Tree;
+ class NodeRef;
+ class NodeID;
+ class RelativePath;
+ }
+// ---------------------------------------------------------------------------------------------------
+
+ namespace configapi
+ {
+ class NotifierImpl;
+ class Factory;
+
+ struct UnoChange { uno::Any newValue, oldValue; };
+
+ //interpreting NodeChanges
+ // resolve the relative path from a given base node to the changed node
+ bool resolveChangeLocation( configuration::RelativePath& aPath,
+ configuration::NodeChangeLocation const& aChange,
+ rtl::Reference< configuration::Tree > const& aBaseTree,
+ configuration::NodeRef const& aBaseNode);
+
+ // change path and base settings to start from the given base tree (root)
+ bool rebaseChange( configuration::NodeChangeLocation& aChange,
+ rtl::Reference< configuration::Tree > const& _aBaseTreeRef);
+ // change path and base settings to start from the given base node
+ bool rebaseChange( configuration::NodeChangeLocation& aChange,
+ rtl::Reference< configuration::Tree > const& _aBaseTreeRef,
+ configuration::NodeRef const& aBaseNode);
+ // resolve non-uno elements to Uno Objects
+ bool resolveUnoObjects(UnoChange& aUnoChange,
+ configuration::NodeChangeData const& aChange,
+ Factory& rFactory);
+ // resolve non-uno elements to Uno Objects inplace
+ bool resolveToUno(configuration::NodeChangeData& aChange,
+ Factory& rFactory);
+
+ // building events
+
+ /// fill a change info from a NodeChangeInfo
+ void fillChange(util::ElementChange& rChange,
+ configuration::NodeChangeInformation const& aInfo,
+ rtl::Reference< configuration::Tree > const& aBaseTree,
+ Factory& rFactory);
+ /// fill a change info from a NodeChangeInfo
+ void fillChange(util::ElementChange& rChange,
+ configuration::NodeChangeInformation const& aInfo,
+ rtl::Reference< configuration::Tree > const& aBaseTree,
+ configuration::NodeRef const& aBaseNode,
+ Factory& rFactory);
+ /// fill a change info from a NodeChangeInfo (base,path and uno objects are assumed to be resolved already)
+ void fillChangeFromResolved(util::ElementChange& rChange, configuration::NodeChangeInformation const& aInfo);
+
+ /// fill a event from a NodeChangeInfo (uno objects are assumed to be resolved already)
+ bool fillEventDataFromResolved(container::ContainerEvent& rEvent, configuration::NodeChangeInformation const& aInfo);
+ /// fill a event from a NodeChangeInfo(uno objects are assumed to be resolved already) - returns false if this isn't a property change
+ bool fillEventDataFromResolved(beans::PropertyChangeEvent& rEvent, configuration::NodeChangeInformation const& aInfo, bool bMore);
+ }
+// ---------------------------------------------------------------------------------------------------
+}
+
+#endif // CONFIGMGR_API_TRANSLATECHANGES_HXX_
diff --git a/configmgr/source/api2/treeiterators.cxx b/configmgr/source/api2/treeiterators.cxx
new file mode 100644
index 000000000000..de3cb41e924e
--- /dev/null
+++ b/configmgr/source/api2/treeiterators.cxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treeiterators.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+
+#include "treeiterators.hxx"
+
+#include "apitypes.hxx"
+#include "configpath.hxx"
+#include "attributes.hxx"
+#include "valueref.hxx"
+#include "propertyinfohelper.hxx"
+
+// .......................................................................
+namespace configmgr
+{
+// .......................................................................
+ namespace configapi
+ {
+ // ===================================================================
+ // = CollectNodeNames
+ // ===================================================================
+ // -------------------------------------------------------------------
+ CollectPropertyInfo::Result CollectNodeNames::handle(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode)
+ {
+ m_aList.push_back(aTree->getSimpleNodeName(aNode.getOffset()));
+ return CONTINUE;
+ }
+
+ // -------------------------------------------------------------------
+ CollectPropertyInfo::Result CollectNodeNames::handle(rtl::Reference< configuration::Tree > const&, configuration::ValueRef const& aNode)
+ {
+ m_aList.push_back(aNode.m_sNodeName);
+ return CONTINUE;
+ }
+
+ // ===================================================================
+ // = CollectPropertyInfo
+ // ===================================================================
+ // -------------------------------------------------------------------
+ CollectNodeNames::Result CollectPropertyInfo::handle(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode)
+ {
+ rtl::OUString aName = aTree->getSimpleNodeName(aNode.getOffset());
+ node::Attributes aAttributes = aTree->getAttributes(aNode);
+ uno::Type aApiType = getUnoInterfaceType();
+
+ m_aList.push_back( helperMakeProperty(aName,aAttributes,aApiType,aTree->hasNodeDefault(aNode)) );
+ return CONTINUE;
+ }
+
+ // -------------------------------------------------------------------
+ CollectNodeNames::Result CollectPropertyInfo::handle(rtl::Reference< configuration::Tree > const& aTree, configuration::ValueRef const& aNode)
+ {
+ rtl::OUString aName = aNode.m_sNodeName;
+ node::Attributes aAttributes = aTree->getAttributes(aNode);
+ uno::Type aApiType = aTree->getUnoType(aNode);
+
+ m_aList.push_back( helperMakeProperty(aName,aAttributes,aApiType,aTree->hasNodeDefault(aNode)) );
+ return CONTINUE;
+ }
+// .......................................................................
+ } // namespace configapi
+
+// .......................................................................
+} // namespace configmgr
+// .......................................................................
+
diff --git a/configmgr/source/api2/treeiterators.hxx b/configmgr/source/api2/treeiterators.hxx
new file mode 100644
index 000000000000..8e5184126078
--- /dev/null
+++ b/configmgr/source/api2/treeiterators.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treeiterators.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_TREEITERATORS_HXX_
+#define CONFIGMGR_TREEITERATORS_HXX_
+
+#include "tree.hxx"
+#include <com/sun/star/beans/Property.hpp>
+#include <rtl/ustring.hxx>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+// .......................................................................
+namespace configmgr
+{
+// .......................................................................
+ namespace configapi
+ {
+ // ===================================================================
+ // = CollectNodeNames
+ // ===================================================================
+ class CollectNodeNames : public configuration::NodeVisitor
+ {
+ protected:
+ std::vector<rtl::OUString> m_aList;
+
+ public:
+ CollectNodeNames() { }
+
+ virtual Result handle(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode); // NodeVisitor
+ virtual Result handle(rtl::Reference< configuration::Tree > const& aTree, configuration::ValueRef const& aNode); // NodeVisitor
+
+ std::vector<rtl::OUString> const& list() const { return m_aList; }
+ };
+
+ // ===================================================================
+ // = CollectPropertyInfo
+ // ===================================================================
+ class CollectPropertyInfo : public configuration::NodeVisitor
+ {
+ protected:
+ std::vector<com::sun::star::beans::Property> m_aList;
+
+ public:
+ CollectPropertyInfo() { }
+
+ virtual Result handle(rtl::Reference< configuration::Tree > const& aTree, configuration::NodeRef const& aNode); // NodeVisitor
+ virtual Result handle(rtl::Reference< configuration::Tree > const& aTree, configuration::ValueRef const& aNode); // NodeVisitor
+
+ std::vector<com::sun::star::beans::Property> const& list() const { return m_aList; }
+ };
+ }
+// .......................................................................
+} // namespace configmgr
+// .......................................................................
+
+#endif // _CONFIGMGR_TREEITERATORS_HXX_
+
diff --git a/configmgr/source/api2/updateimpl.cxx b/configmgr/source/api2/updateimpl.cxx
new file mode 100644
index 000000000000..8de561febf0b
--- /dev/null
+++ b/configmgr/source/api2/updateimpl.cxx
@@ -0,0 +1,650 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updateimpl.cxx,v $
+ * $Revision: 1.15.20.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "updateimpl.hxx"
+#include "accessimpl.hxx"
+#include "apinodeaccess.hxx"
+#include "apinodeupdate.hxx"
+#include "noderef.hxx"
+#include "valueref.hxx"
+#include "nodechange.hxx"
+#include "configset.hxx"
+#include "configgroup.hxx"
+#include "confignotifier.hxx"
+#include "broadcaster.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/PropertyVetoException.hpp>
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------------
+ namespace lang = css::lang;
+ namespace util = css::util;
+ namespace container = css::container;
+
+// Interface methods
+//-----------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------------
+// Update methods
+//-----------------------------------------------------------------------------------
+
+// XNameReplace
+//-----------------------------------------------------------------------------------
+void implReplaceByName(NodeGroupAccess& rNode, const rtl::OUString& sName, const uno::Any& rElement )
+ throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeGroupAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateChildName(sName,aTree,aNode);
+
+ configuration::ValueRef aChildValue( aTree->getChildValue(aNode, aChildName) );
+
+ if (!aChildValue.isValid())
+ {
+ if (aTree->hasChildNode(aNode, aChildName))
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Value. Node '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' is not a simple value.") );
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw lang::IllegalArgumentException( sMessage, xContext, 2 );
+ }
+ else
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing child node not found by implementation");
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Value. Value '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( sMessage, xContext );
+ }
+ }
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateSetValue(aChildValue, rElement);
+
+ if (aChange.test().isChange())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,true));
+// lock.clearForBroadcast();
+
+ aSender.queryConstraints(aChange);
+
+ aTree->integrate(aChange, aNode, true);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Value: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( e.message(), xContext );
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::ConstraintViolation& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ catch (css::beans::PropertyVetoException& ex)
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot set Value. Change was Vetoed: ") );
+ throw lang::WrappedTargetException( sMessage += ex.Message, rNode.getUnoInstance(), uno::makeAny(ex) );
+ }
+}
+//-----------------------------------------------------------------------------------
+
+void implReplaceByName(NodeTreeSetAccess& rNode, const rtl::OUString& sName, const uno::Any& rElement )
+ throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeTreeSetAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateElementName(sName,aTree,aNode);
+
+ rtl::Reference< configuration::ElementTree > aElement( aTree->getElement(aNode,aChildName) );
+
+ if (!aElement.is())
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Set element not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot replace Set Element. Element '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in Set ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( sMessage, xContext );
+ }
+
+ rtl::Reference< configuration::ElementTree > aElementTree = configapi::extractElementTree(rNode.getFactory(), rElement, rNode.getElementInfo());
+ if (!aElementTree.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot replace Set Element: ") );
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Replacing object was not created from this set's template") );
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw lang::IllegalArgumentException( sMessage, xContext, 2 );
+ }
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateReplaceElement( aElement, aElementTree );
+
+ if (aChange.test().isChange())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,true));
+
+ //aSender.queryConstraints(aChange); - N/A: no external constraints on set children possible
+
+ aTree->integrate(aChange, aNode, true);
+ attachSetElement(rNode, aElementTree);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot replace Set Element: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( e.message(), xContext );
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+//-----------------------------------------------------------------------------------
+
+void implReplaceByName(NodeValueSetAccess& rNode, const rtl::OUString& sName, const uno::Any& rElement )
+ throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeValueSetAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateElementName(sName,aTree,aNode);
+
+ rtl::Reference< configuration::ElementTree > aElement( aTree->getElement(aNode,aChildName) );
+
+ if (!aElement.is())
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Set element not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot replace Set Element. Element '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in Set ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( sMessage, xContext );
+ }
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateReplaceElement( aElement, rElement );
+
+ if (aChange.test().isChange())
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,true));
+
+ //aSender.queryConstraints(aChange); - N/A: no external constraints on set children possible
+
+ aTree->integrate(aChange, aNode, true);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot replace Set Element: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( e.message(), xContext );
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::ConstraintViolation& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+}
+
+// XNameContainer
+//-----------------------------------------------------------------------------------
+void implInsertByName(NodeTreeSetAccess& rNode, const rtl::OUString& sName, const uno::Any& rElement)
+ throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeTreeSetAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateElementName(sName,aTree,aNode);
+
+ if( aTree->hasElement(aNode,aChildName) )
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot insert into Set. Element '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' is already present in Set ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::ElementExistException( sMessage, xContext );
+ }
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Set element not found by implementation");
+
+ rtl::Reference< configuration::ElementTree > aElementTree = configapi::extractElementTree(rNode.getFactory(), rElement, rNode.getElementInfo());
+ if (!aElementTree.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot insert into Set: ") );
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Inserted object was not created from this set's template") );
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw lang::IllegalArgumentException( sMessage, xContext, 2 );
+ }
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateInsertElement(aChildName, aElementTree);
+
+ aChange.test(); // make sure old values are set up correctly
+ OSL_ENSURE(aChange.isChange(), "ERROR: Adding a node validated as empty change");
+
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,true));
+
+ //aSender.queryConstraints(); - N/A: no external constraints on set children possible
+
+ aTree->integrate(aChange, aNode, true);
+ attachSetElement(rNode, aElementTree);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument( 1 );
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+}
+
+//-----------------------------------------------------------------------------------
+
+void implInsertByName(NodeValueSetAccess& rNode, const rtl::OUString& sName, const uno::Any& rElement)
+ throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeValueSetAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateElementName(sName,aTree,aNode);
+
+ if( aTree->hasElement(aNode,aChildName) )
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot insert into Set. Element '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' is already present in Set ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::ElementExistException( sMessage, xContext );
+ }
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Set element not found by implementation");
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateInsertElement(aChildName, rElement);
+
+ aChange.test(); // make sure old values are set up correctly
+ OSL_ENSURE(aChange.isChange(), "ERROR: Adding a node validated as empty change");
+
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,true));
+
+ //aSender.queryConstraints(); - N/A: no external constraints on set children possible
+
+ aTree->integrate(aChange, aNode, true);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument( 1 );
+ }
+ catch (configuration::TypeMismatch& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::ConstraintViolation& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.illegalArgument(2);
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+}
+
+//-----------------------------------------------------------------------------------
+void implRemoveByName(NodeTreeSetAccess& rNode, const rtl::OUString& sName )
+ throw(css::container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeTreeSetAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateElementName(sName,aTree,aNode);
+
+ rtl::Reference< configuration::ElementTree > aElement( aTree->getElement(aNode,aChildName) );
+
+ if (!aElement.is())
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Set element not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot remove Set Element. Element '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in Set ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( sMessage, xContext );
+ }
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateRemoveElement(aElement);
+
+ aChange.test(); // make sure old values are set up correctly
+ OSL_ENSURE(aChange.isChange(), "ERROR: Removing a node validated as empty change");
+
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,true));
+
+ //aSender.queryConstraints(); - N/A: no external constraints on set children possible
+
+ aTree->integrate(aChange, aNode, true);
+ detachSetElement(rNode.getFactory(), aElement);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot remove Set Element: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+}
+//-----------------------------------------------------------------------------------
+void implRemoveByName(NodeValueSetAccess& rNode, const rtl::OUString& sName )
+ throw(css::container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeValueSetAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ rtl::OUString aChildName = configuration::validateElementName(sName,aTree,aNode);
+
+ rtl::Reference< configuration::ElementTree > aElement = aTree->getElement(aNode,aChildName);
+ if (!aElement.is())
+ {
+ OSL_ENSURE(!configuration::hasChildOrElement(aTree,aNode,aChildName),"ERROR: Configuration: Existing Set element not found by implementation");
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot remove Set Element. Element '") );
+ sMessage += sName;
+ sMessage += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("' not found in Set ") );
+ sMessage += aTree->getAbsolutePath(aNode).toString();
+
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( sMessage, xContext );
+ }
+
+ configuration::NodeChange aChange = lock.getNodeUpdater().validateRemoveElement(aElement);
+
+ aChange.test(); // make sure old values are set up correctly
+ OSL_ENSURE(aChange.isChange(), "ERROR: Removing a node validated as empty change");
+
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,true));
+
+ //aSender.queryConstraints(); - N/A: no external constraints on set children possible
+
+ aTree->integrate(aChange, aNode, true);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ catch (configuration::InvalidName& ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot remove Set Element: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+ throw container::NoSuchElementException( sMessage += e.message(), xContext );
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+}
+//-----------------------------------------------------------------------------------
+
+// XPropertyWithState
+//-----------------------------------------------------------------------------------
+
+void implSetToDefaultAsProperty(NodeSetAccess& rNode)
+ throw (css::lang::WrappedTargetException, uno::RuntimeException)
+{
+ try
+ {
+ GuardedNodeUpdate<NodeSetAccess> lock( rNode );
+
+ rtl::Reference< configuration::Tree > const aTree( lock.getTree() );
+ configuration::NodeRef const aNode( lock.getNode() );
+
+ configuration::SetDefaulter aDefaulter = lock.getNodeDefaulter();
+
+ configuration::NodeChange aChange = aDefaulter.validateSetToDefaultState();
+
+ const bool bLocal = true;
+
+ if (aChange.test().isChange() )
+ {
+ Broadcaster aSender(rNode.getNotifier().makeBroadcaster(aChange,bLocal));
+
+ aSender.queryConstraints(aChange);
+
+ aTree->integrate(aChange, aNode, bLocal);
+
+ lock.clearForBroadcast();
+ aSender.notifyListeners(aChange);
+ }
+ }
+ catch (configuration::ConstraintViolation & ex)
+ {
+ ExceptionMapper e(ex);
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Default: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+
+ throw lang::WrappedTargetException( sMessage += e.message(), xContext, uno::Any());
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+ catch (lang::WrappedTargetException& ) { throw;}
+ catch (uno::RuntimeException& ) { throw;}
+ catch (uno::Exception& e)
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration - Cannot restore Default: ") );
+ uno::Reference<uno::XInterface> xContext( rNode.getUnoInstance() );
+
+ throw lang::WrappedTargetException( sMessage += e.Message, xContext, uno::makeAny(e));
+ }
+}
+//-----------------------------------------------------------------------------------
+
+// XSingleServiceFactory
+//-----------------------------------------------------------------------------------
+uno::Reference< uno::XInterface > implCreateElement(NodeTreeSetAccess& rNode )
+ throw(uno::Exception, uno::RuntimeException)
+{
+ uno::Reference< uno::XInterface > xRet;
+ try
+ {
+ GuardedNodeData<NodeSetAccess> lock( rNode ); // no provider lock needed ? => if template lock is separate - OK
+
+ rtl::Reference< configuration::ElementTree > aNewElement( rNode.getElementFactory().instantiateTemplate(rNode.getElementInfo()) );
+
+ uno::Any aAny = configapi::makeElement( rNode.getFactory(), aNewElement );
+ if (!(aAny >>= xRet)) // no parent available
+ {
+ OSL_ASSERT(!xRet.is()); // make sure we return NULL
+ OSL_ENSURE(!aAny.hasValue(), "configmgr: BasicSetElement::getParent: could not extract parent - node is not an object");
+ }
+ }
+ catch (configuration::Exception& ex)
+ {
+ ExceptionMapper e(ex);
+ e.setContext( rNode.getUnoInstance() );
+ e.unhandled();
+ }
+
+ return xRet;
+}
+//-----------------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > implCreateElement(NodeTreeSetAccess& rNode, const uno::Sequence< uno::Any >& aArguments )
+ throw(uno::Exception, uno::RuntimeException)
+{
+ { (void)aArguments; }
+ OSL_ENSURE(aArguments.getLength() == 0, "ConfigurationContainer: createInstance: Arguments not supported - ignoring ...");
+ return implCreateElement(rNode);
+}
+
+//-----------------------------------------------------------------------------------
+ } // namespace configapi
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/api2/updateimpl.hxx b/configmgr/source/api2/updateimpl.hxx
new file mode 100644
index 000000000000..e57b5394d94f
--- /dev/null
+++ b/configmgr/source/api2/updateimpl.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updateimpl.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_BASEUPDATEIMPL_HXX_
+#define CONFIGMGR_API_BASEUPDATEIMPL_HXX_
+
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/beans/XPropertyWithState.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+ namespace uno = ::com::sun::star::uno;
+
+ /* implementations of the interfaces supported by a (parent) node
+ within the configuration tree.
+ (updating operation)
+ */
+ namespace configapi
+ {
+ class NodeSetAccess;
+ class NodeTreeSetAccess;
+ class NodeValueSetAccess;
+ class NodeGroupAccess;
+
+ // XNameReplace
+ //---------------------------------------------------------------------
+ void implReplaceByName(NodeGroupAccess& rNode, const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ void implReplaceByName(NodeTreeSetAccess& rNode, const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ void implReplaceByName(NodeValueSetAccess& rNode, const rtl::OUString& rName, const uno::Any& rElement )
+ throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XNameContainer
+ //---------------------------------------------------------------------
+ void implInsertByName(NodeTreeSetAccess& rNode, const rtl::OUString& rName, const uno::Any& rElement)
+ throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ void implInsertByName(NodeValueSetAccess& rNode, const rtl::OUString& rName, const uno::Any& rElement)
+ throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ void implRemoveByName(NodeTreeSetAccess& rNode, const rtl::OUString& rName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ void implRemoveByName(NodeValueSetAccess& rNode, const rtl::OUString& rName )
+ throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XPropertyWithState - updating operation only
+ //---------------------------------------------------------------------
+ void implSetToDefaultAsProperty(NodeSetAccess& rNode)
+ throw (css::lang::WrappedTargetException, uno::RuntimeException);
+
+ // XSingleServiceFactory
+ //---------------------------------------------------------------------
+ uno::Reference< uno::XInterface > implCreateElement(NodeTreeSetAccess& rNode )
+ throw(uno::Exception, uno::RuntimeException);
+
+ uno::Reference< uno::XInterface > implCreateElement(NodeTreeSetAccess& rNode, const uno::Sequence< uno::Any >& aArguments )
+ throw(uno::Exception, uno::RuntimeException);
+
+ //---------------------------------------------------------------------
+ }
+
+}
+#endif // CONFIGMGR_API_BASEUPDATEIMPL_HXX_
+
+
diff --git a/configmgr/source/backend/backendaccess.cxx b/configmgr/source/backend/backendaccess.cxx
new file mode 100644
index 000000000000..6d48c1550cbd
--- /dev/null
+++ b/configmgr/source/backend/backendaccess.cxx
@@ -0,0 +1,830 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendaccess.cxx,v $
+ * $Revision: 1.27 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "backendaccess.hxx"
+#include "logger.hxx"
+#include "matchlocale.hxx"
+#include "layermerge.hxx"
+#include "schemabuilder.hxx"
+
+#ifndef CONFIGMGR_BACKEND_UPDATEDISPATCHER_HXX
+#include "updatedispatch.hxx"
+#endif // CONFIGMGR_BACKEND_UPDATEDISPATCHER_HXX
+#include "backendnotifier.hxx"
+#include "emptylayer.hxx"
+#include "filehelper.hxx"
+#include "simpleinteractionrequest.hxx"
+#include "configinteractionhandler.hxx"
+#include <com/sun/star/configuration/backend/XVersionedSchemaSupplier.hpp>
+#include <com/sun/star/configuration/backend/XCompositeLayer.hpp>
+#include <com/sun/star/configuration/backend/XUpdatableLayer.hpp>
+#include <com/sun/star/configuration/backend/XBackendEntities.hpp>
+#include <com/sun/star/configuration/backend/MergeRecoveryRequest.hpp>
+#include <com/sun/star/configuration/backend/MalformedDataException.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/logfile.hxx>
+
+#include <cppuhelper/exc_hlp.hxx>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif //INCLUDED_VECTOR
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif //INCLUDED_ALGORITHM
+
+#define OU2A(rtlOUString) (::rtl::OUStringToOString((rtlOUString), RTL_TEXTENCODING_ASCII_US).getStr())
+#define RTL_LOGFILE_OU2A(rtlOUString) OU2A(rtlOUString)
+
+#define OUSTR(txt) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(txt) )
+
+namespace configmgr { namespace backend {
+//------------------------------------------------------------------------------
+ namespace task = com::sun::star::task;
+
+inline
+uno::Reference<lang::XMultiServiceFactory> BackendAccess::getServiceFactory() const
+{
+ return uno::Reference<lang::XMultiServiceFactory>(mContext->getServiceManager(),uno::UNO_QUERY_THROW);
+}
+//------------------------------------------------------------------------------
+
+BackendAccess::BackendAccess(
+ const uno::Reference<backenduno::XBackend>& xBackend,
+ const uno::Reference<uno::XComponentContext>& xContext)
+ : mContext(xContext)
+ , mBackend(xBackend)
+ , mBinaryCache(xContext)
+ {
+ OSL_ENSURE(mContext.is(), "BackendAccess: Context is missing");
+ if (!mContext.is())
+ throw lang::NullPointerException(rtl::OUString::createFromAscii("BackendAccess: NULL Context passed"), NULL);
+ if (!xBackend.is())
+ throw lang::NullPointerException(OUSTR("Configuration: Trying to create backend access without backend"),NULL);
+ if (!uno::Reference<backenduno::XSchemaSupplier>::query(xBackend).is())
+ throw lang::NullPointerException(OUSTR("Configuration: No backend for schemas available"),NULL);
+
+
+ mNotifier = new BackendChangeNotifier(xBackend);
+ //Stored as uno::reference to facilitate sharing with MultiStratumBackend
+ mXNotifier = mNotifier;
+
+ //Create Binary Cache
+ uno::Reference<backenduno::XBackendEntities> xBackendEntities = uno::Reference<backenduno::XBackendEntities>( mBackend, uno::UNO_QUERY) ;
+ OSL_ENSURE(xBackendEntities.is(),"Backend does not provide entity information");
+
+ if ( xBackendEntities.is() ) mBinaryCache.setOwnerEntity(xBackendEntities->getOwnerEntity());
+}
+//------------------------------------------------------------------------------
+
+BackendAccess::~BackendAccess() {}
+//------------------------------------------------------------------------------
+namespace
+{
+//------------------------------------------------------------------------------
+
+ static inline
+ bool findLocale(std::vector< com::sun::star::lang::Locale > const & seq, com::sun::star::lang::Locale const & loc)
+ {
+ std::vector< com::sun::star::lang::Locale >::const_iterator first = seq.begin();
+ std::vector< com::sun::star::lang::Locale >::const_iterator last = seq.end();
+ for ( ; first != last; ++first)
+ if (localehelper::equalLocale(*first, loc))
+ return true;
+ return false;
+ }
+//------------------------------------------------------------------------------
+
+ static inline
+ void addLocale( com::sun::star::lang::Locale const & aLocale, std::vector< com::sun::star::lang::Locale > & inoutLocales)
+ {
+ if (!findLocale(inoutLocales,aLocale))
+ inoutLocales.push_back(aLocale);
+ }
+//------------------------------------------------------------------------------
+
+ static rtl::OUString toString(uno::Sequence< rtl::OUString > const & seq, sal_Unicode separator = ',')
+ {
+ rtl::OUStringBuffer buf;
+
+ if (sal_Int32 const nCount = seq.getLength())
+ {
+ buf.append(seq[0]);
+ for (sal_Int32 ix=1; ix < nCount; ++ix)
+ buf.append(separator).append(seq[ix]);
+ }
+ else
+ buf.appendAscii("<none>");
+
+ return buf.makeStringAndClear();
+ }
+//------------------------------------------------------------------------------
+
+ static
+ uno::Sequence< rtl::OUString > intersect(uno::Sequence< rtl::OUString > const & seq1, uno::Sequence< rtl::OUString > const & seq2)
+ {
+ sal_Int32 const len1 = seq1.getLength();
+ uno::Sequence< rtl::OUString > aResult(len1);
+
+ rtl::OUString const * const beg2 = seq2.getConstArray();
+ rtl::OUString const * const end2 = beg2 + seq2.getLength();
+
+ sal_Int32 ix = 0;
+ for (sal_Int32 i1 = 0; i1 < len1; ++i1)
+ {
+ if (std::find(beg2,end2,seq1[i1]) != end2)
+ aResult[ix++] = seq1[i1];
+ }
+ aResult.realloc(ix);
+ return aResult;
+ }
+//------------------------------------------------------------------------------
+} // anonymous namespace
+//------------------------------------------------------------------------------
+
+// helper used by the binary cache
+uno::Sequence< rtl::OUString >
+ getAvailableLocales(const uno::Reference<backenduno::XLayer> * pLayers, sal_Int32 nNumLayers)
+{
+ uno::Sequence< rtl::OUString > aResult;
+
+ for (sal_Int32 i = 0 ; i < nNumLayers ; ++ i)
+ {
+ uno::Reference<backenduno::XCompositeLayer> compositeLayer(
+ pLayers [i], uno::UNO_QUERY) ;
+
+ if (compositeLayer.is())
+ {
+ uno::Sequence<rtl::OUString> aLocales = compositeLayer->listSubLayerIds();
+
+ if (aResult.getLength() == 0)
+ {
+ aResult = aLocales;
+ }
+ else
+ {
+ OSL_TRACE("Warning: multiple composite layers found. Detection of available locales is inaccurate.");
+ // be defensive: only locales present in all composite layers are 'available'
+ aResult= intersect(aResult,aLocales);
+ }
+ }
+ }
+ return aResult;
+}
+//------------------------------------------------------------------------------
+static rtl::OUString getLayerURL(const uno::Reference<backenduno::XLayer> & aLayer);
+
+void BackendAccess::merge(
+ MergedComponentData& aData,
+ const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 aNumLayers,
+ com::sun::star::lang::Locale const & aRequestedLocale,
+ std::vector< com::sun::star::lang::Locale > & inoutMergedLocales,
+ ITemplateDataProvider *aTemplateProvider,
+ sal_Int32 * pLayersMerged)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ LayerMergeHandler * pMerger = new LayerMergeHandler(mContext, aData, aTemplateProvider );
+ uno::Reference<backenduno::XLayerHandler> xLayerMerger(pMerger);
+
+ Logger logger(mContext);
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::BackendAccess", "jb99855", "configmgr: BackendAccess::merge()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "merging %d layers", int(aNumLayers) );
+
+ rtl::OUString const & aLanguage = aRequestedLocale.Language;
+ bool const needAllLanguages = localehelper::isAnyLanguage(aLanguage);
+
+ if (aLanguage.getLength() && !needAllLanguages)
+ {
+ if (!localehelper::isDefaultLanguage(aLanguage))
+ addLocale(aRequestedLocale,inoutMergedLocales);
+ }
+ bool const needLocalizedData = needAllLanguages || !inoutMergedLocales.empty();
+
+ if (logger.isLogging(LogLevel::FINEST))
+ {
+ if (!needLocalizedData)
+ logger.finest("Starting merge with NO locales", "merge()","configmgr::Backend");
+
+ else if (needAllLanguages)
+ logger.finest("Starting merge for ALL locales", "merge()","configmgr::Backend");
+
+ else
+ logger.finest(OUSTR("Starting merge for locale(s): ") +
+ toString(localehelper::makeIsoSequence(inoutMergedLocales)),
+ "merge()","configmgr::Backend");
+ }
+
+ if (pLayersMerged) *pLayersMerged = 0;
+
+ for (sal_Int32 i = 0 ; i < aNumLayers ; ++ i)
+ {
+ if (logger.isLogging(LogLevel::FINEST))
+ logger.finest(OUSTR("+ Merging layer: ") + getLayerURL(pLayers[i]),
+ "merge()","configmgr::Backend");
+
+ pMerger->prepareLayer() ;
+ pLayers [i]->readData(xLayerMerger) ;
+
+ if (needLocalizedData)
+ {
+ uno::Reference<backenduno::XCompositeLayer> compositeLayer(
+ pLayers [i], uno::UNO_QUERY) ;
+
+ if (compositeLayer.is())
+ {
+ uno::Sequence<rtl::OUString> aSubLayerIds = compositeLayer->listSubLayerIds();
+ logger.finest(OUSTR("++ Found locales: ") + toString(aSubLayerIds),
+ "merge()","configmgr::Backend");
+
+ for (sal_Int32 j = 0; j < aSubLayerIds.getLength(); ++j)
+ {
+ rtl::OUString const & aLocaleIso = aSubLayerIds[j];
+ com::sun::star::lang::Locale aLocale = localehelper::makeLocale(aLocaleIso);
+
+ // requesting de-CH, we accept de-CH and de, but not de-DE
+ const localehelper::MatchQuality kMatchAccept = localehelper::MATCH_LANGUAGE_PLAIN;
+
+ if (needAllLanguages || localehelper::isMatch(aLocale,inoutMergedLocales,kMatchAccept))
+ {
+ if(pMerger->prepareSublayer(aLocaleIso))
+ {
+ logger.finest(OUSTR("++ Merging sublayer for locale: ") + aLocaleIso,
+ "merge()","configmgr::Backend");
+ compositeLayer->readSubLayerData(xLayerMerger,aLocaleIso) ;
+ addLocale(aLocale,inoutMergedLocales);
+ }
+ // else dropLocale(aLocale,inoutMergedLocales); ?
+ }
+ }
+ }
+ }
+ if (pLayersMerged) ++*pLayersMerged;
+ }
+}
+//------------------------------------------------------------------------------
+
+bool BackendAccess::readDefaultData( MergedComponentData & aComponentData,
+ rtl::OUString const & aComponent,
+ RequestOptions const & aOptions,
+ bool bIncludeTemplates,
+ const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ ITemplateDataProvider *aTemplateProvider,
+ sal_Int32 * pLayersMerged)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog1, "configmgr::backend::BackendAccess", "jb99855", "configmgr: BackendAccess::readDefaultData()");
+
+ Logger logger(mContext);
+ const sal_Int32 detail = LogLevel::FINER;
+ bool const bLogDetail = logger.isLogging(detail);
+
+ rtl::OUString const aSchemaVersion = this->getSchemaVersion(aComponent);
+
+ if (logger.isLogging(LogLevel::FINE))
+ {
+ rtl::OUStringBuffer aMsg;
+ aMsg.appendAscii("Reading data for component \"").append(aComponent).appendAscii("\"");
+ aMsg.appendAscii(" [version=").append(aSchemaVersion).appendAscii("]");
+
+ logger.fine( aMsg.makeStringAndClear(), "readDefaultData()","configmgr::Backend");
+ }
+
+ com::sun::star::lang::Locale const aRequestedLocale = localehelper::makeLocale(aOptions.getLocale());
+ std::vector< com::sun::star::lang::Locale > aKnownLocales;
+
+ if (bLogDetail) logger.log(detail, "... attempt to read from binary cache", "readDefaultData()","configmgr::Backend");
+ bool bCacheHit = mBinaryCache.readComponentData(aComponentData, getServiceFactory(),
+ aComponent, aSchemaVersion,
+ aOptions.getEntity(),
+ aRequestedLocale, aKnownLocales,
+ pLayers, nNumLayers, bIncludeTemplates);
+
+ if (!bCacheHit)
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog2, "configmgr::backend::BackendAccess", "jb99855", "configmgr: BackendAccess::readDefaultData() - not in cache");
+
+ if (bLogDetail) logger.log(detail, "... cache miss - need full merge", "readDefaultData()","configmgr::Backend");
+ if (bLogDetail) logger.log(detail, "... reading schema", "readDefaultData()","configmgr::Backend");
+ {
+ SchemaBuilder *schemaBuilder = new SchemaBuilder( mContext, aComponent, aComponentData, aTemplateProvider );
+ uno::Reference<backenduno::XSchemaHandler> schemaHandler = schemaBuilder ;
+
+ uno::Reference<backenduno::XSchema> schema = this->getSchema(aComponent);
+ schema->readSchema(schemaHandler) ;
+ }
+
+ if (bLogDetail) logger.log(detail, "... merging layers", "readDefaultData()","configmgr::Backend");
+ this->merge(aComponentData, pLayers, nNumLayers, aRequestedLocale, aKnownLocales, aTemplateProvider, pLayersMerged );
+ promoteToDefault(aComponentData);
+
+ if (mBinaryCache.isCacheEnabled(aOptions.getEntity()))
+ {
+ if (bLogDetail) logger.log(detail, "... creating binary cache", "readDefaultData()","configmgr::Backend");
+ bool bWriteSuccess = mBinaryCache.writeComponentData( aComponentData, getServiceFactory(),
+ aComponent, aSchemaVersion,
+ aOptions.getEntity(), aKnownLocales,
+ pLayers, nNumLayers );
+
+ if (!bWriteSuccess)
+ {
+ logger.info("Binary cache write failed - disabling binary cache","readDefaultData()","configmgr::Backend");
+ mBinaryCache.disableCache();
+ }
+ }
+ else if (bLogDetail)
+ logger.log(detail, "... cache hit", "readDefaultData()","configmgr::Backend");
+ }
+ else if (pLayersMerged)
+ *pLayersMerged = nNumLayers;
+
+ return aComponentData.hasSchema();
+}
+//------------------------------------------------------------------------------
+
+static rtl::OUString getLayerURL(const uno::Reference<backenduno::XLayer> & aLayer)
+{
+ try
+ {
+ namespace beans = com::sun::star::beans;
+ uno::Reference< beans::XPropertySet > xLayerProps( aLayer, uno::UNO_QUERY );
+ if (xLayerProps.is())
+ {
+ uno::Any aPropVal = xLayerProps->getPropertyValue( OUSTR("URL") );
+ rtl::OUString aResult;
+ if (aPropVal >>= aResult)
+ return aResult;
+ }
+ OSL_TRACE("Warning - Cannot get location of layer data\n");
+ }
+ catch (uno::Exception & e)
+ {
+ OSL_TRACE("Warning - Configuration: Retrieving layer URL failed: [%s]\n", OU2A(e.Message));
+ }
+ // TODO: use better fallback, e.g. ServiceName
+ const char * const aFallback = aLayer.is() ? "<Unknown Layer Type>" : "<NULL Layer>";
+ return rtl::OUString::createFromAscii(aFallback);
+}
+//------------------------------------------------------------------------------
+static inline
+rtl::OUString getLayerIdentifier(const uno::Reference<backenduno::XLayer> & aLayer)
+{
+ return getLayerURL(aLayer);
+}
+
+//------------------------------------------------------------------------------
+static void removeLayerData(uno::Reference< backenduno::XLayer > const & xLayer)
+{
+ OSL_ASSERT(xLayer.is());
+
+ uno::Reference< backenduno::XUpdatableLayer > xLayerRemover(xLayer,uno::UNO_QUERY);
+ if (xLayerRemover.is())
+ try
+ {
+ xLayerRemover->replaceWith(createEmptyLayer());
+ }
+ catch (uno::Exception & e)
+ {
+ OSL_TRACE("Warning - Configuration: Could not clear Layer data. Error: [%s]\n", OU2A(e.Message));
+ }
+ else
+ {
+ if (! FileHelper::tryToRemoveFile(getLayerURL(xLayer),true))
+ OSL_TRACE("Warning - Configuration: Could not remove broken user Layer data: [-Not Updatable-]\n");
+ }
+}
+//------------------------------------------------------------------------------
+
+static void discardLayer(uno::Sequence<uno::Reference<backenduno::XLayer> >& layers, sal_Int32 nLayer)
+{
+ OSL_ASSERT(0 <= nLayer && nLayer < layers.getLength());
+ sal_Int32 nNewSize = layers.getLength() - 1;
+
+ for (sal_Int32 i = nLayer; i<nNewSize; ++i)
+ layers[i] = layers[i+1];
+
+ layers.realloc(nNewSize);
+}
+//------------------------------------------------------------------------------
+
+namespace {
+
+class RecursiveHandler:
+ public cppu::WeakImplHelper1< task::XInteractionHandler >
+{
+public:
+ explicit RecursiveHandler(
+ uno::Reference< task::XInteractionHandler > const & outer):
+ m_outer(outer) {}
+
+ virtual void SAL_CALL handle(
+ uno::Reference< task::XInteractionRequest > const & request)
+ throw (uno::RuntimeException)
+ {
+ backenduno::MergeRecoveryRequest req;
+ if (request->getRequest() >>= req) {
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > >
+ cs(request->getContinuations());
+ for (sal_Int32 i = 0; i < cs.getLength(); ++i) {
+ uno::Reference< task::XInteractionDisapprove > dis(
+ cs[i], uno::UNO_QUERY);
+ if (dis.is()) {
+ dis->select();
+ break;
+ }
+ }
+ } else if (m_outer.is()) {
+ m_outer->handle(request);
+ }
+ }
+
+private:
+ RecursiveHandler(RecursiveHandler &); // not defined
+ void operator =(RecursiveHandler &); // not defined
+
+ virtual ~RecursiveHandler() {}
+
+ uno::Reference< task::XInteractionHandler > m_outer;
+};
+
+}
+
+bool BackendAccess::approveRecovery(const uno::Any & aMergeException,
+ const uno::Reference<backenduno::XLayer> & aBrokenLayer,
+ bool bUserLayerData)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ sal_uInt32 const k_supported_choices = apihelper::CONTINUATION_APPROVE | apihelper::CONTINUATION_DISAPPROVE;
+
+ sal_uInt32 chosen = apihelper::CONTINUATION_UNKNOWN;
+
+ apihelper::ConfigurationInteractionHandler handler;
+ try {
+ uno::Reference< task::XInteractionHandler > h(handler.get());
+ if (h.is()) {
+ handler.setRecursive(new RecursiveHandler(h));
+ rtl::Reference< apihelper::SimpleInteractionRequest > req(
+ new apihelper::SimpleInteractionRequest(
+ uno::makeAny(
+ backenduno::MergeRecoveryRequest(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Recover from configuration merge"
+ " failure")),
+ aBrokenLayer, aMergeException,
+ getLayerIdentifier(aBrokenLayer),
+ (bUserLayerData
+ && (uno::Reference< backenduno::XUpdatableLayer >::query(aBrokenLayer).is()
+ || FileHelper::fileExists(
+ getLayerURL(aBrokenLayer)))))),
+ k_supported_choices));
+ h->handle(req.get());
+ chosen = req->getResponse();
+ }
+ } catch (uno::Exception & e) {
+ OSL_TRACE("Warning - Configuration: Interaction handler failed: [%s]\n", OU2A(e.Message));
+ }
+
+ switch (chosen)
+ {
+ case apihelper::CONTINUATION_APPROVE: return true;
+ case apihelper::CONTINUATION_DISAPPROVE: return false;
+ case apihelper::CONTINUATION_UNKNOWN: break;
+
+ default: OSL_ENSURE(false,"Unsolicited continuation chosen"); break;
+ }
+ // no choice available - default: approve, if user data
+ return bUserLayerData;
+}
+//------------------------------------------------------------------------------
+
+ResultHolder< ComponentInstance > BackendAccess::getNodeData(const ComponentRequest& aRequest,
+ ITemplateDataProvider *_aTemplateProvider,
+ INodeDataListener *aListener)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ rtl::OUString const component = aRequest.getComponentName();
+ ITemplateDataProvider * const aTemplateProvider = _aTemplateProvider ? _aTemplateProvider : this;
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::BackendAccess", "jb99855", "configmgr: BackendAccess::getNodeData()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "request path: %s", RTL_LOGFILE_OU2A(component) );
+
+ uno::Sequence<uno::Reference<backenduno::XLayer> > layers =
+ this->getLayers(component, aRequest.getOptions()) ;
+
+ sal_Int32 const k_NumUserLayers = 1;
+
+ sal_Int32 nNumDefaultLayers = layers.getLength() - k_NumUserLayers;
+ sal_Int32 nCurrentLayer( -1 );
+ bool bDefaultRecoveryApproved = false;
+
+ Logger logger(mContext);
+ do try // loop to allow recovery from merge failures
+ {
+ MergedComponentData aComponentData;
+ nCurrentLayer = -1;
+
+ if (!this->readDefaultData(aComponentData, component, aRequest.getOptions(), true,
+ layers.getConstArray(),nNumDefaultLayers,
+ aTemplateProvider, &nCurrentLayer))
+ {
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("Configuration: No data for request. Component \"");
+ sMessage.append(component);
+ sMessage.appendAscii("\" contains no data. ");
+
+ throw com::sun::star::container::NoSuchElementException(sMessage.makeStringAndClear(),mBackend);
+ }
+ OSL_ASSERT(nCurrentLayer == nNumDefaultLayers);
+
+ sal_Int32 const nNumUserLayers = layers.getLength() - nNumDefaultLayers;
+ if (nNumUserLayers > 0)
+ {
+ //Merge User layer (with all locales)
+ logger.finer("... merging user layer", "getNodeData()","configmgr::Backend");
+
+ std::vector< com::sun::star::lang::Locale > aLocales;
+ merge(aComponentData,
+ layers.getConstArray()+nNumDefaultLayers, nNumUserLayers,
+ localehelper::getAnyLocale(), aLocales, aTemplateProvider );
+
+ // mark this one as done
+ ++nCurrentLayer;
+ }
+
+ logger.finer("Reading component data finished successfully", "getNodeData()","configmgr::Backend");
+
+ ComponentInstance retCode(aComponentData.extractSchemaTree(),
+ aComponentData.extractTemplatesTree(),
+ aRequest.getComponentName()) ;
+
+ //Register listener with notifier
+ if(aListener)
+ {
+ mNotifier->addListener(aListener, aRequest);
+ }
+ return ResultHolder< ComponentInstance >(retCode) ;
+ }
+ catch (com::sun::star::container::NoSuchElementException &) { throw; }
+ catch (com::sun::star::uno::RuntimeException &) { throw; }
+ catch (uno::Exception & )
+ {
+ // can only recover if layer merging broke
+ if (nCurrentLayer < 0 || layers.getLength() <= nCurrentLayer)
+ throw;
+
+ uno::Reference< backenduno::XLayer > xBrokenLayer = layers[nCurrentLayer];
+
+ bool bUserLayerBroken = (nCurrentLayer == nNumDefaultLayers);
+
+ if (!bDefaultRecoveryApproved || bUserLayerBroken)
+ {
+ logger.info("Parsing data layer failed. Requesting approval for automated recovery", "getNodeData()","configmgr::Backend");
+ uno::Any theError = cppu::getCaughtException();
+ if (!approveRecovery(theError,xBrokenLayer,bUserLayerBroken))
+ cppu::throwException( theError );
+ }
+
+ // now do the recovery
+ discardLayer(layers,nCurrentLayer);
+ if (bUserLayerBroken)
+ {
+ logger.info("Recovering from broken user data layer - discarding the data", "getNodeData()","configmgr::Backend");
+ removeLayerData(xBrokenLayer);
+ }
+ else
+ {
+ logger.info("Recovering from broken default layer - skipping", "getNodeData()","configmgr::Backend");
+ bDefaultRecoveryApproved = true;
+ --nNumDefaultLayers;
+ }
+ }
+ while (true);
+}
+//------------------------------------------------------------------------------
+
+void BackendAccess::updateNodeData(const UpdateRequest& aUpdate)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ rtl::OUString entity = aUpdate.getOptions().getEntity() ;
+ rtl::OUString component =
+ aUpdate.getUpdateRoot().getModuleName();
+ uno::Reference<backenduno::XUpdateHandler> handler ;
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::BackendAccess", "jb99855", "configmgr: BackendAccess::updateNodeData()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "updating component: %s", RTL_LOGFILE_OU2A(component) );
+
+ if (entity.getLength() == 0) {
+ handler = mBackend->getOwnUpdateHandler(component) ;
+ }
+ else { handler = mBackend->getUpdateHandler(component, entity) ; }
+ UpdateDispatcher dispatcher(handler, aUpdate.getOptions().getLocale()) ;
+
+ dispatcher.dispatchUpdate(aUpdate.getUpdateRoot(),
+ *aUpdate.getUpdateData()) ;
+}
+//------------------------------------------------------------------------------
+
+ResultHolder< NodeInstance > BackendAccess::getDefaultData(const NodeRequest& aRequest)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ rtl::OUString const component = aRequest.getPath().getModuleName();
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::BackendAccess", "jb99855", "configmgr: BackendAccess::getDefaultData()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "request path: %s", RTL_LOGFILE_OU2A(aRequest.getPath().toString()) );
+
+ uno::Sequence<uno::Reference<backenduno::XLayer> > const layers =
+ this->getLayers(component, aRequest.getOptions()) ;
+
+ sal_Int32 const nNumUserLayers = 1;
+ sal_Int32 const nNumDefaultLayers = layers.getLength() - nNumUserLayers;
+
+ MergedComponentData aComponentData;
+
+ if (!this->readDefaultData(aComponentData, component, aRequest.getOptions(), false,
+ layers.getConstArray(),nNumDefaultLayers,
+ this))
+ {
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("Configuration: No data for request. Component \"");
+ sMessage.append(component);
+ sMessage.appendAscii("\" contains no default data. ");
+
+ rtl::OUString const sMsg = sMessage.makeStringAndClear();
+ Logger(mContext).finer(sMsg,"getDefaultData()","configmgr::BackendAccess");
+ throw com::sun::star::container::NoSuchElementException(sMsg,mBackend);
+ }
+
+ std::auto_ptr<ISubtree> aResultTree = aComponentData.extractSchemaTree();
+
+ configuration::AbsolutePath aPath = aRequest.getPath();
+ if( aPath.begin() != aPath.end())
+ {
+ for(std::vector<configuration::Path::Component>::const_reverse_iterator it=aPath.begin()+1,endIt=aPath.end();it!=endIt; ++it)
+ {
+ std::auto_ptr<INode> aChild=aResultTree->removeChild(it->getName());
+ if(aChild.get()== NULL)
+ {
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("Configuration: No data for request. Element \"");
+ sMessage.append(aPath.toString());
+ sMessage.appendAscii("\" does not exist in the default data. ");
+
+ rtl::OUString const sMsg = sMessage.makeStringAndClear();
+ Logger(mContext).finest(sMsg,"getDefaultData()","configmgr::BackendAccess");
+ throw com::sun::star::container::NoSuchElementException(sMsg,mBackend);
+ }
+
+ ISubtree *pChildAsSubtree = aChild->asISubtree();
+ if(pChildAsSubtree == NULL)
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("BackendAccess::getDefaultData - Node Expected, Found Property: ").concat(it->getName());
+ Logger(mContext).finer(sMsg,"getDefaultData()","configmgr::BackendAccess");
+ throw backenduno::MalformedDataException(sMsg, mBackend, uno::Any());
+ }
+ aResultTree.reset(pChildAsSubtree);
+ aChild.release();
+ }
+ }
+
+ NodeInstance retCode(aResultTree, aRequest.getPath()) ;
+ return ResultHolder< NodeInstance >(retCode) ;
+}
+//------------------------------------------------------------------------------
+
+ResultHolder< TemplateInstance > BackendAccess::getTemplateData(const TemplateRequest& aRequest)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ rtl::OUString component = aRequest.getComponentName();
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::BackendAccess", "jb99855", "configmgr: BackendAccess::getTemplateData()");
+ RTL_LOGFILE_CONTEXT_TRACE2(aLog, "requested template: %s/%s",
+ RTL_LOGFILE_OU2A(aRequest.getComponentName().toString()) ,
+ aRequest.isComponentRequest() ? "*" : RTL_LOGFILE_OU2A(aRequest.getComponentName().toString()) );
+
+ MergedComponentData aComponentData;
+
+ {
+ SchemaBuilder *schemaBuilder = new SchemaBuilder( mContext, component, aComponentData ) ;
+ uno::Reference<backenduno::XSchemaHandler> handler = schemaBuilder ;
+
+ uno::Reference<backenduno::XSchema> schema = this->getSchema(component);
+
+ schema->readTemplates(handler) ;
+ }
+
+ TemplateInstance::Data aResultData;
+ if (aRequest.isComponentRequest())
+ {
+ aResultData.reset( aComponentData.extractTemplatesTree().release() );
+ }
+ else
+ {
+ backenduno::TemplateIdentifier templateId ;
+ templateId.Name = aRequest.getTemplateName();
+ templateId.Component = aRequest.getComponentName();
+
+ aResultData = aComponentData.extractTemplateNode(templateId.Name);
+ }
+
+ TemplateInstance retCode(aResultData,aRequest.getTemplateName(), aRequest.getComponentName()) ;
+ return ResultHolder< TemplateInstance >(retCode) ;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference< backenduno::XSchema > BackendAccess::getSchema(const rtl::OUString& aComponent)
+{
+ uno::Reference< backenduno::XSchemaSupplier > xSchemaBackend(mBackend, uno::UNO_QUERY_THROW);
+ OSL_ASSERT(xSchemaBackend.is());
+
+ uno::Reference< backenduno::XSchema > xSchema = xSchemaBackend->getComponentSchema(aComponent) ;
+ if (!xSchema.is())
+ {
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("Configuration: No data for request. Component \"");
+ sMessage.append(aComponent);
+ sMessage.appendAscii("\" is unknown. [No schema available]");
+
+ rtl::OUString const sMsg = sMessage.makeStringAndClear();
+ Logger(mContext).warning(sMsg,"getSchema()","configmgr::BackendAccess");
+ throw com::sun::star::container::NoSuchElementException(sMsg,xSchemaBackend);
+ }
+
+ return xSchema;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString BackendAccess::getSchemaVersion(const rtl::OUString& aComponent)
+{
+ uno::Reference< backenduno::XVersionedSchemaSupplier > xSchemaBackend(mBackend, uno::UNO_QUERY);
+ if (xSchemaBackend.is())
+ return xSchemaBackend->getSchemaVersion(aComponent);
+ else
+ return rtl::OUString();
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence< uno::Reference<backenduno::XLayer> > BackendAccess::getLayers(const rtl::OUString& aComponent,const RequestOptions& aOptions)
+{
+ rtl::OUString aEntity = aOptions.getEntity() ;
+
+ if (aEntity.getLength() == 0)
+ {
+ // Use own entity instead
+ return mBackend->listOwnLayers(aComponent) ;
+ }
+ else
+ {
+ return mBackend->listLayers(aComponent, aEntity) ;
+ }
+}
+//------------------------------------------------------------------------------
+void BackendAccess::removeRequestListener(INodeDataListener *aListener,
+ const ComponentRequest& aRequest)
+ SAL_THROW(())
+{
+
+ OSL_PRECOND(aListener, "ERROR: trying to remove a NULL listener");
+ mNotifier->removeListener(aListener, aRequest);
+}
+//------------------------------------------------------------------------------
+} } // configmgr.backend
diff --git a/configmgr/source/backend/backendaccess.hxx b/configmgr/source/backend/backendaccess.hxx
new file mode 100644
index 000000000000..e89bd9b11b87
--- /dev/null
+++ b/configmgr/source/backend/backendaccess.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendaccess.hxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_BACKENDACCESS_HXX_
+#define CONFIGMGR_BACKEND_BACKENDACCESS_HXX_
+
+#include "backendnotifier.hxx"
+#include "mergeddataprovider.hxx"
+#include "mergedcomponentdata.hxx"
+#include "matchlocale.hxx"
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+#include <com/sun/star/configuration/backend/XSchema.hpp>
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include "binarycache.hxx"
+#include <com/sun/star/configuration/backend/XBackendChangesNotifier.hpp>
+
+
+namespace configmgr { namespace backend {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backenduno = css::configuration::backend ;
+
+/**
+ Implementation of IMergedDataProvider handling the access
+ to the configuration data.
+ */
+class BackendAccess : public IMergedDataProvider
+{
+ public :
+ /**
+ Constructor using an XBackend implementation and a
+ service factory.
+
+ @param xBackend backend used for access to data
+ @param xContext uno context for instantiation of services
+ */
+ BackendAccess( const uno::Reference<backenduno::XBackend>& xBackend,
+ const uno::Reference<uno::XComponentContext>& xContext) ;
+ /** Destructor */
+ ~BackendAccess(void) ;
+
+ // IMergedDataProvider
+ virtual ResultHolder< ComponentInstance > getNodeData(const ComponentRequest& aRequest,
+ ITemplateDataProvider* aTemplateProvider,
+ INodeDataListener *aListener = NULL)
+ SAL_THROW((com::sun::star::uno::Exception)) ;
+ virtual void removeRequestListener(INodeDataListener *aListener,
+ const ComponentRequest& aRequest)
+ SAL_THROW(());
+ virtual void updateNodeData(const UpdateRequest& aUpdate)
+ SAL_THROW((com::sun::star::uno::Exception)) ;
+ virtual ResultHolder< NodeInstance > getDefaultData(const NodeRequest& aRequest)
+ SAL_THROW((com::sun::star::uno::Exception)) ;
+ virtual ResultHolder< TemplateInstance > getTemplateData(const TemplateRequest& aRequest)
+ SAL_THROW((com::sun::star::uno::Exception)) ;
+
+ private :
+
+ /**
+ Retrieves the schema of a component.
+ */
+ uno::Reference< backenduno::XSchema > getSchema(const rtl::OUString& aComponent) ;
+
+ /**
+ Retrieves the schema version of a component.
+ */
+ rtl::OUString getSchemaVersion(const rtl::OUString& aComponent) ;
+
+ /**
+ Retrieves the layers for a request.
+ */
+ uno::Sequence< uno::Reference<backenduno::XLayer> > getLayers(const rtl::OUString& aComponent,const RequestOptions& aOptions) ;
+
+ /**
+ Reads merged default data with a given number of layers.
+ */
+ bool readDefaultData( MergedComponentData & aComponentData,
+ rtl::OUString const & aComponent,
+ RequestOptions const & aOptions,
+ bool bIncludeTemplates,
+ const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ ITemplateDataProvider *aTemplateProvider,
+ sal_Int32 * pLayersMerged = 0)
+ SAL_THROW((com::sun::star::uno::Exception));
+ /**
+ Merges layers onto component data.
+ */
+ void merge(
+ MergedComponentData& aData,
+ const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 aNumLayers,
+ com::sun::star::lang::Locale const & aRequestedLocale,
+ std::vector< com::sun::star::lang::Locale > & inoutMergedLocales,
+ ITemplateDataProvider *aTemplateProvider,
+ sal_Int32 * pLayersMerged = 0)
+ SAL_THROW((com::sun::star::uno::Exception));
+ private :
+ /**
+ Decides if merging should be retried after an exception.
+
+ @throws com::sun::star::uno::Exception
+ if not approved
+ */
+ bool approveRecovery(
+ const uno::Any & aMergeException,
+ const uno::Reference<backenduno::XLayer> & aBrokenLayer,
+ bool bUserLayerData)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ private :
+ /** Get the factory used for service invocation */
+ uno::Reference<lang::XMultiServiceFactory> getServiceFactory() const;
+ /** UNO context to which this backend belongs */
+ uno::Reference<uno::XComponentContext> mContext ;
+ /** Backend being accessed */
+ uno::Reference<backenduno::XBackend> mBackend ;
+ /** Binary cache of default data */
+ BinaryCache mBinaryCache;
+ /** Manages Nofification from the Backends */
+ uno::Reference<backenduno::XBackendChangesListener> mXNotifier;
+
+ BackendChangeNotifier * mNotifier;
+
+} ;
+
+} } // configmgr.backend
+
+#endif // CONFIGMGR_BACKEND_BACKENDACCESS_HXX_
diff --git a/configmgr/source/backend/backendfactory.cxx b/configmgr/source/backend/backendfactory.cxx
new file mode 100644
index 000000000000..f5989f008a86
--- /dev/null
+++ b/configmgr/source/backend/backendfactory.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendfactory.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "backendfactory.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include "bootstrapcontext.hxx"
+#include "bootstrap.hxx"
+#include "backendaccess.hxx"
+#include "serviceinfohelper.hxx"
+#include "wrapexception.hxx"
+
+
+#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+#include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
+
+namespace configmgr
+{
+// -------------------------------------------------------------------------
+ namespace backend
+ {
+// -------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -------------------------------------------------------------------------
+const sal_Char k_DefaultBackendWrapper[] = "com.sun.star.comp.configuration.backend.SingleBackendAdapter";
+const sal_Char k_DefaultBackendService[] = "com.sun.star.comp.configuration.backend.LocalSingleBackend";
+
+// -------------------------------------------------------------------------
+const sal_Char k_DefaultBackendServiceAndImplName[] = K_DefaultBackendServiceAndImplName ;
+
+// -------------------------------------------------------------------------
+const sal_Char k_GenericBackendServiceAndImplName[] = "com.sun.star.configuration.backend.Backend" ;
+
+// -------------------------------------------------------------------------
+static sal_Char const * const k_BackendServiceNames [] =
+{
+ k_DefaultBackendServiceAndImplName,
+ k_GenericBackendServiceAndImplName,
+ 0
+};
+// -------------------------------------------------------------------------
+static const ServiceRegistrationInfo k_DefaultBackendServiceInfo =
+{
+ k_DefaultBackendServiceAndImplName,
+ k_BackendServiceNames
+};
+// -------------------------------------------------------------------------
+static const ServiceRegistrationInfo k_GenericBackendServiceInfo =
+{
+ k_GenericBackendServiceAndImplName,
+ k_BackendServiceNames + 1
+};
+// -------------------------------------------------------------------------
+static const SingletonRegistrationInfo k_DefaultBackendSingletonInfo =
+{
+ K_DefaultBackendSingletonName,
+ k_DefaultBackendServiceAndImplName,
+ k_DefaultBackendServiceAndImplName,
+ & k_GenericBackendServiceInfo
+};
+// -------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+const SingletonRegistrationInfo * getDefaultBackendSingletonInfo()
+{
+ return & k_DefaultBackendSingletonInfo;
+}
+// -------------------------------------------------------------------------
+
+const ServiceRegistrationInfo * getDefaultBackendServiceInfo()
+{
+ return & k_DefaultBackendServiceInfo;
+}
+// -------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+
+uno::Reference<uno::XInterface> SAL_CALL
+ getDefaultBackendSingleton( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const& xContext )
+{
+ OSL_ENSURE( xContext.is(), "ERROR: NULL context has no singletons" );
+
+ UnoContextTunnel aTunnel;
+ aTunnel.passthru( xContext );
+
+ uno::Reference<uno::XInterface> xResult;
+
+ if (xContext.is())
+ try
+ {
+ xContext->getValueByName(SINGLETON(K_DefaultBackendSingletonName))
+ >>= xResult;
+ }
+ catch (uno::Exception & )
+ {
+ // to do: really use the tunneled failure when that is set properly
+ if ( aTunnel.recoverFailure(true).hasValue() )
+ {
+ // have a failure, but can't recover it
+ // -> try to regenerate
+ instantiateDefaultBackend(xContext);
+
+ OSL_ENSURE(false, "Cannot recreate configuration backend instantiation failure - using generic error");
+ }
+ // cannot recover any failure
+ throw;
+ }
+
+ return xResult;
+}
+// -------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+
+static
+uno::Sequence< uno::Any > createInitArgs(ContextReader const & _aContext)
+{
+ OSL_ASSERT(_aContext.hasBootstrapContext());
+ uno::Sequence< uno::Any > aResult( 1 );
+ aResult[0] <<= _aContext.getBootstrapContext();
+ return aResult;
+}
+// -------------------------------------------------------------------------
+
+static
+inline
+uno::Reference< uno::XInterface > createService(ContextReader const & _aCtx, uno::Sequence< uno::Any > const & _aInitArgs, rtl::OUString const & _aSvc)
+{
+ uno::Reference< lang::XMultiComponentFactory > xFactory = _aCtx.getServiceManager();
+ OSL_ENSURE(xFactory.is(),"ERROR: ComponentContext has no service manager\n");
+ if (!xFactory.is()) throw uno::RuntimeException( rtl::OUString::createFromAscii("ERROR: ComponentContext has no service manager\n"), NULL );
+ return xFactory->createInstanceWithArgumentsAndContext( _aSvc, _aInitArgs, _aCtx.getBaseContext());
+}
+// -------------------------------------------------------------------------
+
+static
+uno::Reference< backenduno::XBackend > wrapSingleBackend(ContextReader const & _aSettings, uno::Sequence< uno::Any > const & _aInitArgs, uno::Reference< backenduno::XMultiLayerStratum > const & _xWrappedBackend)
+{
+ OSL_ASSERT(_aSettings.hasUnoBackendWrapper() || _aSettings.hasBootstrapContext());
+
+ rtl::OUString aWrapperSvc = _aSettings.hasUnoBackendWrapper() ?
+ _aSettings.getUnoBackendWrapper() :
+ rtl::OUString::createFromAscii(k_DefaultBackendWrapper);
+
+ OSL_ENSURE (aWrapperSvc.getLength(), "ERROR: No wrapper service for wrapped configuration");
+ OSL_ENSURE (_xWrappedBackend.is(), "ERROR: No backend to wrap for wrapped configuration");
+
+ sal_Int32 const nBaseArgsCount = _aInitArgs.getLength();
+ uno::Sequence< uno::Any > aExtendedArgs( _aInitArgs );
+ aExtendedArgs.realloc( nBaseArgsCount + 1 );
+ aExtendedArgs[nBaseArgsCount] <<= _xWrappedBackend;
+
+ return uno::Reference< backenduno::XBackend >::query( createService(_aSettings,aExtendedArgs,aWrapperSvc) );
+}
+// -------------------------------------------------------------------------
+
+static
+uno::Reference< backenduno::XBackend > createOfflineBackend(ContextReader const & _aSettings, uno::Sequence< uno::Any > const & _aInitArgs)
+{
+ OSL_ASSERT(_aSettings.hasUnoBackendWrapper() || _aSettings.hasBootstrapContext());
+
+ uno::Reference< backenduno::XBackend > xResult;
+ if ( _aSettings.hasUnoBackendWrapper() )
+ {
+ rtl::OUString const aWrapperSvc = _aSettings.getUnoBackendWrapper();
+
+ xResult = uno::Reference< backenduno::XBackend >::query( createService(_aSettings,_aInitArgs,aWrapperSvc) );
+ }
+
+ return xResult;
+}
+// -------------------------------------------------------------------------
+
+static
+uno::Reference< uno::XInterface > createRealBackend(ContextReader const & _aSettings, uno::Sequence< uno::Any > const & _aInitArgs)
+{
+ OSL_ASSERT(_aSettings.hasUnoBackendService() || _aSettings.hasBootstrapContext());
+
+ rtl::OUString const aBackendServiceName = _aSettings.hasUnoBackendService() ?
+ _aSettings.getUnoBackendService() :
+ rtl::OUString::createFromAscii(k_DefaultBackendService);
+
+ uno::Reference< uno::XInterface > xResult =
+ createService(_aSettings,_aInitArgs,aBackendServiceName);
+
+ return xResult;
+}
+// -------------------------------------------------------------------------
+
+static
+uno::Reference< backenduno::XBackend > createOnlineBackend(ContextReader const & _aSettings, uno::Sequence< uno::Any > const & _aInitArgs)
+{
+ OSL_ENSURE( _aSettings.isUnoBackend(), "ERROR - BackendFactory: For legacy backends use createSessionBackend()");
+
+ uno::Reference< backenduno::XBackend > xResult;
+
+ uno::Reference< uno::XInterface > xRealBackend = createRealBackend(_aSettings,_aInitArgs);
+
+ if (_aSettings.hasUnoBackendWrapper())
+ {
+ // try wrapping a single backend
+ uno::Reference< backenduno::XMultiLayerStratum > xSingleRealBackend( xRealBackend, uno::UNO_QUERY);
+ if (xSingleRealBackend.is())
+ xResult = wrapSingleBackend(_aSettings,_aInitArgs,xSingleRealBackend);
+
+ // if we don't have one, try using it as unwrapped backend
+ else
+ xResult.set(xRealBackend, uno::UNO_QUERY);
+ }
+ else
+ {
+ // look for a direct implementation of XBackend
+ xResult.set(xRealBackend, uno::UNO_QUERY);
+ if (!xResult.is())
+ {
+ // try the default wrapper if we only have a single backend
+ uno::Reference< backenduno::XMultiLayerStratum > xSingleRealBackend( xRealBackend, uno::UNO_QUERY);
+ if (xSingleRealBackend.is())
+ xResult = wrapSingleBackend(_aSettings,_aInitArgs,xSingleRealBackend);
+
+ else
+ OSL_ENSURE( !xRealBackend.is(), "Configuration Backend implements no known backend interface" );
+ }
+ }
+
+ return xResult;
+}
+// -------------------------------------------------------------------------
+
+static uno::Reference< backenduno::XBackend > createUnoBackend(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const& _xCtx)
+{
+ ContextReader aSettings(_xCtx);
+ OSL_ENSURE( aSettings.isUnoBackend(), "ERROR - BackendFactory: Legacy backends are not supported any more");
+
+ uno::Sequence< uno::Any > aArguments = createInitArgs(aSettings);
+
+ sal_Bool bOffline = aSettings.hasOfflineSetting() ? aSettings.getOfflineSetting() : !aSettings.hasUnoBackendService();
+
+ uno::Reference< backenduno::XBackend > xResult;
+
+ if (!bOffline)
+ xResult = createOnlineBackend (aSettings,aArguments);
+
+ if (!xResult.is())
+ xResult = createOfflineBackend(aSettings,aArguments);
+
+ return xResult;
+}
+// -------------------------------------------------------------------------
+// to do: tunnel and raise fully typed exception information (and use it in the get..Singleton wrappers)
+ #define TUNNEL_ALL_EXCEPTIONS() \
+ WRAP_CONFIGBACKEND_CREATION_EXCEPTIONS1( UnoContextTunnel::tunnelFailure, true )
+
+// -------------------------------------------------------------------------
+
+uno::Reference<uno::XInterface> SAL_CALL instantiateDefaultBackend( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const& xTargetContext )
+{
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext = UnoContextTunnel::recoverContext(xTargetContext);
+
+ try
+ {
+ return uno::Reference< uno::XInterface >( createUnoBackend(xContext), uno::UNO_QUERY );
+ }
+ TUNNEL_ALL_EXCEPTIONS()
+
+ OSL_ASSERT(!"unreached");
+ return NULL;
+}
+// -------------------------------------------------------------------------
+
+uno::Reference< backenduno::XBackend > BackendFactory::getUnoBackend()
+{
+ return uno::Reference< backenduno::XBackend >::query( getDefaultBackendSingleton(m_xCtx) );
+}
+// -------------------------------------------------------------------------
+
+rtl::Reference<IMergedDataProvider> BackendFactory::createBackend()
+{
+ rtl::Reference< IMergedDataProvider > xBackend;
+
+ uno::Reference< backenduno::XBackend > xBackendService = this->getUnoBackend();
+
+ if (xBackendService.is())
+ xBackend = new BackendAccess(xBackendService, m_xCtx);
+
+ return xBackend;
+}
+// -------------------------------------------------------------------------
+
+BackendFactory BackendFactory::instance(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & _xCtx)
+{
+ return BackendFactory(_xCtx);
+}
+
+//-----------------------------------------------------------------------------
+ } // namespace
+//-----------------------------------------------------------------------------
+} // namespace
diff --git a/configmgr/source/backend/backendnotifier.cxx b/configmgr/source/backend/backendnotifier.cxx
new file mode 100644
index 000000000000..22991285f4a9
--- /dev/null
+++ b/configmgr/source/backend/backendnotifier.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendnotifier.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "backendnotifier.hxx"
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+#include "configpath.hxx"
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+ namespace backend
+ {
+
+
+//----------------------------------------------------------------------------
+BackendChangeNotifier::BackendChangeNotifier(const uno::Reference<backenduno::XBackend>& _xBackend)
+: m_aMutex()
+ ,m_aListeners()
+ ,m_aBackend(_xBackend, uno::UNO_QUERY)
+{
+
+}
+// ---------------------------------------------------------------------------
+
+BackendChangeNotifier::~BackendChangeNotifier()
+{
+ m_aListeners.clear();
+}
+// ---------------------------------------------------------------------------
+void SAL_CALL BackendChangeNotifier::componentDataChanged(const backenduno::ComponentChangeEvent& _aEvent)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ rtl::OUString aComponentName = _aEvent.Component;
+ std::map<rtl::OUString, ComponentNotifier>::iterator aIter = m_aListeners.find(aComponentName);
+ if(aIter != m_aListeners.end())
+ {
+ aIter->second.notifyListeners(aComponentName);
+ }
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL BackendChangeNotifier::disposing( lang::EventObject const & /*rSource*/ )
+throw (uno::RuntimeException)
+{
+ osl::MutexGuard aListGuard(m_aMutex);
+ if (m_aBackend.is())
+ {
+ m_aBackend.clear();
+ }
+ m_aListeners.clear();
+}
+// -----------------------------------------------------------------------------
+void BackendChangeNotifier::addListener(INodeDataListener * _xListener, const ComponentRequest& _aRequest) SAL_THROW(())
+{
+ osl::MutexGuard aListGuard(m_aMutex);
+
+ OSL_PRECOND(_xListener, "ERROR: trying to register a NULL listener");
+ ComponentListener aComponentListener(_xListener, _aRequest.getOptions());
+
+ const rtl::OUString aComponentName = _aRequest.getComponentName();
+
+ //Check if we have a Listener registered for that Component
+ std::map<rtl::OUString, ComponentNotifier>::iterator aIter;
+ aIter = m_aListeners.find(aComponentName);
+ if (aIter == m_aListeners.end())
+ {
+ ComponentNotifier aComponentNotifier;
+ aComponentNotifier.addListenerToList(aComponentListener);
+ m_aListeners[aComponentName] = aComponentNotifier;
+
+ //Now need to register Listener with MultiStratumBackend for that Component
+ if (m_aBackend.is())
+ {
+ m_aBackend->addChangesListener(this, aComponentName);
+ }
+ }
+ else
+ {
+ //Add Listener and Option to ComponentNotifier list
+ aIter->second.addListenerToList(aComponentListener);
+
+ }
+
+}
+// ---------------------------------------------------------------------------
+
+void BackendChangeNotifier::removeListener(INodeDataListener * _xListener, const ComponentRequest& _aRequest) SAL_THROW(())
+{
+ osl::MutexGuard aListGuard(m_aMutex);
+ OSL_PRECOND(!m_aListeners.empty(),
+ "BackendChangeNotifier:Cannot Remove Listener, no Listeners Registered");
+ OSL_PRECOND(_xListener, "ERROR: trying to remove a NULL listener");
+
+ std::map<rtl::OUString, ComponentNotifier>::iterator aIter;
+ rtl::OUString aComponentName = _aRequest.getComponentName();
+
+ aIter = m_aListeners.find(aComponentName);
+ if (aIter == m_aListeners.end())
+ {
+ OSL_TRACE("BackendChangeNotifier: removeListener: no listener registered for component %s",
+ aComponentName.getStr());
+ }
+ else
+ {
+ ComponentListener aComponentListener(_xListener, _aRequest.getOptions());
+ aIter->second.removeListenerFromList(aComponentListener);
+ if (aIter->second.isListEmpty())
+ {
+ m_aListeners.erase(aIter);
+ //Need all to de-register listeners from the lower layers
+ if (m_aBackend.is())
+ {
+ m_aBackend->removeChangesListener(this, aComponentName);
+ }
+ }
+ }
+
+}
+// ---------------------------------------------------------------------------
+ComponentNotifier::ComponentNotifier():m_aListenerList()
+{
+}
+// ---------------------------------------------------------------------------
+
+
+void ComponentNotifier::addListenerToList(const ComponentListener& _aListener)
+{
+ m_aListenerList.push_back(_aListener);
+ //REM TO REMOVE
+ ComponentListener aListener = m_aListenerList.front();
+
+}
+// ---------------------------------------------------------------------------
+void ComponentNotifier::removeListenerFromList(const ComponentListener& _aListener)
+{
+ OSL_PRECOND(!m_aListenerList.empty(),
+ "ComponentNotifier:Cannot Remove Listener, no Listeners Registered");
+
+ std::list<ComponentListener>::iterator aIter;
+
+ //Remove first instance that matches in the list
+ aIter = std::find(m_aListenerList.begin(), m_aListenerList.end(),_aListener);
+ if(aIter != m_aListenerList.end())
+ {
+ m_aListenerList.erase(aIter);
+ }
+}
+// ---------------------------------------------------------------------------
+void ComponentNotifier::notifyListeners(const rtl::OUString& _aComponent)
+{
+
+ for( std::list<ComponentListener>::iterator aIter = m_aListenerList.begin();
+ aIter != m_aListenerList.end(); aIter++)
+ {
+ ComponentRequest aRequest(_aComponent, (*aIter).m_aOptions);
+
+ (*aIter).m_aListener->dataChanged(aRequest);
+ }
+
+}
+// ---------------------------------------------------------------------------
+ } // namespace backend
+
+// ---------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/backendnotifier.hxx b/configmgr/source/backend/backendnotifier.hxx
new file mode 100644
index 000000000000..5f3840ec8e4a
--- /dev/null
+++ b/configmgr/source/backend/backendnotifier.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendnotifier.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_BACKEND_BACKENDNOTIFIER_HXX
+#define CONFIGMGR_BACKEND_BACKENDNOTIFIER_HXX
+
+#include "mergeddataprovider.hxx"
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+#include <com/sun/star/configuration/backend/XBackendChangesNotifier.hpp>
+#include <osl/mutex.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+#ifndef INCLUDED_LIST
+#include <list>
+#define INCLUDED_LIST
+#endif
+
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// ---------------------------------------------------------------------------
+ struct ComponentListener
+ {
+ explicit
+ ComponentListener(INodeDataListener * _xListener, RequestOptions _aOptions):
+ m_aListener( _xListener),
+ m_aOptions(_aOptions)
+ {}
+
+ bool operator==(const ComponentListener& _aListener)const
+ {
+ return ( (&m_aListener == &_aListener.m_aListener)&&
+ (compareRequestOptions(m_aOptions, _aListener.m_aOptions)== 0) );
+
+ }
+ INodeDataListener * m_aListener;
+ RequestOptions m_aOptions;
+ };
+
+ /** Class used to store ComponentListener(listener and options)
+ */
+ class ComponentNotifier
+ {
+ public:
+ ComponentNotifier();
+ void addListenerToList(const ComponentListener& _aListener);
+ void removeListenerFromList(const ComponentListener& _aListener);
+ bool isListEmpty(){ return m_aListenerList.empty();}
+ void notifyListeners(const rtl::OUString& _aComponent);
+ private:
+ std::list<ComponentListener> m_aListenerList;
+ };
+ // ---------------------------------------------------------------------------
+ /** Interface providing a multicasting service for changes in the backend
+ */
+ class BackendChangeNotifier :public cppu::WeakImplHelper1<backenduno::XBackendChangesListener>
+ {
+ public:
+ BackendChangeNotifier(const uno::Reference<backenduno::XBackend>& _xBackend);
+ ~BackendChangeNotifier();
+
+ virtual void SAL_CALL componentDataChanged(const backenduno::ComponentChangeEvent& aEvent)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL disposing( lang::EventObject const & rSource )
+ throw (uno::RuntimeException);
+ // notification support.
+ /// register a listener for observing changes to the cached data
+ void addListener(INodeDataListener * _xListener, const ComponentRequest& _aRequest) SAL_THROW(());
+ /// unregister a listener previously registered
+ void removeListener(INodeDataListener * _xListener, const ComponentRequest& _aRequest) SAL_THROW(());
+ private:
+ osl::Mutex m_aMutex;
+ std::map<rtl::OUString, ComponentNotifier> m_aListeners;
+
+ /** Backend being accessed */
+ uno::Reference<backenduno::XBackendChangesNotifier> m_aBackend ;
+ };
+// ---------------------------------------------------------------------------
+ } // namespace backend
+
+// ---------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/backend/backendstratalistener.cxx b/configmgr/source/backend/backendstratalistener.cxx
new file mode 100644
index 000000000000..b8f19dd0f064
--- /dev/null
+++ b/configmgr/source/backend/backendstratalistener.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendstratalistener.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "backendstratalistener.hxx"
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+ // -----------------------------------------------------------------------------
+ BackendStrataListener::BackendStrataListener(const MultiStratumBackend& aBackend)
+ :mBackend(aBackend)
+ {}
+ BackendStrataListener:: ~BackendStrataListener(){}
+
+ void SAL_CALL BackendStrataListener::componentDataChanged(const backenduno::ComponentChangeEvent& aEvent)
+ throw (::com::sun::star::uno::RuntimeException)
+ {
+
+ mBackend.notifyListeners(aEvent);
+
+ }
+ // -----------------------------------------------------------------------------
+ void SAL_CALL BackendStrataListener::disposing( lang::EventObject const & /*rSource*/ )
+ throw (uno::RuntimeException)
+ {
+
+ }
+ }
+}
diff --git a/configmgr/source/backend/backendstratalistener.hxx b/configmgr/source/backend/backendstratalistener.hxx
new file mode 100644
index 000000000000..826b3269efd6
--- /dev/null
+++ b/configmgr/source/backend/backendstratalistener.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendstratalistener.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_BACKEND_BACKENDSTRATALISTENER_HXX
+#define CONFIGMGR_BACKEND_BACKENDSTRATALISTENER_HXX
+
+#include <com/sun/star/configuration/backend/XBackendChangesListener.hpp>
+#include <com/sun/star/configuration/backend/ComponentChangeEvent.hpp>
+#include "backendnotifier.hxx"
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+#include "multistratumbackend.hxx"
+
+
+#include <cppuhelper/implbase1.hxx>
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ namespace backenduno = ::com::sun::star::configuration::backend;
+ // --------------------------------------------------------------------------
+ class BackendStrataListener: public cppu::WeakImplHelper1<backenduno::XBackendChangesListener>
+ {
+ public:
+ BackendStrataListener(const MultiStratumBackend& aBackend);
+ ~BackendStrataListener();
+ virtual void SAL_CALL componentDataChanged(const backenduno::ComponentChangeEvent& aEvent)
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL disposing( lang::EventObject const & rSource )
+ throw (uno::RuntimeException);
+ private:
+ const MultiStratumBackend& mBackend ;
+
+ };
+
+
+
+ }
+ // -----------------------------------------------------------------------------
+}
+// -----------------------------------------------------------------------------
+#endif
diff --git a/configmgr/source/backend/basicimporthandler.cxx b/configmgr/source/backend/basicimporthandler.cxx
new file mode 100644
index 000000000000..68bc9d113ce1
--- /dev/null
+++ b/configmgr/source/backend/basicimporthandler.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: basicimporthandler.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "basicimporthandler.hxx"
+#include <com/sun/star/configuration/backend/ComponentChangeEvent.hpp>
+#include <com/sun/star/configuration/backend/XBackendChangesNotifier.hpp>
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+BasicImportHandler::BasicImportHandler(
+ uno::Reference< backenduno::XBackend > const & xBackend,rtl::OUString const & aEntity, const sal_Bool& bNotify)
+: m_bSendNotification(bNotify)
+, m_xBackend(xBackend)
+, m_aComponentName()
+, m_aEntity(aEntity)
+{
+ OSL_ENSURE( m_xBackend.is(), "Creating an import handler without a target backend" );
+}
+// -----------------------------------------------------------------------------
+
+BasicImportHandler::~BasicImportHandler()
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ BasicImportHandler::startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ m_aComponentName = rtl::OUString();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ BasicImportHandler::endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if ( m_bSendNotification)
+ {
+ backenduno::ComponentChangeEvent aEvent;
+ aEvent.Source=*this;
+ aEvent.Component = m_aComponentName;
+
+ uno::Reference<backenduno::XBackendChangesListener> xListener(m_xBackend, uno::UNO_QUERY);
+ if( xListener.is())
+ {
+ xListener->componentDataChanged(aEvent);
+ }
+ else
+ {
+ OSL_ENSURE(false, "ImportMergeHandler: target backend does not support notifications");
+ }
+ }
+ m_aComponentName = rtl::OUString();
+}
+// -----------------------------------------------------------------------------
+
+bool BasicImportHandler::startComponent( const rtl::OUString& aName )
+{
+ if (hasComponent()) return false;
+
+ m_aComponentName = aName;
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+void BasicImportHandler::raiseMalformedDataException(sal_Char const * pMsg)
+{
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+
+ throw backenduno::MalformedDataException(sMsg, *this, uno::Any());
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/basicimporthandler.hxx b/configmgr/source/backend/basicimporthandler.hxx
new file mode 100644
index 000000000000..246d1d6f933d
--- /dev/null
+++ b/configmgr/source/backend/basicimporthandler.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: basicimporthandler.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_BASICIMPORTHANDLER_HXX
+#define CONFIGMGR_BACKEND_BASICIMPORTHANDLER_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+ class BasicImportHandler : public cppu::WeakImplHelper1< backenduno::XLayerHandler >
+ {
+ public:
+ explicit
+ BasicImportHandler(){}
+
+ BasicImportHandler(uno::Reference< backenduno::XBackend > const & xBackend,rtl::OUString const & aEntity = rtl::OUString(), const sal_Bool& bNofity= sal_False);
+ ~BasicImportHandler();
+
+ // XLayerHandler subset - call these implementations from your derived class implementations
+ protected:
+ virtual void SAL_CALL
+ startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ protected:
+ bool hasComponent() const { return m_aComponentName.getLength() != 0; }
+ bool hasEntity() const { return m_aEntity.getLength() != 0; }
+
+ rtl::OUString getComponent() const { return m_aComponentName; }
+ rtl::OUString getEntity() const { return m_aEntity; }
+ uno::Reference< backenduno::XBackend > getBackend() const { return m_xBackend; }
+
+ bool startComponent( const rtl::OUString& aName );
+
+ void raiseMalformedDataException(sal_Char const * pMsg);
+ /** If True, notification should be send to backend
+ */
+ sal_Bool m_bSendNotification;
+ private:
+ uno::Reference< backenduno::XBackend > const m_xBackend;
+ rtl::OUString m_aComponentName;
+ rtl::OUString const m_aEntity;
+
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/basicupdatemerger.cxx b/configmgr/source/backend/basicupdatemerger.cxx
new file mode 100644
index 000000000000..dd7363142ba9
--- /dev/null
+++ b/configmgr/source/backend/basicupdatemerger.cxx
@@ -0,0 +1,341 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: basicupdatemerger.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "basicupdatemerger.hxx"
+#include "layerdefaultremover.hxx"
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+#ifndef INCLUDED_ITERATOR
+#include <iterator>
+#define INCLUDED_ITERATOR
+#endif
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+BasicUpdateMerger::BasicUpdateMerger( uno::Reference< backenduno::XLayer > const & _xSourceLayer )
+: m_xSourceLayer(_xSourceLayer)
+, m_xResultHandler()
+, m_nNesting(0)
+, m_bSkipping(false)
+{
+}
+// -----------------------------------------------------------------------------
+
+BasicUpdateMerger::~BasicUpdateMerger()
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::readData( uno::Reference< backenduno::XLayerHandler > const & _xResultHandler )
+ throw ( backenduno::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!_xResultHandler.is())
+ {
+ rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("UpdateMerger: Error - NULL output handler unexpected") );
+ throw lang::NullPointerException(sMsg,*this);
+ }
+ if (!m_xSourceLayer.is())
+ {
+ rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("UpdateMerger: Error - No source layer set") );
+ throw lang::NullPointerException(sMsg,*this);
+ }
+
+ try
+ {
+ m_xResultHandler = new LayerDefaultRemover(_xResultHandler);
+ m_xSourceLayer->readData( this );
+ }
+ catch (uno::Exception & )
+ {
+ m_xResultHandler.clear();
+ throw;
+ }
+
+ m_xResultHandler.clear();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (m_nNesting)
+ raiseMalformedDataException("UpdateMerger: Cannot start layer - layer already in progress");
+
+ m_bSkipping = false;
+
+ m_xResultHandler->startLayer();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (m_nNesting > 0)
+ raiseMalformedDataException("UpdateMerger: Cannot end layer - data handling still in progress");
+
+ this->flushContext();
+
+ m_xResultHandler->endLayer();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->overrideNode(aName, aAttributes, bClear);
+
+ pushLevel(aName);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->addOrReplaceNode(aName, aAttributes);
+
+ pushLevel(aName);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->addOrReplaceNodeFromTemplate(aName, aTemplate, aAttributes);
+
+ pushLevel(aName);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->endNode();
+
+ popLevel();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->dropNode(aName);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->overrideProperty(aName, aAttributes, aType, bClear);
+
+ pushLevel( rtl::OUString() ); // do not match context path to property names
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->endProperty();
+
+ popLevel();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->setPropertyValue(aValue);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->setPropertyValueForLocale(aValue,aLocale);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->addProperty(aName, aAttributes, aType);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicUpdateMerger::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isSkipping())
+ m_xResultHandler->addPropertyWithValue(aName, aAttributes, aValue);
+}
+// -----------------------------------------------------------------------------
+
+void BasicUpdateMerger::raiseMalformedDataException(sal_Char const * pMsg)
+{
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+
+ throw backenduno::MalformedDataException(sMsg, *this, uno::Any());
+}
+// -----------------------------------------------------------------------------
+
+void BasicUpdateMerger::startSkipping()
+{
+ OSL_PRECOND( m_nNesting == 0, "BasicUpdateMerger: starting to skip, while already forwarding data");
+ m_nNesting = 1;
+ m_bSkipping = true;
+ OSL_POSTCOND( isHandling(), "BasicUpdateMerger: isHandling() is broken");
+ OSL_POSTCOND( isSkipping(), "BasicUpdateMerger: isSkipping() is broken");
+}
+// -----------------------------------------------------------------------------
+
+
+void BasicUpdateMerger::pushLevel(rtl::OUString const & _aContext)
+{
+ if (m_nNesting > 0)
+ {
+ ++m_nNesting;
+ OSL_POSTCOND( isHandling(), "BasicUpdateMerger: level counting is broken" );
+ }
+ else if (m_nNesting < 0)
+ {
+ OSL_POSTCOND( isHandling(), "BasicUpdateMerger: level counting is broken" );
+ }
+ else if (m_aSearchPath.empty())
+ {
+ ++m_nNesting;
+ OSL_POSTCOND( isHandling(), "BasicUpdateMerger: level counting is broken" );
+ }
+ else if ( m_aSearchPath.back().equals(_aContext) ) // search path is reverse - see findContext()
+ {
+ OSL_ENSURE( m_nNesting == 0, "BasicUpdateMerger: level count while searching must be zero");
+
+ m_aSearchPath.pop_back();
+ }
+ else // start forwarding
+ {
+ m_nNesting = 1;
+ OSL_POSTCOND( isHandling(), "BasicUpdateMerger: level counting is broken" );
+ OSL_POSTCOND(!isSkipping(), "BasicUpdateMerger: skip flag set while searching " );
+ }
+}
+// -----------------------------------------------------------------------------
+
+void BasicUpdateMerger::popLevel()
+{
+ OSL_PRECOND( isHandling(), "BasicUpdateMerger: ending a node that wasn't handled here");
+ if (m_nNesting > 0)
+ {
+ if (--m_nNesting == 0)
+ m_bSkipping = false;
+ }
+ else if (m_nNesting == 0) // ending a context level, but the context is not yet gone
+ {
+ OSL_ENSURE( !m_aSearchPath.empty(), "BasicUpdateMerger: flushing a context that was already found");
+ flushContext();
+ leaveContext();
+ }
+ else
+ {
+ OSL_ENSURE( m_aSearchPath.empty(), "BasicUpdateMerger: Left an unfinished context" );
+ }
+}
+// -----------------------------------------------------------------------------
+
+void BasicUpdateMerger::findContext(std::vector<rtl::OUString> const & _aContext)
+{
+ // make the context a *reverse* copy of the context path
+ OSL_PRECOND( ! isHandling(), "BasicUpdateMerger: starting context search while still handling data");
+ m_aSearchPath.clear();
+ m_aSearchPath.reserve(_aContext.size());
+ std::copy( _aContext.rbegin(), _aContext.rend(), std::back_inserter(m_aSearchPath) );
+}
+// -----------------------------------------------------------------------------
+
+void BasicUpdateMerger::leaveContext()
+{
+ OSL_PRECOND( !isHandling(), "BasicUpdateMerger: ending the context while still handling data or seaching the context");
+
+ // force
+ m_nNesting = -1;
+
+ OSL_POSTCOND( ! isSkipping(), "BasicUpdateMerger: ending the context node while still skipping data");
+ OSL_POSTCOND( isHandling(), "BasicUpdateMerger: cannot mark context as being handled to the end.");
+}
+// -----------------------------------------------------------------------------
+
+void BasicUpdateMerger::flushContext()
+{
+ std::vector<rtl::OUString>::size_type nNesting = m_aSearchPath.size();
+
+ while (!m_aSearchPath.empty())
+ {
+ m_xResultHandler->overrideNode(m_aSearchPath.back(), 0, false);
+ m_aSearchPath.pop_back();
+ }
+ this->flushUpdate();
+
+ while (nNesting > 0)
+ {
+ m_xResultHandler->endNode();
+ --nNesting;
+ }
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/basicupdatemerger.hxx b/configmgr/source/backend/basicupdatemerger.hxx
new file mode 100644
index 000000000000..147db1e56ee4
--- /dev/null
+++ b/configmgr/source/backend/basicupdatemerger.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: basicupdatemerger.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_BASICUPDATEMERGER_HXX
+#define CONFIGMGR_BACKEND_BASICUPDATEMERGER_HXX
+
+#include <cppuhelper/implbase2.hxx>
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+ class BasicUpdateMerger : public cppu::WeakImplHelper2< backenduno::XLayerHandler, backenduno::XLayer >
+ {
+ public:
+ explicit
+ BasicUpdateMerger(uno::Reference< backenduno::XLayer > const & _xSourceLayer);
+ ~BasicUpdateMerger();
+
+ // XLayerHandler
+ protected:
+ virtual void SAL_CALL
+ startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // XLayer
+ protected:
+ virtual void SAL_CALL
+ readData( const uno::Reference< backenduno::XLayerHandler >& aHandler )
+ throw (backenduno::MalformedDataException, lang::NullPointerException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // new overrideable
+ private:
+ /// write the whole update to the output
+ virtual void flushUpdate() = 0;
+
+ protected:
+ bool isHandling() const { return m_nNesting != 0 || !m_aSearchPath.empty(); }
+ bool isSkipping() const { return m_bSkipping; }
+ void startSkipping();
+
+ void findContext(std::vector<rtl::OUString> const & _aContext);
+ void leaveContext();
+
+ uno::Reference< backenduno::XLayerHandler > getResultWriter() const { return m_xResultHandler; };
+
+ void raiseMalformedDataException(sal_Char const * pMsg);
+ private:
+ void pushLevel(rtl::OUString const & _aLevel);
+ void popLevel();
+
+ void flushContext();
+ private:
+ uno::Reference< backenduno::XLayer > m_xSourceLayer;
+ uno::Reference< backenduno::XLayerHandler > m_xResultHandler;
+ std::vector<rtl::OUString> m_aSearchPath;
+
+ sal_Int16 m_nNesting;
+ bool m_bSkipping;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/binarycache.cxx b/configmgr/source/backend/binarycache.cxx
new file mode 100644
index 000000000000..fe1b0f63f311
--- /dev/null
+++ b/configmgr/source/backend/binarycache.cxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binarycache.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "binarycache.hxx"
+
+#include "binaryreadhandler.hxx"
+#include "binarywritehandler.hxx"
+
+#include "mergedcomponentdata.hxx"
+#include "filehelper.hxx"
+#include "typeconverter.hxx"
+
+#ifndef _CONFIGMGR_BOOTSTRAP_HXX
+#include "bootstrap.hxx"
+#endif
+#include <osl/file.hxx>
+#include "tools/getprocessworkingdir.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+
+#define RTL_LOGFILE_OU2A(rtlOUString) (::rtl::OUStringToOString((rtlOUString), RTL_TEXTENCODING_ASCII_US).getStr())
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ const rtl::OUString aSettingName(
+ RTL_CONSTASCII_USTRINGPARAM( CONTEXT_ITEM_PREFIX_ "CacheUrl"));
+ // ---------------------------------------------------------------------------------------
+ static inline bool isValidFileURL (rtl::OUString const& _sFileURL)
+ {
+ rtl::OUString sSystemPath;
+ return _sFileURL.getLength() && (osl::File::E_None == osl::File::getSystemPathFromFileURL(_sFileURL, sSystemPath));
+ }
+ // -----------------------------------------------------------------------------
+ // ---------------------------------------------------------------------------------------
+ static
+ bool implEnsureAbsoluteURL(rtl::OUString & _rsURL) // also strips embedded dots etc.
+ {
+ if (!_rsURL.getLength())
+ return false;
+
+ if (!isValidFileURL(_rsURL))
+ {
+ OSL_TRACE("Binary cache: File URL %s is invalid.",
+ rtl::OUStringToOString(_rsURL,RTL_TEXTENCODING_ASCII_US).getStr());
+ return false;
+ }
+
+ rtl::OUString sBasePath;
+ OSL_VERIFY(tools::getProcessWorkingDir(&sBasePath));
+
+ rtl::OUString sAbsolute;
+ if ( osl::File::E_None == osl::File::getAbsoluteFileURL(sBasePath, _rsURL, sAbsolute))
+ {
+ _rsURL = sAbsolute;
+ return isValidFileURL(_rsURL);
+ }
+ else
+ {
+ OSL_ENSURE(!isValidFileURL(_rsURL), "Could not get absolute file URL for valid URL");
+ return false;
+ }
+ }
+ // ---------------------------------------------------------------------------------------
+ static const sal_Unicode kComponentSeparator = '.' ;
+ static const sal_Unicode kPathSeparator = '/' ;
+ static const char kBinarySuffix[] = ".dat" ;
+
+ rtl::OUString BinaryCache::getCacheFileURL(const rtl::OUString& aComponent) const
+ {
+ rtl::OUStringBuffer retCode (mBaseURL);
+ retCode.append(kPathSeparator) ;
+ // retCode.append(aComponent.replace(kComponentSeparator, kPathSeparator)) ;
+ retCode.append(aComponent) ;
+ retCode.appendAscii(RTL_CONSTASCII_STRINGPARAM(kBinarySuffix));
+
+ rtl::OUString aResult = retCode.makeStringAndClear() ;
+
+ if (isValidFileURL(aResult))
+ {
+ return aResult;
+ }
+ else
+ {
+ OSL_ENSURE(false, "Component File URL is invalid");
+ return rtl::OUString();
+ }
+ }
+ // -----------------------------------------------------------------------------
+ BinaryCache::BinaryCache(const uno::Reference<uno::XComponentContext>& xContext )
+ : mBaseURL()
+ , mOwnerEntity()
+ , mbCacheEnabled(false)
+ {
+
+ //initialise the base URL
+ ContextReader aReader(xContext);
+
+ rtl::OUString sCacheUrl;
+ if (!aReader.isAdminService())
+ {
+ mbCacheEnabled = (aReader.getBestContext()->getValueByName(aSettingName) >>= sCacheUrl)
+ && implEnsureAbsoluteURL(sCacheUrl);
+ }
+
+ if (mbCacheEnabled)
+ {
+ mBaseURL = sCacheUrl;
+ if (!FileHelper::dirExists(sCacheUrl))
+ {
+ osl::File::RC errorCode = FileHelper::mkdirs(sCacheUrl);
+ if (errorCode)
+ {
+#if (OSL_DEBUG_LEVEL > 0)
+ rtl::OString sURL = rtl::OUStringToOString(sCacheUrl,RTL_TEXTENCODING_ASCII_US);
+ rtl::OString sErr = rtl::OUStringToOString(FileHelper::createOSLErrorString(errorCode),RTL_TEXTENCODING_ASCII_US);
+ ::osl_trace("Configuration: Cannot create cache directory \"%s\". "
+ "Error is %s [%d]",sURL.getStr(),sErr.getStr(),int(errorCode)) ;
+#endif
+ mbCacheEnabled = false;
+ }
+ }
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryCache::setOwnerEntity(const rtl::OUString & aOwnerEntity)
+ {
+ OSL_PRECOND(mOwnerEntity.getLength() == 0, "Owner entity of cache already set");
+ mOwnerEntity = aOwnerEntity;
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryCache::disableCache()
+ {
+ mbCacheEnabled = false;
+ }
+ // -----------------------------------------------------------------------------
+
+ bool BinaryCache::isCacheEnabled(rtl::OUString const & aEntity) const
+ {
+ if (!mbCacheEnabled) return false;
+
+ // default entity is empty
+ if (aEntity.getLength() == 0) return true;
+
+ return aEntity.equals(mOwnerEntity);
+ }
+ // -----------------------------------------------------------------------------
+ bool BinaryCache::readComponentData(MergedComponentData & aComponentData,
+ uno::Reference< lang::XMultiServiceFactory > const & aFactory,
+ rtl::OUString const & aComponent,
+ rtl::OUString const & aSchemaVersion,
+ rtl::OUString const & aEntity,
+ com::sun::star::lang::Locale const & aRequestedLocale,
+ std::vector< com::sun::star::lang::Locale > & outKnownLocales,
+ const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ bool bIncludeTemplates)
+ {
+ if (isCacheEnabled(aEntity))
+ try
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::BinaryCache", "jb99855", "configmgr: BinaryCache::readComponentData() - enabled");
+ BinaryReadHandler aCacheReader(getCacheFileURL(aComponent),aComponent,aFactory);
+
+ // #i49148# Invalidate cache when schema version changes - using former 'owner' parameter for version
+ if(aCacheReader.validateHeader(pLayers, nNumLayers, aSchemaVersion, aRequestedLocale, outKnownLocales))
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog1, "configmgr::backend::BinaryCache", "jb99855", "configmgr: BinaryCache::readComponentData() - cache hit");
+ aComponentData.setSchemaRoot( aCacheReader.readComponentTree() );
+ if (bIncludeTemplates)
+ aComponentData.setTemplatesTree( aCacheReader.readTemplatesTree() );
+ return true;
+ }
+ }
+ catch (uno::Exception & e)
+ {
+ OSL_TRACE("Binary Cache read failed - exception: %s", rtl::OUStringToOString(e.Message,RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ return false;
+ }
+ // -----------------------------------------------------------------------------
+
+ bool BinaryCache::writeComponentData(MergedComponentData const & aComponentData,
+ uno::Reference< lang::XMultiServiceFactory > const & aFactory,
+ rtl::OUString const & aComponent,
+ rtl::OUString const & aSchemaVersion,
+ rtl::OUString const & aEntity,
+ std::vector< com::sun::star::lang::Locale > const & aKnownLocales,
+ const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers)
+ {
+ if (isCacheEnabled(aEntity))
+ try
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog3, "configmgr::backend::BinaryCache", "jb99855", "configmgr: BinaryCache::writeComponentData() - enabled");
+ BinaryWriteHandler aCacheWriter(getCacheFileURL(aComponent),aComponent, aFactory);
+
+ //write data to cache
+ // #i49148# Invalidate cache when schema version changes - using former 'owner' parameter for schema
+ if (aCacheWriter.generateHeader(pLayers, nNumLayers, aSchemaVersion, aKnownLocales))
+ {
+ aCacheWriter.writeComponentTree(aComponentData.getSchemaTree());
+ aCacheWriter.writeTemplatesTree(aComponentData.getTemplatesTree());
+ return true;
+ }
+ }
+ catch (uno::Exception & e)
+ {
+ OSL_TRACE("Configuration: Cache write failed - exception: %s", rtl::OUStringToOString(e.Message,RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ return false;
+ }
+ // -----------------------------------------------------------------------------
+
+ }
+// -----------------------------------------------------------------------------
+}
diff --git a/configmgr/source/backend/binarycache.hxx b/configmgr/source/backend/binarycache.hxx
new file mode 100644
index 000000000000..18e3e9f983e3
--- /dev/null
+++ b/configmgr/source/backend/binarycache.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binarycache.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_BINARYCACHE_HXX
+#define CONFIGMGR_BINARYCACHE_HXX
+
+#include "matchlocale.hxx"
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace css = com::sun::star ;
+ namespace uno = css::uno ;
+ namespace lang = css::lang ;
+ namespace backenduno = css::configuration::backend ;
+
+ // -----------------------------------------------------------------------------
+ class MergedComponentData;
+
+ // -----------------------------------------------------------------------------
+
+ class BinaryCache
+ {
+ public:
+ explicit
+ BinaryCache(const uno::Reference<uno::XComponentContext>& xContext);
+
+ void setOwnerEntity(rtl::OUString const & aOwnerEntity);
+ void disableCache();
+
+ bool isCacheEnabled(rtl::OUString const & aEntity) const;
+
+ rtl::OUString getCacheFileURL(rtl::OUString const & aComponent) const;
+
+ bool readComponentData(MergedComponentData & aComponentData,
+ uno::Reference< lang::XMultiServiceFactory > const & aFactory,
+ rtl::OUString const & aComponent,
+ rtl::OUString const & aSchemaVersion,
+ rtl::OUString const & aEntity,
+ com::sun::star::lang::Locale const & aRequestedLocale,
+ std::vector< com::sun::star::lang::Locale > & outKnownLocales,
+ const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ bool bIncludeTemplates = true);
+
+ bool writeComponentData(MergedComponentData const & aComponentData,
+ uno::Reference< lang::XMultiServiceFactory > const & aFactory,
+ rtl::OUString const & aComponent,
+ rtl::OUString const & aSchemaVersion,
+ rtl::OUString const & aEntity,
+ std::vector< com::sun::star::lang::Locale > const & aKnownLocales,
+ const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers);
+ private:
+ rtl::OUString mBaseURL;
+ rtl::OUString mOwnerEntity;
+ bool mbCacheEnabled;
+ };
+
+ // -----------------------------------------------------------------------------------
+ // helper for cache reader implementations - see backendaccess.cxx for implementation
+ uno::Sequence< rtl::OUString >
+ getAvailableLocales(const uno::Reference<backenduno::XLayer> * pLayers, sal_Int32 nNumLayers);
+ // -----------------------------------------------------------------------------------
+ }
+// -----------------------------------------------------------------------------------
+}
+
+#endif //
+
diff --git a/configmgr/source/backend/binaryreader.cxx b/configmgr/source/backend/binaryreader.cxx
new file mode 100644
index 000000000000..8f8af945026a
--- /dev/null
+++ b/configmgr/source/backend/binaryreader.cxx
@@ -0,0 +1,693 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binaryreader.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "binaryreader.hxx"
+#include "binarytype.hxx"
+#include "valuenode.hxx"
+#include "filehelper.hxx"
+#include "oslstream.hxx"
+
+
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XDataInputStream.hpp>
+#include <com/sun/star/io/XDataOutputStream.hpp>
+#include <com/sun/star/io/BufferSizeExceededException.hpp>
+#include <com/sun/star/io/UnexpectedEOFException.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+#include <osl/file.hxx>
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+#include "tracer.hxx"
+
+#define ASCII(x) rtl::OUString::createFromAscii(x)
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace uno = com::sun::star::uno;
+ namespace io = com::sun::star::io;
+
+
+ // --------------------------------------------------------------------------
+
+ inline rtl::OUString ErrorToMessage_Impl (osl::FileBase::RC eError)
+ {
+ return FileHelper::createOSLErrorString (eError);
+ }
+
+ // --------------------------------------------------------------------------
+
+ class BinaryReader_Impl :
+ public cppu::WeakImplHelper1< com::sun::star::io::XDataInputStream >
+ {
+ public:
+ /** Construction.
+ */
+ explicit BinaryReader_Impl (rtl::OUString const & rFileUrl)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ /** XInputStream.
+ */
+ virtual sal_Int32 SAL_CALL readBytes (
+ uno::Sequence<sal_Int8> & rData, sal_Int32 nBytesToRead)
+ throw (
+ io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL readSomeBytes (
+ uno::Sequence<sal_Int8> & rData, sal_Int32 nBytesToRead)
+ throw (
+ io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException);
+
+ virtual void SAL_CALL skipBytes (sal_Int32 nBytesToSkip)
+ throw (
+ io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL available()
+ throw (
+ io::NotConnectedException,
+ io::IOException, uno::RuntimeException);
+
+ virtual void SAL_CALL closeInput()
+ throw (
+ io::NotConnectedException,
+ io::IOException, uno::RuntimeException);
+
+
+ /** XDataInputStream.
+ */
+ virtual sal_Int8 SAL_CALL readBoolean()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ virtual sal_Int8 SAL_CALL readByte()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ virtual sal_Unicode SAL_CALL readChar()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ virtual sal_Int16 SAL_CALL readShort()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL readLong()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ virtual sal_Int64 SAL_CALL readHyper()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ virtual float SAL_CALL readFloat()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ virtual double SAL_CALL readDouble()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL readUTF()
+ throw (
+ io::IOException, uno::RuntimeException);
+
+ protected:
+ /** Destruction.
+ */
+ virtual ~BinaryReader_Impl();
+
+ private:
+ sal_uInt32 checkAvail(); // may throw NotConnectedException
+ sal_uInt32 getMaxAvail(sal_Int32 nRequest); // may throw NotConnectedException, BufferSizeExceededException
+ sal_uInt8 const * readBuffer(sal_uInt32 nRequired); // may throw NotConnectedException, UnexpectedEOFException
+ private:
+ /** Representation.
+ */
+ sal_uInt8 * m_pBuffer;
+ sal_uInt32 m_nLength;
+ sal_uInt32 m_nOffset;
+
+ /** Not implemented.
+ */
+ BinaryReader_Impl (const BinaryReader_Impl&);
+ BinaryReader_Impl& operator= (const BinaryReader_Impl&);
+ };
+
+ // --------------------------------------------------------------------------
+ static inline void checkIOError(osl::File::RC errcode)
+ {
+ if (errcode != osl::FileBase::E_None)
+ {
+ throw io::IOException (ErrorToMessage_Impl (errcode), NULL);
+ }
+ }
+ static void raiseBufferError()
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("Cannot allocate Buffer: Too large");
+ throw io:: BufferSizeExceededException(sMsg, NULL);
+ }
+ // -------------------------------------------------------------------------
+ BinaryReader_Impl::BinaryReader_Impl (rtl::OUString const & rFileUrl)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ : m_pBuffer (0)
+ , m_nLength (0)
+ , m_nOffset (0)
+ {
+ osl::File aFile (rFileUrl);
+
+ checkIOError( aFile.open (OpenFlag_Read) );
+ sal_uInt64 nLength = 0;
+ checkIOError( aFile.getSize (nLength) );
+ if (nLength > 0xffffffff)
+ raiseBufferError();
+ m_nLength = sal_uInt32(nLength);
+
+ sal_uInt8 *pBuffer = static_cast<sal_uInt8*>(rtl_allocateMemory (m_nLength));
+ if (!pBuffer)
+ raiseBufferError();
+
+ sal_uInt64 nRead = 0;
+ osl::File::RC result = aFile.read (pBuffer, nLength, nRead);
+ if (result != osl::FileBase::E_None)
+ {
+ rtl_freeMemory (pBuffer);
+ checkIOError( result );
+ }
+ if (nRead != nLength)
+ {
+ rtl_freeMemory (pBuffer);
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("BinaryCache - Could not read entire size of file: ");
+ throw io::UnexpectedEOFException(sMsg.concat(rFileUrl),NULL);
+ }
+ m_pBuffer = pBuffer;
+ }
+
+ // --------------------------------------------------------------------------
+
+ BinaryReader_Impl::~BinaryReader_Impl()
+ {
+ if (m_pBuffer) rtl_freeMemory (m_pBuffer);
+ }
+
+ // --------------------------------------------------------------------------
+ // XInputStream implementation.
+ // --------------------------------------------------------------------------
+ sal_uInt32 BinaryReader_Impl::checkAvail ()
+ {
+ if (!m_pBuffer)
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("BinaryCache - Stream is not open. No data available for reading.");
+ throw io::NotConnectedException(sMsg,*this);
+ }
+ OSL_ASSERT(m_nLength >= m_nOffset);
+ return m_nLength - m_nOffset;
+ }
+ // --------------------------------------------------------------------------
+
+ sal_uInt32 BinaryReader_Impl::getMaxAvail (sal_Int32 nRequest)
+ {
+ if (nRequest < 0)
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("BinaryCache - Invalid read request - negative byte count requested.");
+ throw io::BufferSizeExceededException(sMsg,*this);
+ }
+ sal_uInt32 const uRequest = sal_uInt32(nRequest);
+ sal_uInt32 const uAvail = checkAvail ();
+ return std::min(uRequest,uAvail);
+ }
+ // --------------------------------------------------------------------------
+
+ sal_uInt8 const * BinaryReader_Impl::readBuffer (sal_uInt32 nRequest)
+ {
+ sal_uInt32 const nAvail = checkAvail ();
+ if (nRequest > nAvail)
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("BinaryCache - Invalid file format - read past end-of-file.");
+ throw io::UnexpectedEOFException(sMsg,*this);
+ }
+ sal_uInt8 const * pData = m_pBuffer + m_nOffset;
+ m_nOffset += nRequest;
+ return pData;
+ }
+ // --------------------------------------------------------------------------
+
+ sal_Int32 SAL_CALL BinaryReader_Impl::readBytes (
+ uno::Sequence<sal_Int8> & rData, sal_Int32 nBytesToRead)
+ throw (
+ io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException)
+ {
+ sal_uInt32 nRead = getMaxAvail(nBytesToRead);
+ if (nRead > 0)
+ {
+ rData.realloc (nRead);
+ memcpy (rData.getArray(), readBuffer(nRead), nRead);
+ }
+ return sal_Int32(nRead);
+ }
+
+ // --------------------------------------------------------------------------
+
+ sal_Int32 SAL_CALL BinaryReader_Impl::readSomeBytes (
+ uno::Sequence<sal_Int8> & rData, sal_Int32 nBytesToRead)
+ throw (
+ io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException)
+ {
+ return readBytes(rData,nBytesToRead);
+ }
+
+ // --------------------------------------------------------------------------
+
+ void SAL_CALL BinaryReader_Impl::skipBytes (sal_Int32 nBytesToSkip)
+ throw (
+ io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException)
+ {
+ (void) readBuffer(sal_uInt32(nBytesToSkip));
+ }
+
+ // --------------------------------------------------------------------------
+
+ sal_Int32 SAL_CALL BinaryReader_Impl::available()
+ throw (
+ io::NotConnectedException,
+ io::IOException, uno::RuntimeException)
+ {
+ const sal_uInt32 nMaxAvail = 0x7FFFFFFF;
+ const sal_uInt32 nAvail = checkAvail();
+ return sal_Int32(std::min(nAvail,nMaxAvail));
+ }
+
+ // --------------------------------------------------------------------------
+
+ void SAL_CALL BinaryReader_Impl::closeInput()
+ throw (
+ io::NotConnectedException,
+ io::IOException, uno::RuntimeException)
+ {
+ OSL_ENSURE(m_pBuffer,"BinaryCache - Closing stream that is already closed");
+ if (m_pBuffer)
+ {
+ rtl_freeMemory (m_pBuffer);
+ m_pBuffer = 0;
+ }
+ }
+
+ // --------------------------------------------------------------------------
+ // XDataInputStream implementation.
+ // --------------------------------------------------------------------------
+
+ sal_Int8 SAL_CALL BinaryReader_Impl::readBoolean()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ return this->readByte();
+ }
+
+ // --------------------------------------------------------------------------
+
+ sal_Int8 SAL_CALL BinaryReader_Impl::readByte()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ sal_Int8 result = sal_Int8(*readBuffer(1));
+
+ return result;
+ }
+
+ // --------------------------------------------------------------------------
+
+ sal_Unicode SAL_CALL BinaryReader_Impl::readChar()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ sal_Unicode result;
+
+ sal_uInt8 const * pData = readBuffer(sizeof result);
+
+ result = sal_Unicode(
+ (sal_uInt16(pData[0]) << 8) |
+ (sal_uInt16(pData[1]) << 0) );
+
+ return result;
+ }
+
+ // --------------------------------------------------------------------------
+
+ sal_Int16 SAL_CALL BinaryReader_Impl::readShort()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ sal_Int16 result;
+
+ sal_uInt8 const * pData = readBuffer(sizeof result);
+
+ result = sal_Int16(
+ (sal_uInt16(pData[0]) << 8) |
+ (sal_uInt16(pData[1]) << 0) );
+
+ return result;
+ }
+
+ // --------------------------------------------------------------------------
+
+ sal_Int32 SAL_CALL BinaryReader_Impl::readLong()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ sal_Int32 result;
+
+ sal_uInt8 const * pData = readBuffer(sizeof result);
+
+ result = sal_Int32(
+ (sal_uInt32(pData[0]) << 24) |
+ (sal_uInt32(pData[1]) << 16) |
+ (sal_uInt32(pData[2]) << 8) |
+ (sal_uInt32(pData[3]) << 0) );
+
+ return result;
+ }
+
+ // --------------------------------------------------------------------------
+
+ sal_Int64 SAL_CALL BinaryReader_Impl::readHyper()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ sal_Int64 result;
+
+ sal_uInt8 const * pData = readBuffer(sizeof result);
+
+ result = sal_Int64(
+ (sal_uInt64(pData[0]) << 56) |
+ (sal_uInt64(pData[1]) << 48) |
+ (sal_uInt64(pData[2]) << 40) |
+ (sal_uInt64(pData[3]) << 32) |
+ (sal_uInt64(pData[4]) << 24) |
+ (sal_uInt64(pData[5]) << 16) |
+ (sal_uInt64(pData[6]) << 8) |
+ (sal_uInt64(pData[7]) << 0) );
+
+ return result;
+ }
+
+ // --------------------------------------------------------------------------
+
+ float SAL_CALL BinaryReader_Impl::readFloat()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ union { float f; sal_uInt32 n; } result;
+
+ sal_uInt8 const * pData = readBuffer(sizeof result.n);
+
+ result.n = sal_uInt32(
+ (sal_uInt32(pData[0]) << 24) |
+ (sal_uInt32(pData[1]) << 16) |
+ (sal_uInt32(pData[2]) << 8) |
+ (sal_uInt32(pData[3]) << 0) );
+
+ return result.f;
+ }
+
+ // --------------------------------------------------------------------------
+
+ double SAL_CALL BinaryReader_Impl::readDouble()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ union { double d; sal_uInt64 n; } result;
+
+ sal_uInt8 const * pData = readBuffer(sizeof result.n);
+
+ result.n = sal_uInt64(
+ (sal_uInt64(pData[0]) << 56) |
+ (sal_uInt64(pData[1]) << 48) |
+ (sal_uInt64(pData[2]) << 40) |
+ (sal_uInt64(pData[3]) << 32) |
+ (sal_uInt64(pData[4]) << 24) |
+ (sal_uInt64(pData[5]) << 16) |
+ (sal_uInt64(pData[6]) << 8) |
+ (sal_uInt64(pData[7]) << 0) );
+
+ return result.d;
+ }
+
+ // --------------------------------------------------------------------------
+
+ rtl::OUString SAL_CALL BinaryReader_Impl::readUTF()
+ throw (io::IOException, uno::RuntimeException)
+ {
+ sal_uInt32 nLength;
+
+ sal_uInt8 const * const pData = readBuffer(sizeof nLength);
+
+ nLength = sal_uInt32(
+ (sal_uInt32(pData[0]) << 24) |
+ (sal_uInt32(pData[1]) << 16) |
+ (sal_uInt32(pData[2]) << 8) |
+ (sal_uInt32(pData[3]) << 0) );
+
+ bool bIsAscii = (nLength & binary::STR_ASCII_MASK) == binary::STR_ASCII_MASK;
+ nLength &=~binary::STR_ASCII_MASK;
+
+ rtl::OUString result;
+ if (nLength != 0)
+ {
+ sal_Char const * const pUTF = reinterpret_cast<sal_Char const * >(readBuffer(nLength));
+
+ sal_Int32 const nStrLength = sal_Int32(nLength);
+ OSL_ASSERT(nStrLength >= 0);
+
+ rtl_TextEncoding const enc = bIsAscii ? RTL_TEXTENCODING_ASCII_US : RTL_TEXTENCODING_UTF8;
+
+ rtl_uString_internConvert(&result.pData, pUTF, nStrLength, enc,
+ OSTRING_TO_OUSTRING_CVTFLAGS, NULL);
+ }
+
+ return result;
+ }
+
+ // --------------------------------------------------------------------------
+ // BinaryReader implementation.
+ // --------------------------------------------------------------------------
+
+ BinaryReader::BinaryReader(rtl::OUString const & _sFileURL):
+ m_sFileURL(_sFileURL) {}
+
+ BinaryReader::~BinaryReader() {}
+
+ bool BinaryReader::open()
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ OSL_PRECOND(!m_xDataInputStream.is(),"Binary Reader: already open");
+ if (m_xDataInputStream.is())
+ return false;
+
+ if (m_sFileURL.getLength() == 0)
+ return false;
+
+ if (!FileHelper::fileExists(m_sFileURL))
+ return false;
+
+ m_xDataInputStream.set(new BinaryReader_Impl (m_sFileURL));
+ return true;
+ }
+
+ // --------------------------------------------------------------------------
+
+ inline BinaryReader_Impl * BinaryReader::getDataInputStream()
+ {
+ OSL_ENSURE(m_xDataInputStream.is(),"Binary Cache: Reader was not opened - no input stream");
+ return m_xDataInputStream.get();
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read(sal_Bool &_bValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ _bValue = getDataInputStream()->readBoolean();
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read(sal_Int8 &_nValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ _nValue = getDataInputStream()->readByte();
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read(sal_Int16 &_nValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ _nValue = getDataInputStream()->readShort();
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read(sal_Int32 &_nValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ _nValue = getDataInputStream()->readLong();
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read(sal_Int64 &_nValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ _nValue = getDataInputStream()->readHyper();
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read(double &_nValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ _nValue = getDataInputStream()->readDouble();
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read(rtl::OUString& _aStr)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ _aStr = getDataInputStream()->readUTF();
+ }
+
+ // -----------------------------------------------------------------------------
+ template <class Element>
+ void readSequence(BinaryReader& _rReader, uno::Sequence< Element > & aSequence)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // PRE: the Sequence must exist
+ sal_Int32 nLength;
+ _rReader.read(nLength);
+
+ aSequence.realloc(nLength);
+
+ Element* const pElement = aSequence.getArray(); // fill the hole array
+ for(sal_Int32 i=0; i<nLength; ++i)
+ {
+ _rReader.read(pElement[i]); // read one element
+ }
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read (uno::Sequence< sal_Int8 > &_aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ readSequence(*this, _aValue);
+ }
+
+ // --------------------------------------------------------------------------
+
+ void BinaryReader::read (uno::Sequence< rtl::OUString > &_aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ readSequence(*this, _aValue);
+ }
+
+ // --------------------------------------------------------------------------
+
+ uno::Sequence< sal_Int8 > const * const for_binary = 0;
+
+ #define CASE_READ_SEQUENCE(TYPE_CLASS, DATA_TYPE) \
+ case TYPE_CLASS: \
+ { \
+ OSL_ENSURE( ::getCppuType(static_cast<DATA_TYPE const*>(0)).getTypeClass() == (TYPE_CLASS), "Typeclass does not match element type" ); \
+ uno::Sequence< DATA_TYPE > aData; \
+ readSequence(_rReader, aData); \
+ _aValue <<= aData; \
+ } break
+
+ bool readSequenceValue (
+ BinaryReader & _rReader,
+ uno::Any & _aValue,
+ uno::Type const & _aElementType)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ switch(_aElementType.getTypeClass())
+ {
+ CASE_READ_SEQUENCE( uno::TypeClass_BOOLEAN, sal_Bool );
+
+ CASE_READ_SEQUENCE( uno::TypeClass_SHORT, sal_Int16 );
+
+ CASE_READ_SEQUENCE( uno::TypeClass_LONG, sal_Int32 );
+
+ CASE_READ_SEQUENCE( uno::TypeClass_HYPER, sal_Int64 );
+
+ CASE_READ_SEQUENCE( uno::TypeClass_DOUBLE, double );
+
+ CASE_READ_SEQUENCE( uno::TypeClass_STRING, rtl::OUString );
+
+ case uno::TypeClass_SEQUENCE:
+ if (_aElementType == ::getCppuType(for_binary))
+ {
+ uno::Sequence< sal_Int8 > aData;
+ readSequence(_rReader, aData);
+ _aValue <<= aData;
+ break;
+ }
+ // else fall through
+
+ default:
+ OSL_ENSURE(false, "Unexpected type for sequence elements");
+ return false;
+ }
+ return true;
+ }
+
+ #undef CASE_READ_SEQUENCE
+
+ // --------------------------------------------------------------------------
+
+
+ }
+}
diff --git a/configmgr/source/backend/binaryreader.hxx b/configmgr/source/backend/binaryreader.hxx
new file mode 100644
index 000000000000..3fdda0f5bd56
--- /dev/null
+++ b/configmgr/source/backend/binaryreader.hxx
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binaryreader.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_BINARYREADER_HXX
+#define CONFIGMGR_BINARYREADER_HXX
+
+#include <rtl/ref.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace css = com::sun::star;
+
+ namespace io = css::io;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+ // -----------------------------------------------------------------------------
+ class BinaryReader_Impl;
+ class BinaryReader
+ {
+ rtl::OUString m_sFileURL;
+
+ rtl::Reference<BinaryReader_Impl> m_xDataInputStream;
+ public:
+ explicit BinaryReader (rtl::OUString const & _sFileURL);
+
+ ~BinaryReader();
+
+ public:
+ bool open() SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void read(sal_Bool &_nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void read(sal_Int8 &_nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void read(sal_Int16 &_nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void read(sal_Int32 &_nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void read(sal_Int64 &_nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void read(double &_nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void read(rtl::OUString& _aStr) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void read(uno::Sequence< sal_Int8 > &_aValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void read(uno::Sequence< rtl::OUString > &_aValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ private:
+ inline BinaryReader_Impl * getDataInputStream();
+ };
+ // --------------------------------------------------------------------------
+
+ bool readSequenceValue (
+ BinaryReader & _rReader,
+ uno::Any & _aValue,
+ uno::Type const & _aElementType) SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ // --------------------------------------------------------------------------
+ }
+}
+#endif
diff --git a/configmgr/source/backend/binaryreadhandler.cxx b/configmgr/source/backend/binaryreadhandler.cxx
new file mode 100644
index 000000000000..f465027719e5
--- /dev/null
+++ b/configmgr/source/backend/binaryreadhandler.cxx
@@ -0,0 +1,690 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binaryreadhandler.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "binaryreadhandler.hxx"
+#include "binarycache.hxx"
+#include "binarytype.hxx"
+#include "simpletypehelper.hxx"
+#include "typeconverter.hxx"
+#include "treenodefactory.hxx"
+
+#include "tracer.hxx"
+#include <com/sun/star/io/WrongFormatException.hpp>
+#include <com/sun/star/util/XTimeStamped.hpp>
+
+
+#define ASCII(x) rtl::OUString::createFromAscii(x)
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+
+ namespace css = com::sun::star;
+ namespace io = css::io;
+ namespace util = css::util;
+
+ // -----------------------------------------------------------------------------
+ BinaryReadHandler::BinaryReadHandler(rtl::OUString const & _aFileURL,
+ rtl::OUString const & _aComponentName,
+ uno::Reference<lang::XMultiServiceFactory> const & )
+ : m_BinaryReader(_aFileURL)
+ , m_aNodeFactory()
+ , m_aComponentName(_aComponentName)
+ {
+ }
+ // -----------------------------------------------------------------------------
+ BinaryReadHandler::~BinaryReadHandler()
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ static inline
+ bool isRequestingNoLocale(com::sun::star::lang::Locale const & aRequestedLocale)
+ {
+ rtl::OUString const & aLanguage = aRequestedLocale.Language;
+ return aLanguage.getLength() == 0 || localehelper::isDefaultLanguage(aLanguage);
+ }
+ // -----------------------------------------------------------------------------
+
+ static
+ bool supportsLocale(uno::Sequence< rtl::OUString > const & aStoredLocales, rtl::OUString const & aRequestedLocale)
+ {
+ for (sal_Int32 ix=0; ix<aStoredLocales.getLength(); ++ix)
+ if (aStoredLocales[ix].equalsIgnoreAsciiCase(aRequestedLocale))
+ return true;
+
+ return false;
+ }
+ // -----------------------------------------------------------------------------
+
+ static
+ bool supportsAll(uno::Sequence< rtl::OUString > const & aStoredLocales, uno::Sequence< rtl::OUString > const & aRequestedLocales)
+ {
+ for (sal_Int32 jx=0; jx<aRequestedLocales.getLength(); ++jx)
+ if (!supportsLocale(aStoredLocales,aRequestedLocales[jx]))
+ return false;
+
+ return true;
+ }
+ // -----------------------------------------------------------------------------
+
+ bool BinaryReadHandler::verifyFileHeader( const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ const rtl::OUString& _aSchemaVersion,
+ com::sun::star::lang::Locale const & aRequestedLocale,
+ std::vector< com::sun::star::lang::Locale > & outKnownLocales)
+ {
+ try
+ {
+ //Open the reader
+ sal_Int16 nMagic, nVersion;
+ m_BinaryReader.read(nMagic);
+ m_BinaryReader.read(nVersion);
+ if (nMagic !=binary::CFG_BINARY_MAGIC || nVersion != binary::CFG_BINARY_VERSION )
+ return false;
+
+ rtl::OUString aSchemaVersion;
+ m_BinaryReader.read(aSchemaVersion);
+ if (!aSchemaVersion.equals(_aSchemaVersion))
+ return false;
+
+ uno::Sequence< rtl::OUString > aAvailableLocales;
+ uno::Sequence< rtl::OUString > aKnownLocales;
+ m_BinaryReader.read(aKnownLocales);
+ m_BinaryReader.read(aAvailableLocales);
+ outKnownLocales = localehelper::makeLocaleSequence(aKnownLocales);
+
+ if (isRequestingNoLocale(aRequestedLocale))
+ {
+ // any existing combination of locales (including none) is valid
+ }
+ else if (!localehelper::designatesAllLocales(aRequestedLocale))
+ {
+ // one particular locale requested
+ rtl::OUString const aIsoLocale = localehelper::makeIsoLocale(aRequestedLocale);
+ if (!supportsLocale(aKnownLocales,aIsoLocale))
+ {
+ // a locale we didn't load previously
+ return false;
+ }
+ else if (! supportsLocale(aAvailableLocales,aIsoLocale))
+ {
+ // a locale we handled by fallback previously
+ uno::Sequence< rtl::OUString > aNewlyAvailableLocales =
+ getAvailableLocales(pLayers,nNumLayers);
+
+ // ... and that has become available now
+ if (supportsLocale(aNewlyAvailableLocales,aIsoLocale))
+ return false;
+
+ // ... or other new locales have been added
+ if (!supportsAll(aAvailableLocales,aNewlyAvailableLocales))
+ return false;
+ }
+ }
+ else
+ {
+ uno::Sequence< rtl::OUString > aNewlyAvailableLocales =
+ getAvailableLocales(pLayers,nNumLayers);
+
+ // not all locales were requested yet
+ if (!supportsAll(aKnownLocales,aNewlyAvailableLocales))
+ return false;
+
+ // new locales have been added
+ if (!supportsAll(aAvailableLocales,aNewlyAvailableLocales))
+ return false;
+ }
+
+ rtl::OUString aComponentName;
+ m_BinaryReader.read(aComponentName);
+ if (!aComponentName.equals(m_aComponentName))
+ return false;
+
+ return true;
+ }
+ catch (uno::Exception &)
+ {
+ CFG_TRACE_INFO("Binary Cache can't be used");
+ return false;
+ }
+ }
+ // -----------------------------------------------------------------------------
+ bool BinaryReadHandler::isUptodate(const std::vector<rtl::OUString> & _timeStamps)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ sal_Int32 nNumBinaryLayers;
+ m_BinaryReader.read(nNumBinaryLayers);
+ if (nNumBinaryLayers < 0 || sal_uInt32(nNumBinaryLayers) != _timeStamps.size())
+ return false;
+
+ for ( std::vector<rtl::OUString>::const_iterator it = _timeStamps.begin();
+ it != _timeStamps.end();
+ ++it)
+ {
+ rtl::OUString binaryTimeStamp;
+ m_BinaryReader.read(binaryTimeStamp);
+ if ( ! it->equals(binaryTimeStamp) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ // -----------------------------------------------------------------------------
+ binary::NodeType::Type BinaryReadHandler::readNodeType()
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ binary::NodeType::Type eType = binary::NodeType::invalid;
+
+ sal_Int8 nValue;
+ m_BinaryReader.read(nValue);
+
+ sal_uInt8 const nRightValue( nValue );
+ if ( (nRightValue & binary::NodeType::nodetype_mask) == nRightValue )
+ eType = binary::NodeType::Type(nRightValue);
+
+ if (eType == binary::NodeType::invalid)
+ {
+ OSL_ENSURE(false, "unknown or unhandled node type");
+ throw io::WrongFormatException();
+ }
+
+ return eType;
+ }
+
+ // -----------------------------------------------------------------------------
+ binary::ValueFlags::Type BinaryReadHandler::readValueFlags(bool& bSeq, bool& bHasValue, bool& bHasDefault )
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ sal_Int8 nValue;
+ m_BinaryReader.read(nValue);
+
+ sal_uInt8 const nRightValue( nValue );
+ binary::ValueFlags::Type eType = binary::ValueFlags::Type(nRightValue & binary::ValueFlags::basictype_mask);
+ if ( eType >= binary::ValueFlags::val_invalid)
+ {
+ OSL_ENSURE(false, "unknown or unhandled value type");
+ throw io::WrongFormatException();
+ }
+
+
+ if (nRightValue & binary::ValueFlags::seq)
+ bSeq = true;
+ else
+ bSeq = false;
+
+ if (nRightValue & binary::ValueFlags::first_value_NULL)
+ bHasValue = false;
+ else
+ bHasValue = true;
+
+ if (nRightValue & binary::ValueFlags::second_value_NULL)
+ bHasDefault = false;
+ else
+ bHasDefault = true;
+
+ return eType;
+ }
+
+ // -----------------------------------------------------------------------------
+
+ void BinaryReadHandler::readName(rtl::OUString &_aString)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ m_BinaryReader.read (_aString);
+ }
+
+ // -----------------------------------------------------------------------------
+ void BinaryReadHandler::readAttributes(node::Attributes &_aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ sal_Int8 nValue;
+ m_BinaryReader.read(nValue);
+
+ _aAttributes.setState( node::State(nValue & 0x03) );
+
+ _aAttributes.setAccess( nValue & 0x04 ? true : false, nValue & 0x08 ? true : false);
+
+ _aAttributes.setNullable(nValue & 0x10 ? true : false);
+ _aAttributes.setLocalized(nValue & 0x20 ? true : false);
+ if(nValue & 0x40 )
+ {
+ _aAttributes.markMandatory();
+ }
+ if(nValue & 0x80)
+ {
+ _aAttributes.markRemovable();
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryReadHandler::readGroup(rtl::OUString &_aName, node::Attributes &_aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ readAttributes(_aAttributes);
+ readName(_aName);
+ }
+ // -----------------------------------------------------------------------------
+ void BinaryReadHandler::readSet(rtl::OUString &_aName, node::Attributes &_aAttributes,
+ rtl::OUString &_sInstanceName, rtl::OUString &_sInstanceModule)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ readAttributes(_aAttributes);
+ readName(_aName);
+ readName(_sInstanceName);
+ readName(_sInstanceModule);
+ }
+
+ // -----------------------------------------------------------------------------
+ template <class T>
+ inline
+ void readAsAny(BinaryReader& rBinaryReader, uno::Any & _aValue, uno::Type& _aType, T& _aVar)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ rBinaryReader.read(_aVar);
+ _aValue <<= _aVar;
+ _aType = _aValue.getValueType();
+ }
+
+ // -----------------------------------------------------------------------------
+ uno::Type convertValueTypeToType(binary::ValueFlags::Type eBasicValueType, bool bSeq)
+ {
+ uno::Type aType;
+
+ if (!bSeq)
+ {
+ switch(eBasicValueType)
+ {
+ // --------------- Simple types ---------------
+
+ case binary::ValueFlags::val_boolean:
+ aType = SimpleTypeHelper::getBooleanType();
+ break;
+ case binary::ValueFlags::val_int16:
+ aType = SimpleTypeHelper::getShortType();
+ break;
+ case binary::ValueFlags::val_int32:
+ aType = SimpleTypeHelper::getIntType();
+ break;
+ case binary::ValueFlags::val_int64:
+ aType = SimpleTypeHelper::getLongType();
+ break;
+ case binary::ValueFlags::val_double:
+ aType = SimpleTypeHelper::getDoubleType();
+ break;
+ case binary::ValueFlags::val_string:
+ aType = SimpleTypeHelper::getStringType();
+ break;
+ case binary::ValueFlags::val_binary:
+ aType = SimpleTypeHelper::getBinaryType();
+ break;
+ case binary::ValueFlags::val_any:
+ aType = SimpleTypeHelper::getAnyType();
+ break;
+ default:
+ OSL_ENSURE(false,"Invalid value type");
+ break;
+ }
+ }
+ else
+ {
+ // ------------ Sequences ------------
+ switch(eBasicValueType)
+ {
+ case binary::ValueFlags::val_boolean:
+ aType = ::getCppuType(static_cast<uno::Sequence<sal_Bool> const*>(0));
+ break;
+ case binary::ValueFlags::val_int16:
+ aType = ::getCppuType(static_cast<uno::Sequence<sal_Int16> const*>(0));
+ break;
+ case binary::ValueFlags::val_int32:
+ aType = ::getCppuType(static_cast<uno::Sequence<sal_Int32> const*>(0));
+ break;
+ case binary::ValueFlags::val_int64:
+ aType = ::getCppuType(static_cast<uno::Sequence<sal_Int64> const*>(0));
+ break;
+ case binary::ValueFlags::val_double:
+ aType = ::getCppuType(static_cast<uno::Sequence<double> const*>(0));
+ break;
+ case binary::ValueFlags::val_string:
+ aType = ::getCppuType(static_cast<uno::Sequence<rtl::OUString> const*>(0));
+ break;
+ case binary::ValueFlags::val_binary:
+ aType = ::getCppuType(static_cast<uno::Sequence< uno::Sequence< sal_Int8 > > const*>(0));
+ break;
+ default:
+ OSL_ENSURE(false,"Invalid sequence value type");
+ break;
+ }
+ }
+
+ return aType;
+ }
+
+ // -----------------------------------------------------------------------------
+ void BinaryReadHandler::readValue(rtl::OUString &_aName, node::Attributes &_aAttributes,
+ uno::Any& _aValue, uno::Any& _aDefaultValue,uno::Type& _aType)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ bool bSeq = false;
+ bool bHasValue = false;
+ bool bHasDefault = false;
+
+ binary::ValueFlags::Type eBasicType = readValueFlags(bSeq, bHasValue, bHasDefault);
+ readAttributes(_aAttributes);
+ readName(_aName);
+
+ if (!bSeq && (bHasValue || bHasDefault))
+ {
+ switch(eBasicType)
+ {
+ case binary::ValueFlags::val_any:
+ {
+ OSL_ENSURE(false,"Node of type Any cannot have value");
+ throw io::WrongFormatException();
+ }
+ case binary::ValueFlags::val_string:
+ {
+ rtl::OUString aStr;
+ if (bHasValue)
+ readAsAny(m_BinaryReader, _aValue, _aType, aStr);
+ if (bHasDefault)
+ readAsAny(m_BinaryReader, _aDefaultValue, _aType, aStr);
+ break;
+ }
+ case binary::ValueFlags::val_boolean:
+ {
+ sal_Bool nValue;
+ if (bHasValue)
+ readAsAny(m_BinaryReader,_aValue, _aType, nValue);
+ if (bHasDefault)
+ readAsAny(m_BinaryReader,_aDefaultValue, _aType, nValue);
+ break;
+ }
+ case binary::ValueFlags::val_int16:
+ {
+ sal_Int16 nValue;
+ if (bHasValue)
+ readAsAny(m_BinaryReader,_aValue, _aType, nValue);
+ if (bHasDefault)
+ readAsAny(m_BinaryReader,_aDefaultValue, _aType, nValue);
+ break;
+ }
+ case binary::ValueFlags::val_int32:
+ {
+ sal_Int32 nValue;
+ if (bHasValue)
+ readAsAny(m_BinaryReader,_aValue, _aType, nValue);
+ if (bHasDefault)
+ readAsAny(m_BinaryReader,_aDefaultValue, _aType, nValue);
+ break;
+ }
+ case binary::ValueFlags::val_int64:
+ {
+ sal_Int64 nValue;
+ if (bHasValue)
+ readAsAny(m_BinaryReader,_aValue, _aType, nValue);
+ if (bHasDefault)
+ readAsAny(m_BinaryReader,_aDefaultValue, _aType, nValue);
+ break;
+ }
+ case binary::ValueFlags::val_double:
+ {
+ double nValue;
+ if (bHasValue)
+ readAsAny(m_BinaryReader,_aValue, _aType, nValue);
+ if (bHasDefault)
+ readAsAny(m_BinaryReader, _aDefaultValue, _aType, nValue);
+ break;
+ }
+ case binary::ValueFlags::val_binary:
+ {
+ uno::Sequence< sal_Int8 > aValue;
+ if (bHasValue)
+ readAsAny(m_BinaryReader,_aValue, _aType, aValue);
+ if (bHasDefault)
+ readAsAny(m_BinaryReader,_aDefaultValue, _aType, aValue);
+ break;
+ }
+ default:
+ OSL_ENSURE(false, "Invalid value type");
+ throw io::WrongFormatException();
+ }
+ }
+ else
+ {
+ _aType = convertValueTypeToType(eBasicType, bSeq);
+ if (_aType == uno::Type())
+ throw io::WrongFormatException();
+ }
+
+ if(bSeq)
+ {
+ OSL_ASSERT(_aType.getTypeClass() == uno::TypeClass_SEQUENCE);
+ uno::Type const aElementType = getSequenceElementType(_aType);
+ if (bHasValue)
+ readSequenceValue(m_BinaryReader, _aValue, aElementType );
+
+ if(bHasDefault)
+ readSequenceValue(m_BinaryReader, _aDefaultValue, aElementType );
+ }
+
+ }
+ // -----------------------------------------------------------------------------
+ std::auto_ptr<ISubtree> BinaryReadHandler::readComponentTree()
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ binary::NodeType::Type eType = this->readNodeType();
+
+ if (eType != binary::NodeType::component)
+ {
+ // TODO: search for component tree
+ OSL_ENSURE(false, "binary Cache: unexpected tree type for component data");
+ throw io::WrongFormatException();
+ }
+
+ return readToplevelTree();
+ }
+ // -----------------------------------------------------------------------------
+ std::auto_ptr<ISubtree> BinaryReadHandler::readTemplatesTree()
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ binary::NodeType::Type eType = this->readNodeType();
+
+ if (eType != binary::NodeType::templates)
+ {
+ // TODO: search for templates tree
+ OSL_ENSURE(false, "binary Cache: unexpected tree type for template data");
+ throw io::WrongFormatException();
+ }
+
+ return readToplevelTree();
+ }
+ // -----------------------------------------------------------------------------
+
+ std::auto_ptr<ISubtree> BinaryReadHandler::readToplevelTree()
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ std::auto_ptr<ISubtree> pTree;
+
+ rtl::OUString aName;
+ node::Attributes aAttributes;
+ const bool not_extensible = false;
+
+ binary::NodeType::Type eType = this->readNodeType();
+ switch (eType)
+ {
+ case binary::NodeType::groupnode:
+ {
+ this->readGroup(aName, aAttributes);
+ pTree = m_aNodeFactory.createGroup(aName,not_extensible,aAttributes);
+ break;
+ }
+ case binary::NodeType::setnode:
+ {
+ backenduno::TemplateIdentifier aTemplate;
+ this->readSet(aName, aAttributes,aTemplate.Name, aTemplate.Component);
+ pTree = m_aNodeFactory.createSet(aName,aTemplate,not_extensible,aAttributes);
+ break;
+ }
+ case binary::NodeType::nodata:
+ break;
+
+ default:
+ OSL_ENSURE(false, "binary Cache - cannot read data: unexpected node type for tree");
+ throw io::WrongFormatException();
+
+ }
+
+ if (pTree.get() != NULL)
+ {
+ readChildren(*pTree);
+
+ //read terminating stop node
+ eType = this->readNodeType();
+ OSL_ENSURE(binary::NodeType::stop == eType, "Missing stop node to mark end of tree");
+ }
+ return pTree;
+ }
+
+
+ // -----------------------------------------------------------------------------
+ bool BinaryReadHandler::validateHeader( const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ const rtl::OUString& _aSchemaVersion,
+ com::sun::star::lang::Locale const & aRequestedLocale,
+ std::vector< com::sun::star::lang::Locale > & outKnownLocales)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+
+ //Check here if the file exists
+ if (!m_BinaryReader.open())
+ return false;
+
+ if(!this->verifyFileHeader(pLayers, nNumLayers, _aSchemaVersion, aRequestedLocale, outKnownLocales))
+ return false;
+
+ //Check if layers are uptodate
+ std::vector <rtl::OUString> timeStamps(nNumLayers);
+ for (sal_Int32 i = 0 ; i < nNumLayers ; ++ i)
+ {
+ uno::Reference<util::XTimeStamped> xTimeStamp = uno::Reference<util::XTimeStamped>(pLayers[i], uno::UNO_QUERY);
+ if (xTimeStamp.is())
+ {
+ rtl::OUString aTimeStamp = xTimeStamp->getTimestamp();
+ timeStamps[i] = aTimeStamp;
+ }
+ }
+
+ return this->isUptodate(timeStamps);
+ }
+ // -----------------------------------------------------------------------------
+ void BinaryReadHandler::readChildren(ISubtree & rTree )
+ {
+ OSL_ASSERT(!binary::NodeType::stop); // loop stops at stop node
+ while (binary::NodeType::Type eType = this->readNodeType())
+ {
+ rtl::OUString aName;
+ node::Attributes aAttributes;
+ const bool not_extensible = false;
+ switch (eType)
+ {
+ case binary::NodeType::groupnode:
+ {
+ this->readGroup(aName, aAttributes);
+
+ std::auto_ptr<ISubtree> pNewNode = m_aNodeFactory.createGroup(aName, not_extensible, aAttributes);
+ if (pNewNode.get() == NULL)
+ {
+ OSL_ENSURE(false, "Error: factory returned NULL group node - skipping");
+ continue;
+ }
+
+ readChildren( *pNewNode );
+ rTree.addChild(base_ptr(pNewNode));
+ break;
+ }
+ case binary::NodeType::setnode:
+ {
+ backenduno::TemplateIdentifier aTemplate;
+ this->readSet(aName, aAttributes,aTemplate.Name, aTemplate.Component);
+
+ std::auto_ptr<ISubtree> pNewSetNode = m_aNodeFactory.createSet(aName,aTemplate,not_extensible,aAttributes);
+ if (pNewSetNode.get() == NULL)
+ {
+ OSL_ENSURE(false, "Error: factory returned NULL set node - skipping");
+ continue;
+ }
+
+ readChildren( *pNewSetNode );
+ rTree.addChild(base_ptr(pNewSetNode));
+ break;
+ }
+ case binary::NodeType::valuenode:
+ {
+ uno::Any aValue;
+ uno::Any aDefaultValue;
+ uno::Type aType;
+
+ this->readValue(aName, aAttributes, aValue, aDefaultValue, aType);
+
+ OTreeNodeFactory & rValueFactory = m_aNodeFactory.getNodeFactory();
+
+ std::auto_ptr<ValueNode> pValueNode;
+ if (aValue.hasValue() || aDefaultValue.hasValue())
+ {
+ pValueNode = rValueFactory.createValueNode(aName,aValue, aDefaultValue, aAttributes);
+ }
+ else
+ {
+ pValueNode = rValueFactory.createNullValueNode(aName,aType, aAttributes);
+ }
+
+ rTree.addChild(base_ptr(pValueNode));
+ break;
+ }
+ default:
+ OSL_ENSURE(false, "Binary cache: Invalid node type");
+ throw io::WrongFormatException();
+ }
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------
+ }
+ // -----------------------------------------------------------------------------
+}
diff --git a/configmgr/source/backend/binaryreadhandler.hxx b/configmgr/source/backend/binaryreadhandler.hxx
new file mode 100644
index 000000000000..4c8dc921ffb4
--- /dev/null
+++ b/configmgr/source/backend/binaryreadhandler.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binaryreadhandler.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_BINARYREADHANDLER_HXX
+#define CONFIGMGR_BINARYREADHANDLER_HXX
+
+#include "binaryreader.hxx"
+#include "componentdatahelper.hxx"
+#include "valuenode.hxx"
+#include "binarytype.hxx"
+#include "attributes.hxx"
+#include "matchlocale.hxx"
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+#include <com/sun/star/io/IOException.hpp>
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif // INCLUDED_MEMORY
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif // INCLUDED_VECTOR
+
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace css = com::sun::star;
+
+ namespace io = css::io;
+ namespace uno = css::uno;
+ namespace backenduno = css::configuration::backend ;
+
+ // -----------------------------------------------------------------------------
+
+ class BinaryReadHandler
+ {
+ BinaryReader m_BinaryReader;
+ ComponentDataFactory m_aNodeFactory;
+ rtl::OUString m_aComponentName;
+
+ public:
+ BinaryReadHandler(rtl::OUString const & _aFileURL, rtl::OUString const & _aComponentName, uno::Reference<lang::XMultiServiceFactory> const & _aFactory);
+ ~BinaryReadHandler();
+
+ bool validateHeader( const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ const rtl::OUString& _aSchemaVersion,
+ com::sun::star::lang::Locale const & aRequestedLocale,
+ std::vector< com::sun::star::lang::Locale > & outKnownLocales)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ std::auto_ptr<ISubtree> readComponentTree()
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ std::auto_ptr<ISubtree> readTemplatesTree()
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ private:
+ std::auto_ptr<ISubtree> readToplevelTree()
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void readChildren(ISubtree & rTree)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ private:
+ bool verifyFileHeader( const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ const rtl::OUString& _aSchemaVersion,
+ com::sun::star::lang::Locale const & aRequestedLocale,
+ std::vector< com::sun::star::lang::Locale > & outKnownLocales);
+
+ bool isUptodate(const std::vector<rtl::OUString> & _timeStamps)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void readChildNodes(ISubtree & rSubTree)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ binary::NodeType::Type readNodeType()
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ binary::ValueFlags::Type readValueFlags(bool& bSeq, bool& hasValue, bool& hasDefault )
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void readAttributes(node::Attributes &_aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void readGroup(rtl::OUString &_aName, node::Attributes &_aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void readSet(rtl::OUString &_aName, node::Attributes &_aAttributes,
+ rtl::OUString &_sInstanceName, rtl::OUString &_sInstanceModule)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void readValue(rtl::OUString &_aName, node::Attributes &_aAttributes,
+ uno::Any& _aValue, uno::Any& _aDefaultValue,uno::Type& _aType)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void readName(rtl::OUString &_aString)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+ };
+ // ---------------------------------------------------------------------------
+ }
+ // -----------------------------------------------------------------------------
+}// namespace configmgr
+#endif
diff --git a/configmgr/source/backend/binarytype.hxx b/configmgr/source/backend/binarytype.hxx
new file mode 100644
index 000000000000..d335aabb4508
--- /dev/null
+++ b/configmgr/source/backend/binarytype.hxx
@@ -0,0 +1,61 @@
+#ifndef CONFIGMGR_BINARYTYPE_HXX
+#define CONFIGMGR_BINARYTYPE_HXX
+
+#include <sal/types.h>
+
+namespace configmgr
+{
+ namespace binary
+ {
+ const sal_uInt32 STR_ASCII_MASK = 0x80000000;
+ const sal_Int16 CFG_BINARY_MAGIC = 10001;
+ const sal_Int16 CFG_BINARY_VERSION = 3;
+
+ namespace ValueFlags
+ {
+ enum Type
+ {
+ val_any, // = 0
+ val_string, // = 1
+ val_boolean, // = 2
+ val_int16, // = 3
+ val_int32, // = 4
+ val_int64, // = 5
+ val_double, // = 6
+ val_binary, // = 7
+ val_invalid, // = 8
+
+ //Sequence Flag
+ seq = 0x10,
+
+ //Pairstate Flags
+ first_value_NULL = 0x20,
+ second_value_NULL = 0x40,
+
+ //Masks
+ basictype_mask = 0x0F,
+ valuetype_mask = 0x1F,
+ pairstate_mask = first_value_NULL | second_value_NULL
+ };
+ }
+
+ namespace NodeType
+ {
+ enum Type
+ {
+ //Node Type Identifiers
+ stop = 0,
+ valuenode = 0x20,
+ groupnode = 0x40,
+ setnode = 0x80,
+ component = 0x60,
+ templates = 0xA0,
+ nodata = 0xC0,
+ invalid = 0xE0,
+
+ nodetype_mask = 0xE0
+ };
+ }
+ }
+}
+#endif
diff --git a/configmgr/source/backend/binarywritehandler.cxx b/configmgr/source/backend/binarywritehandler.cxx
new file mode 100644
index 000000000000..e81a718ed11d
--- /dev/null
+++ b/configmgr/source/backend/binarywritehandler.cxx
@@ -0,0 +1,492 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binarywritehandler.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "binarywritehandler.hxx"
+#include "binarycache.hxx"
+#include <com/sun/star/util/XTimeStamped.hpp>
+#include "typeconverter.hxx"
+#include "simpletypehelper.hxx"
+
+#define ASCII(x) rtl::OUString::createFromAscii(x)
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+
+ namespace css = com::sun::star;
+ namespace util = css::util ;
+
+ // -----------------------------------------------------------------------------
+
+ BinaryWriteHandler::BinaryWriteHandler( rtl::OUString const & _aFileURL,
+ rtl::OUString const & _aComponentName,
+ uno::Reference<lang::XMultiServiceFactory> const & _aFactory)
+ : m_BinaryWriter(_aFileURL,_aFactory)
+ , m_aComponentName(_aComponentName)
+ {
+
+ }
+ // -----------------------------------------------------------------------------
+ static
+ binary::ValueFlags::Type convertTypeToValueType(uno::Type const& _aType)
+ {
+ binary::ValueFlags::Type eType = binary::ValueFlags::val_invalid;
+ uno::TypeClass const aClass = _aType.getTypeClass();
+ switch(aClass)
+ {
+ case uno::TypeClass_ANY:
+ eType = binary::ValueFlags::val_any;
+ break;
+ case uno::TypeClass_BOOLEAN:
+ eType = binary::ValueFlags::val_boolean;
+ break;
+ case uno::TypeClass_SHORT:
+ eType = binary::ValueFlags::val_int16;
+ break;
+ case uno::TypeClass_LONG:
+ eType = binary::ValueFlags::val_int32;
+ break;
+ case uno::TypeClass_HYPER:
+ eType = binary::ValueFlags::val_int64;
+ break;
+ case uno::TypeClass_DOUBLE:
+ eType = binary::ValueFlags::val_double;
+ break;
+ case uno::TypeClass_STRING:
+ eType = binary::ValueFlags::val_string;
+ break;
+ case uno::TypeClass_SEQUENCE:
+ if (_aType == SimpleTypeHelper::getBinaryType())
+ {
+ eType = binary::ValueFlags::val_binary;
+ }
+ else
+ {
+ uno::Type aType = configmgr::getSequenceElementType(_aType);
+ eType = convertTypeToValueType(aType);
+
+ OSL_ENSURE(!(eType & binary::ValueFlags::seq), "Binary Writer - Invalid value type: Multiple nesting of sequences");
+ eType = binary::ValueFlags::Type( eType | binary::ValueFlags::seq );
+ }
+ break;
+ default:
+ OSL_ENSURE(false, "Binary Writer - Invalid value type: not supported");
+ break;
+ }
+ return eType;
+ }
+
+ // -----------------------------------------------------------------------------
+ template <class T>
+ inline /* make performance crew happy ;-) */
+ void writeDirectly(BinaryWriter& _rWriter, T const& _aVal)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ _rWriter.write(_aVal);
+ }
+ // -----------------------------------------------------------------------------
+ static
+ inline
+ void writeDirectly(BinaryWriter& _rWriter, uno::Sequence<sal_Int8> const& _aBinary);
+ // -----------------------------------------------------------------------------
+ template <class T>
+ inline /* make performance crew happy ;-) */
+ void writeFromAny(BinaryWriter& _rWriter,uno::Any const& _aValue, T& _aVar)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ OSL_VERIFY(_aValue >>= _aVar ); // "Invalid Any for value"
+ writeDirectly(_rWriter,_aVar);
+ }
+ // -----------------------------------------------------------------------------
+
+ template <class Element>
+ void writeSequence(BinaryWriter& _rWriter, uno::Sequence< Element > const& aSequence)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ sal_Int32 const nLength = aSequence.getLength();
+ _rWriter.write(nLength);
+
+ for(sal_Int32 i=0; i<nLength; ++i)
+ {
+ writeDirectly(_rWriter, aSequence[i]);
+ }
+ }
+ // -----------------------------------------------------------------------------
+ static
+ inline
+ void writeDirectly(BinaryWriter& _rWriter, uno::Sequence<sal_Int8> const& _aBinary)
+ {
+ writeSequence(_rWriter,_aBinary);
+ }
+ // -----------------------------------------------------------------------------
+ #define CASE_WRITE_SEQUENCE(TYPE_CLASS, DATA_TYPE) \
+ case TYPE_CLASS: \
+ { \
+ uno::Sequence< DATA_TYPE > aData; \
+ OSL_ASSERT( ::getCppuType(aData.getConstArray()).getTypeClass() == (TYPE_CLASS) ); \
+ OSL_VERIFY( _aValue >>= aData ); \
+ writeSequence(_rWriter,aData); \
+ } break
+
+ // -----------------------------------------------------------------------------
+ static
+ void writeSequenceValue(BinaryWriter& _rWriter, uno::Any const& _aValue, uno::Type const& aElementType)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ switch(aElementType.getTypeClass())
+ {
+ CASE_WRITE_SEQUENCE( uno::TypeClass_BOOLEAN, sal_Bool );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_SHORT, sal_Int16 );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_LONG, sal_Int32 );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_HYPER, sal_Int64 );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_DOUBLE, double );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_STRING, rtl::OUString );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_SEQUENCE, uno::Sequence<sal_Int8> );
+
+ default:
+ OSL_ENSURE(false, "Unexpected typeclass for sequence elements");
+ break;
+ }
+ }
+ #undef CASE_WRITE_SEQUENCE
+
+ // -----------------------------------------------------------------------------
+ static
+ void writeSimpleValue(BinaryWriter& _rWriter, uno::Any const& _aValue, uno::Type const& _aType)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // PRE: Header must be written
+ uno::TypeClass aDestinationClass = _aType.getTypeClass();
+ switch (aDestinationClass)
+ {
+ case uno::TypeClass_BOOLEAN:
+ {
+ sal_Bool bValue = sal_False;
+ writeFromAny(_rWriter, _aValue, bValue);
+ break;
+ }
+ case uno::TypeClass_BYTE:
+ {
+ sal_Int8 nValue = 0;
+ writeFromAny(_rWriter, _aValue, nValue);
+ break;
+ }
+ case uno::TypeClass_SHORT:
+ {
+ sal_Int16 nValue = 0;
+ writeFromAny(_rWriter, _aValue, nValue);
+ break;
+ }
+ case uno::TypeClass_LONG:
+ {
+ sal_Int32 nValue = 0;
+ writeFromAny(_rWriter, _aValue, nValue);
+ break;
+ }
+ case uno::TypeClass_HYPER:
+ {
+ sal_Int64 nValue = 0;
+ writeFromAny(_rWriter, _aValue, nValue);
+ break;
+ }
+ case uno::TypeClass_DOUBLE:
+ {
+ double nValue = 0;
+ writeFromAny(_rWriter, _aValue, nValue);
+ break;
+ }
+ case uno::TypeClass_STRING:
+ {
+ rtl::OUString aStr;
+ writeFromAny(_rWriter, _aValue, aStr);
+ break;
+ }
+ case uno::TypeClass_SEQUENCE:
+ {
+ OSL_ENSURE (_aType == SimpleTypeHelper::getBinaryType(),"Unexpected sequence as simple type");
+ uno::Sequence<sal_Int8> aBinary;
+ writeFromAny(_rWriter, _aValue, aBinary);
+ break;
+ }
+ default:
+ OSL_ENSURE(false, "Unexpected typeclass for simple value");
+ break;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeValue(uno::Any const& _aValue)
+ {
+ bool bSeq;
+ uno::Type aTargetType = getBasicType(_aValue.getValueType(), bSeq);
+
+ if (!bSeq)
+ {
+ writeSimpleValue(m_BinaryWriter,_aValue, aTargetType);
+ }
+ else
+ {
+ writeSequenceValue(m_BinaryWriter,_aValue, aTargetType);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeFileHeader( rtl::OUString const & _aSchemaVersion,
+ const uno::Sequence<rtl::OUString> & aKnownLocales,
+ const uno::Sequence<rtl::OUString> & aDataLocales )
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ m_BinaryWriter.write(binary::CFG_BINARY_MAGIC);
+ m_BinaryWriter.write(binary::CFG_BINARY_VERSION);
+ m_BinaryWriter.write(_aSchemaVersion);
+ writeSequence(m_BinaryWriter,aKnownLocales);
+ writeSequence(m_BinaryWriter,aDataLocales);
+ m_BinaryWriter.write(m_aComponentName);
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeGroupNode(rtl::OUString const& _aName,node::Attributes const& _aAttributes )
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ writeAttributes(_aAttributes );
+ m_BinaryWriter.write(_aName);
+ }
+
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeSetNode(rtl::OUString const& _aName,
+ rtl::OUString const& _aTemplateName,
+ rtl::OUString const& _aTemplateModule,
+ node::Attributes const& _aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ writeAttributes(_aAttributes );
+ m_BinaryWriter.write(_aName);
+ m_BinaryWriter.write(_aTemplateName);
+ m_BinaryWriter.write(_aTemplateModule);
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeLayerInfoList(uno::Reference<backenduno::XLayer> const * pLayers, sal_Int32 nNumLayers)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+
+ m_BinaryWriter.write(nNumLayers);
+ for (sal_Int32 i = 0 ; i < nNumLayers ; ++ i)
+ {
+ uno::Reference<util::XTimeStamped> xTimeStamp = uno::Reference<util::XTimeStamped>(pLayers[i], uno::UNO_QUERY);
+
+ rtl::OUString aTimeStamp = xTimeStamp.is() ? xTimeStamp->getTimestamp() : rtl::OUString();
+ m_BinaryWriter.write(aTimeStamp);
+ }
+
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeNodeType(binary::NodeType::Type _eType)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ sal_Int8 nValue = static_cast< sal_Int8 >( _eType );
+ m_BinaryWriter.write(nValue);
+
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeAttributes(node::Attributes const& _aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ sal_Int8 nValue = static_cast< sal_Int8 >( _aAttributes.state() );
+
+ OSL_ASSERT(0 <= nValue && nValue <= 3);
+
+ OSL_ENSURE(!_aAttributes.isReadonly() || !_aAttributes.isFinalized(),"Unexpected attribute mix: node is both read-only and finalized");
+
+ nValue |= (_aAttributes.isReadonly() ? 1 : 0) << 2;
+ nValue |= (_aAttributes.isFinalized() ? 1 : 0) << 3;
+
+ nValue |= (_aAttributes.isNullable() ? 1 : 0) << 4;
+ nValue |= (_aAttributes.isLocalized() ? 1 : 0) << 5;
+
+ nValue |= (_aAttributes.isMandatory() ? 1 : 0) << 6;
+ nValue |= (_aAttributes.isRemovable() ? 1 : 0) << 7;
+
+ m_BinaryWriter.write(nValue);
+
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeValueNode(rtl::OUString const& _aName,
+ node::Attributes const& _aAttributes,
+ uno::Type const& _aType,
+ uno::Any const& _aUserValue,
+ uno::Any const& _aDefaultValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ //write value flags
+ binary::ValueFlags::Type eType = convertTypeToValueType(_aType);
+ sal_Int8 nValueType = sal_Int8(eType);
+
+ bool hasUserValue = _aUserValue.hasValue();
+ bool hasDefault = _aDefaultValue.hasValue();
+
+ if (!hasUserValue) nValueType |= binary::ValueFlags::first_value_NULL;
+ if (!hasDefault) nValueType |= binary::ValueFlags::second_value_NULL;
+
+ m_BinaryWriter.write(nValueType);
+ writeAttributes(_aAttributes );
+ m_BinaryWriter.write(_aName);
+
+ if(hasUserValue)
+ {
+ OSL_ENSURE(_aUserValue.getValueType() == _aType, "Type mismatch in value node");
+ writeValue(_aUserValue);
+ }
+ if(hasDefault)
+ {
+ OSL_ENSURE(_aDefaultValue.getValueType() == _aType, "Type mismatch in value node");
+ writeValue(_aDefaultValue);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeStop()
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ sal_Int8 nStopValue = 0;
+ m_BinaryWriter.write(nStopValue);
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeComponentTree(const ISubtree * _pComponentTree)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ this->writeNodeType(binary::NodeType::component);
+ if (_pComponentTree)
+ {
+ this->writeTree(*_pComponentTree);
+ this->writeStop();
+ }
+ else
+ {
+ this->writeNodeType(binary::NodeType::nodata);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeTemplatesTree(const ISubtree * _pTemplatesTree)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ this->writeNodeType(binary::NodeType::templates);
+ if (_pTemplatesTree)
+ {
+ this->writeTree(*_pTemplatesTree);
+ this->writeStop();
+ }
+ else
+ {
+ this->writeNodeType(binary::NodeType::nodata);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::writeTree(const ISubtree & rTree)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ if ( rTree.isSetNode() )
+ {
+ this->writeNodeType(binary::NodeType::setnode);
+ this->writeSetNode( rTree.getName(),
+ rTree.getElementTemplateName(),
+ rTree.getElementTemplateModule(),
+ rTree.getAttributes());
+ }
+ else
+ {
+ this->writeNodeType(binary::NodeType::groupnode);
+ this->writeGroupNode( rTree.getName(), rTree.getAttributes() );
+ }
+
+ // process children
+ this->applyToChildren(rTree);
+
+ this->writeStop();
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::handle(const ISubtree & rTree)
+ {
+ writeTree(rTree);
+ }
+ // -----------------------------------------------------------------------------
+
+ void BinaryWriteHandler::handle(const ValueNode & rValue)
+ {
+ this->writeNodeType(binary::NodeType::valuenode);
+
+ this->writeValueNode( rValue.getName(),
+ rValue.getAttributes(),
+ rValue.getValueType(),
+ rValue.getUserValue(),
+ rValue.getDefault() );
+ }
+ // -----------------------------------------------------------------------------
+
+ bool BinaryWriteHandler::generateHeader(const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ const rtl::OUString& aEntity,
+ const std::vector< com::sun::star::lang::Locale > & aKnownLocales )
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ //Open the writer
+ if (!m_BinaryWriter.open())
+ return false;
+
+ this->writeFileHeader( aEntity,
+ localehelper::makeIsoSequence(aKnownLocales),
+ getAvailableLocales(pLayers,nNumLayers) );
+
+ this->writeLayerInfoList(pLayers, nNumLayers);
+ return true;
+ }
+ // -----------------------------------------------------------------------------
+
+ }
+ // -----------------------------------------------------------------------------
+}
diff --git a/configmgr/source/backend/binarywritehandler.hxx b/configmgr/source/backend/binarywritehandler.hxx
new file mode 100644
index 000000000000..63fff70cec2b
--- /dev/null
+++ b/configmgr/source/backend/binarywritehandler.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binarywritehandler.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_BINARYWRITEHANDLER_HXX
+#define CONFIGMGR_BINARYWRITEHANDLER_HXX
+
+#include "valuenode.hxx"
+#include "binarywriter.hxx"
+#include "binarytype.hxx"
+#include "attributes.hxx"
+#include "matchlocale.hxx"
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+#include <com/sun/star/io/IOException.hpp>
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace css = com::sun::star;
+
+ namespace io = css::io;
+ namespace uno = css::uno;
+ namespace backenduno = css::configuration::backend ;
+
+ // -----------------------------------------------------------------------------
+ class BinaryWriteHandler : private NodeAction
+ {
+ BinaryWriter m_BinaryWriter;
+ rtl::OUString m_aComponentName;
+
+ public:
+ BinaryWriteHandler(rtl::OUString const & _aFileURL, rtl::OUString const & _aComponentName, uno::Reference<lang::XMultiServiceFactory> const & _aFactory);
+
+ bool generateHeader( const uno::Reference<backenduno::XLayer> * pLayers,
+ sal_Int32 nNumLayers,
+ const rtl::OUString& aEntity,
+ const std::vector< com::sun::star::lang::Locale > & aKnownLocales )
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeComponentTree(const ISubtree * _pComponentTree)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void writeTemplatesTree(const ISubtree * _pTemplatesTree)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+ private:
+ void writeTree(ISubtree const & rTree)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ // Node Action
+ virtual void handle(ISubtree const & aSubtree);
+ virtual void handle(ValueNode const & aValue);
+ private:
+ void writeFileHeader( rtl::OUString const & _aSchemaVersion,
+ const uno::Sequence<rtl::OUString> & aKnownLocales,
+ const uno::Sequence<rtl::OUString> & aDataLocales )
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeLayerInfoList(uno::Reference<backenduno::XLayer> const * pLayers, sal_Int32 nNumlayers)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeGroupNode(rtl::OUString const& _aName,node::Attributes const& _aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeValueNode(rtl::OUString const& _aName,
+ node::Attributes const& _aAttributes,
+ uno::Type const& _aType,
+ uno::Any const& _aUserValue,
+ uno::Any const& _aDefaultValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeSetNode(rtl::OUString const& _aName,
+ rtl::OUString const& _aTemplateName,
+ rtl::OUString const& _aTemplateModule,
+ node::Attributes const& _aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeAttributes(node::Attributes const& _aAttributes)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeNodeType(binary::NodeType::Type _eType)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeStop()
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ void writeValue( uno::Any const& _aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ };
+ // ---------------------------------------------------------------------------
+ }
+ // -----------------------------------------------------------------------------
+}// namespace configmgr
+#endif
diff --git a/configmgr/source/backend/binarywriter.cxx b/configmgr/source/backend/binarywriter.cxx
new file mode 100644
index 000000000000..a7def5d773e3
--- /dev/null
+++ b/configmgr/source/backend/binarywriter.cxx
@@ -0,0 +1,218 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binarywriter.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "binarywriter.hxx"
+#include "valuenode.hxx"
+#include "filehelper.hxx"
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include "oslstream.hxx"
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XDataOutputStream.hpp>
+#include "typeconverter.hxx"
+#include "binarytype.hxx"
+#include "simpletypehelper.hxx"
+
+#define ASCII(x) rtl::OUString::createFromAscii(x)
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace uno = com::sun::star::uno;
+ namespace io = com::sun::star::io;
+
+ BinaryWriter::BinaryWriter(rtl::OUString const &_aFileURL, uno::Reference<lang::XMultiServiceFactory> const& _xServiceProvider)
+ : m_aFileURL(_aFileURL)
+ , m_xServiceProvider(_xServiceProvider)
+ , m_xDataOutputStream()
+ {}
+
+ bool BinaryWriter::open() SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ if (m_aFileURL.getLength() == 0)
+ return false;
+
+ OSL_ENSURE(!m_xDataOutputStream.is(), "Binary Writer: already open");
+ if ( m_xDataOutputStream.is())
+ return false;
+
+ if (FileHelper::fileExists(m_aFileURL))
+ {
+ if (osl::File::RC errorCode = osl::File::remove(m_aFileURL))
+ {
+ // creating the file will fail later
+ OSL_TRACE("Binary Cache: Cannot remove existing file [%d]",int(errorCode));
+ }
+ }
+ else
+ {
+ //create missing directories
+ rtl::OUString parentDirectory = FileHelper::getParentDir(m_aFileURL) ;
+
+ if (osl::File::RC errorCode = FileHelper::mkdirs(parentDirectory))
+ {
+ // creating the file will fail later
+ OSL_TRACE("Binary Cache: Cannot create package cache directory [%d]",int(errorCode));
+ }
+ }
+
+ uno::Reference<io::XOutputStream> xOutput = new BufferedFileOutputStream(m_aFileURL, true, 1024);
+
+ uno::Reference< io::XActiveDataSource > xFormattingStream(
+ m_xServiceProvider->createInstance(ASCII("com.sun.star.io.DataOutputStream")),
+ uno::UNO_QUERY_THROW);
+
+ xFormattingStream->setOutputStream(xOutput);
+
+ m_xDataOutputStream.set(xFormattingStream, uno::UNO_QUERY_THROW);
+
+ OSL_ASSERT(m_xDataOutputStream.is());
+ return m_xDataOutputStream.is();
+ }
+
+ void BinaryWriter::close() SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ if (m_xDataOutputStream.is())
+ m_xDataOutputStream->closeOutput();
+
+ m_xDataOutputStream.clear();
+ }
+
+ BinaryWriter::~BinaryWriter()
+ {
+ try
+ {
+ close();
+ }
+ catch (uno::Exception& e)
+ {
+ (void)e;
+ OSL_ENSURE(false, rtl::OUStringToOString(e.Message,RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ void BinaryWriter::write(sal_Bool _aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // write one byte
+ m_xDataOutputStream->writeBoolean(_aValue);
+ }
+ void BinaryWriter::write(sal_Int8 _aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // write one byte
+ m_xDataOutputStream->writeByte(_aValue);
+ }
+ void BinaryWriter::write(sal_Int16 _aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // write two bytes
+ m_xDataOutputStream->writeShort(_aValue);
+ }
+ void BinaryWriter::write(sal_Int32 _aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // write four byte
+ m_xDataOutputStream->writeLong(_aValue);
+ }
+ void BinaryWriter::write(sal_Int64 _aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // write eight byte
+ m_xDataOutputStream->writeHyper(_aValue);
+ }
+ void BinaryWriter::write(double _aValue)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // write eight byte
+ m_xDataOutputStream->writeDouble(_aValue);
+ }
+
+ // -----------------------------------------------------------------------------
+ bool isAsciiEncoding(rtl::OUString const& _aStr)
+ {
+ const sal_Unicode *pStr = _aStr.getStr();
+ sal_Int32 nLen = _aStr.getLength();
+ while (nLen--)
+ {
+ if (*pStr++ > 127)
+ return false;
+ }
+ return true;
+ }
+
+ // -----------------------------------------------------------------------------
+ void BinaryWriter::write(rtl::OUString const& _aStr)
+ SAL_THROW( (io::IOException, uno::RuntimeException) )
+ {
+ // @@@ OBinaryBaseReader_Impl::readUTF() @@@
+
+ rtl::OString aUTF;
+ // to fasten the conversion for ascii data, we mask the length
+ bool bIsAscii = isAsciiEncoding(_aStr);
+ if (bIsAscii)
+ rtl_uString2String (
+ &(aUTF.pData), _aStr.getStr(), _aStr.getLength(),
+ RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS);
+ else
+ rtl_uString2String (
+ &(aUTF.pData), _aStr.getStr(), _aStr.getLength(),
+ RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ sal_Int32 nLength = aUTF.getLength();
+ uno::Sequence<sal_Int8> aData (nLength);
+ memcpy (aData.getArray(), aUTF.getStr(), nLength);
+
+ OSL_ENSURE((nLength & binary::STR_ASCII_MASK) == 0,"String too long");
+ if (bIsAscii)
+ {
+ nLength |= binary::STR_ASCII_MASK;
+ OSL_ASSERT((nLength & binary::STR_ASCII_MASK) == binary::STR_ASCII_MASK);
+ OSL_ASSERT(sal_Int32(nLength & ~binary::STR_ASCII_MASK) == aData.getLength());
+ }
+ m_xDataOutputStream->writeLong (nLength);
+
+ m_xDataOutputStream->writeBytes (aData);
+ }
+
+ // -----------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------
+ }
+// -----------------------------------------------------------------------------
+}
diff --git a/configmgr/source/backend/binarywriter.hxx b/configmgr/source/backend/binarywriter.hxx
new file mode 100644
index 000000000000..9f9617a2f43b
--- /dev/null
+++ b/configmgr/source/backend/binarywriter.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: binarywriter.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_BINARYWRITER_HXX
+#define CONFIGMGR_BINARYWRITER_HXX
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/XDataOutputStream.hpp>
+
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ namespace css = com::sun::star;
+
+ namespace io = css::io;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+ // -----------------------------------------------------------------------------
+
+ class BinaryWriter
+ {
+ rtl::OUString m_aFileURL;
+
+ uno::Reference<lang::XMultiServiceFactory> m_xServiceProvider;
+ uno::Reference< io::XDataOutputStream > m_xDataOutputStream;
+
+ public:
+ BinaryWriter(rtl::OUString const& m_aFilename, uno::Reference<lang::XMultiServiceFactory> const& _rxServiceProvider);
+
+ ~BinaryWriter();
+ bool open() SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void close() SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ // Type writer
+ void write(sal_Bool _bValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void write(sal_Int8 _nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void write(sal_Int16 _nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void write(sal_Int32 _nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void write(sal_Int64 _nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void write(double _nValue) SAL_THROW( (io::IOException, uno::RuntimeException) );
+ void write(rtl::OUString const& _aStr) SAL_THROW( (io::IOException, uno::RuntimeException) );
+
+ };
+ } //namespace backend
+} // namespace configmgr
+
+#endif
diff --git a/configmgr/source/backend/componentdatahelper.cxx b/configmgr/source/backend/componentdatahelper.cxx
new file mode 100644
index 000000000000..3f2c2002b2e3
--- /dev/null
+++ b/configmgr/source/backend/componentdatahelper.cxx
@@ -0,0 +1,617 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: componentdatahelper.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "componentdatahelper.hxx"
+#include "treenodefactory.hxx"
+#include "typeconverter.hxx"
+#include "strdecl.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/container/ElementExistException.hpp>
+#include <com/sun/star/beans/IllegalTypeException.hpp>
+#include <com/sun/star/beans/PropertyExistException.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+
+// -----------------------------------------------------------------------------
+#define OUSTR( str ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(str) )
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace beans = ::com::sun::star::beans;
+ namespace container = ::com::sun::star::container;
+// -----------------------------------------------------------------------------
+
+DataBuilderContext::DataBuilderContext( uno::Reference< uno::XComponentContext > const & xContext )
+: m_aLogger(xContext)
+, m_aParentStack()
+, m_aActiveComponent()
+, m_pContext()
+, m_aExpectedComponentName(rtl::OUString())
+{
+
+}
+// -----------------------------------------------------------------------------
+
+DataBuilderContext::DataBuilderContext( uno::Reference< uno::XComponentContext > const & xContext, uno::XInterface * _pContext, ITemplateDataProvider* aTemplateProvider )
+: m_aLogger(xContext)
+, m_aParentStack()
+, m_aActiveComponent()
+, m_pContext(_pContext)
+, m_aExpectedComponentName()
+, m_aTemplateProvider( aTemplateProvider )
+{
+
+}
+// -----------------------------------------------------------------------------
+
+DataBuilderContext::DataBuilderContext( uno::Reference< uno::XComponentContext > const & xContext, uno::XInterface * _pContext, const rtl::OUString& aExpectedComponentName, ITemplateDataProvider* aTemplateProvider )
+: m_aLogger(xContext)
+, m_aParentStack()
+, m_aActiveComponent()
+, m_pContext(_pContext)
+, m_aExpectedComponentName( aExpectedComponentName )
+, m_aTemplateProvider( aTemplateProvider )
+{
+
+}
+// -----------------------------------------------------------------------------
+
+DataBuilderContext::DataBuilderContext(DataBuilderContext const & aBaseContext, uno::XInterface * _pContext)
+: m_aLogger(aBaseContext.m_aLogger)
+, m_aParentStack()
+, m_aActiveComponent()
+, m_pContext(_pContext)
+, m_aExpectedComponentName()
+, m_aTemplateProvider( aBaseContext.m_aTemplateProvider )
+{
+
+}
+// -----------------------------------------------------------------------------
+
+DataBuilderContext::~DataBuilderContext( )
+{
+
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::raiseMalformedDataException(sal_Char const * _pText) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException, com::sun::star::uno::RuntimeException))
+{
+ rtl::OUString const sMessage = makeMessageWithPath(_pText);
+ m_aLogger.error(sMessage,"parse","configmgr::backend::DataBuilder");
+ throw backenduno::MalformedDataException(sMessage, m_pContext, uno::Any());
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::raiseIllegalTypeException(sal_Char const * _pText) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException, com::sun::star::uno::RuntimeException))
+{
+ rtl::OUString const sMessage = makeMessageWithPath(_pText);
+ beans::IllegalTypeException e(sMessage, m_pContext);
+
+ rtl::OUString const sFullMessage = OUSTR("Illegal Type: ").concat(sMessage);
+ m_aLogger.error(sFullMessage,"parse","configmgr::backend::DataBuilder");
+ throw backenduno::MalformedDataException(sFullMessage, m_pContext, uno::makeAny(e));
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::raiseIllegalArgumentException(sal_Char const * _pText, sal_Int16 _nPos) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ rtl::OUString const sMessage = makeMessageWithPath(_pText);
+ lang::IllegalArgumentException e(sMessage, m_pContext, _nPos);
+
+ rtl::OUString const sFullMessage = OUSTR("Illegal Argument: ").concat(sMessage);
+ m_aLogger.error(sFullMessage,"parse","configmgr::backend::DataBuilder");
+ throw backenduno::MalformedDataException(sFullMessage, m_pContext, uno::makeAny(e));
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::raiseNoSuchElementException(sal_Char const * _pText, rtl::OUString const & _sElement) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ rtl::OUString const sMessage = makeMessageWithName(_pText,_sElement);
+ container::NoSuchElementException e(sMessage, m_pContext);
+
+ rtl::OUString const sFullMessage = OUSTR("No Such Node: ").concat(sMessage);
+ m_aLogger.error(sFullMessage,"parse","configmgr::backend::DataBuilder");
+ throw backenduno::MalformedDataException(sFullMessage, m_pContext, uno::makeAny(e));
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::raiseElementExistException(sal_Char const * _pText, rtl::OUString const & _sElement) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ rtl::OUString const sMessage = makeMessageWithName(_pText,_sElement);
+ container::ElementExistException e(sMessage, m_pContext);
+
+ rtl::OUString const sFullMessage = OUSTR("Node Already Exists: ").concat(sMessage);
+ m_aLogger.error(sFullMessage,"parse","configmgr::backend::DataBuilder");
+ throw backenduno::MalformedDataException(sFullMessage, m_pContext, uno::makeAny(e));
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::raisePropertyExistException(sal_Char const * _pText, rtl::OUString const & _sElement) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ rtl::OUString const sMessage = makeMessageWithName(_pText,_sElement);
+ beans::PropertyExistException e(sMessage, m_pContext);
+
+ rtl::OUString const sFullMessage = OUSTR("No Such Property: ").concat(sMessage);
+ m_aLogger.error(sFullMessage,"parse","configmgr::backend::DataBuilder");
+ throw backenduno::MalformedDataException(sFullMessage, m_pContext, uno::makeAny(e));
+}
+// -----------------------------------------------------------------------------
+
+rtl::OUString DataBuilderContext::makeMessageWithPath(sal_Char const * _pText) const
+ SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii(_pText);
+
+ sMessage.appendAscii(" [@").append(getNodeParentagePath()).appendAscii("] ");
+
+ return sMessage.makeStringAndClear();
+}
+// -----------------------------------------------------------------------------
+
+rtl::OUString DataBuilderContext::makeMessageWithName(sal_Char const * _pText, rtl::OUString const & _aName) const
+ SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii(_pText);
+
+ if (_aName.getLength() != 0)
+ sMessage.appendAscii(" [").append(getNodePath(_aName)).appendAscii("] ");
+ else
+ sMessage.appendAscii(" [@").append(getNodeParentagePath()).appendAscii("] ");
+
+ return sMessage.makeStringAndClear();
+}
+// -----------------------------------------------------------------------------
+const sal_Unicode k_pathsep = '/';
+
+rtl::OUString DataBuilderContext::getNodeParentagePath() const
+{
+ rtl::OUStringBuffer path;
+
+ for (Stack< ISubtree * >::bottomup_iterator it = m_aParentStack.begin_up();
+ it != m_aParentStack.end_up(); ++it)
+ {
+ OSL_ASSERT(*it);
+ path.append(k_pathsep).append((**it).getName());
+ }
+
+ return path.makeStringAndClear();
+}
+// -----------------------------------------------------------------------------
+
+rtl::OUString DataBuilderContext::getNodePath(rtl::OUString const & aNodeName) const
+{
+ rtl::OUStringBuffer path( getNodeParentagePath() );
+
+ path.append(k_pathsep).append(aNodeName);
+
+ return path.makeStringAndClear();
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+bool DataBuilderContext::isDone() const
+{
+ OSL_ENSURE(m_aParentStack.empty() || hasActiveComponent(),"DataBuilderContext:Inconsistent Activity state");
+
+ return m_aParentStack.empty();
+}
+// -----------------------------------------------------------------------------
+
+ISubtree & DataBuilderContext::implGetCurrentParent() const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ if (m_aParentStack.empty())
+ raiseMalformedDataException("Invalid Component Data: Operation requires open parent node.");
+
+ OSL_ENSURE( m_aParentStack.top(), "NULL tree on node-stack" );
+
+ return *m_aParentStack.top();
+}
+// -----------------------------------------------------------------------------
+
+bool DataBuilderContext::isWritable(INode const * pNode) const
+ SAL_THROW(())
+{
+ OSL_PRECOND(pNode,"Unexpected NULL node pointer");
+ return pNode->getAttributes().isWritable();
+
+}
+// -----------------------------------------------------------------------------
+
+bool DataBuilderContext::isRemovable(ISubtree const * pItem) const
+ SAL_THROW(())
+{
+ OSL_PRECOND(pItem,"Unexpected NULL item pointer");
+ return pItem->getAttributes().isRemovable();
+}
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+rtl::OUString DataBuilderContext::getTemplateComponent( const backenduno::TemplateIdentifier& aItemType ) const
+{
+ if (aItemType.Component.getLength() != 0)
+ return aItemType.Component;
+
+ else
+ return getActiveComponent();
+}
+// -----------------------------------------------------------------------------
+
+backenduno::TemplateIdentifier DataBuilderContext::completeComponent( const backenduno::TemplateIdentifier& aItemType ) const
+{
+ backenduno::TemplateIdentifier aComplete(aItemType);
+ if (aComplete.Component.getLength() == 0)
+ aComplete.Component = getActiveComponent();
+
+ return aComplete;
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+backenduno::TemplateIdentifier DataBuilderContext::getCurrentItemType() const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ ISubtree const * pCurrentSet = getCurrentParent().asISubtree();
+ if (!pCurrentSet || !pCurrentSet->isSetNode())
+ raiseMalformedDataException("Component Builder Context: Cannot add/replace node - context is not a set");
+
+ backenduno::TemplateIdentifier aCompleteType;
+
+ aCompleteType.Name = pCurrentSet->getElementTemplateName();
+ aCompleteType.Component = pCurrentSet->getElementTemplateModule();
+
+ return aCompleteType;
+}
+// -----------------------------------------------------------------------------
+
+backenduno::TemplateIdentifier DataBuilderContext::getValidItemType(backenduno::TemplateIdentifier const & aItemType) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ ISubtree const * pCurrentSet = getCurrentParent().asISubtree();
+ if (!pCurrentSet || !pCurrentSet->isSetNode())
+ raiseMalformedDataException("Component Builder Context: Cannot add/replace node - context is not a set");
+
+ backenduno::TemplateIdentifier aCompleteType = completeComponent( aItemType );
+
+ // for now only a single item-type is supported
+ if (aCompleteType.Name != pCurrentSet->getElementTemplateName())
+ raiseIllegalTypeException("Component Builder Context: Cannot add/replace node - template is not permitted in containing set");
+
+ if (aCompleteType.Component != pCurrentSet->getElementTemplateModule())
+ raiseIllegalTypeException("Component Builder Context: Cannot add/replace node - template is not permitted in containing set (component mismatch)");
+
+ return aCompleteType;
+}
+// -----------------------------------------------------------------------------
+
+ISubtree * DataBuilderContext::addNodeToCurrent(std::auto_ptr<ISubtree> _aNode)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(_aNode.get(), "ERROR: Adding a NULL node");
+
+ if (this->findChild(_aNode->getName()))
+ raiseElementExistException("Component Builder Context: The node to be added does already exist", _aNode->getName());
+
+ return getCurrentParent().addChild( base_ptr(_aNode) )->asISubtree();
+}
+// -----------------------------------------------------------------------------
+
+ISubtree * DataBuilderContext::addLocalizedToCurrent(std::auto_ptr<ISubtree> _aNode)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(_aNode.get(), "ERROR: Adding a NULL node");
+
+ if (this->findChild(_aNode->getName()))
+ raisePropertyExistException("Component Builder Context: The property to be added does already exist", _aNode->getName());
+
+ return getCurrentParent().addChild( base_ptr(_aNode) )->asISubtree();
+}
+// -----------------------------------------------------------------------------
+
+ValueNode * DataBuilderContext::addPropertyToCurrent(std::auto_ptr<ValueNode> _aNode, bool _bMayReplace)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(_aNode.get(), "ERROR: Adding a NULL node");
+ OSL_PRECOND(!_bMayReplace || _aNode->getAttributes().isReplacedForUser(), "Wrong status for added property");
+
+ if (this->findChild(_aNode->getName()))
+ {
+ // We currently may get a 'replace', when overriding an added property
+ if (_bMayReplace && getCurrentParent().isSetNode())
+ {
+ getCurrentParent().removeChild(_aNode->getName());
+ _aNode->modifyState(node::isReplaced);
+ }
+ else
+
+ raisePropertyExistException("Component Builder Context: The property to be added does already exist", _aNode->getName());
+ }
+ return getCurrentParent().addChild( base_ptr(_aNode) )->asValueNode();
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::markCurrentMerged()
+{
+ Stack< ISubtree * >::topdown_iterator it = m_aParentStack.begin_down(), end = m_aParentStack.end_down();
+ for ( ;it != end && (*it)->isDefault(); ++it)
+ (*it)->modifyState( node::isMerged );
+
+#if OSL_DEBUG_LEVEL > 0
+ for ( ;it != end; ++it)
+ OSL_ENSURE(!(*it)->isDefault(),"Found a default node in ancestry of a merged change");
+#endif
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+bool DataBuilderContext::isProperty(INode * pProp) const
+ SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(pProp, "ERROR: Unexpected NULL node");
+
+ if (pProp == NULL)
+ {
+ rtl::OUString sMsg = makeMessageWithName("INTERNAL ERROR (DataBuilderContext): Trying to inspect NULL node",rtl::OUString() );
+ throw uno::RuntimeException( sMsg, m_pContext );
+ }
+
+ if ( ISubtree * pTree = pProp->asISubtree() )
+ return isLocalizedValueSet( *pTree );
+
+ OSL_ASSERT(dynamic_cast< ValueNode * >(pProp) != 0);
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+INode * DataBuilderContext::findChild(rtl::OUString const & _aName)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ return getCurrentParent().getChild(_aName);
+}
+// -----------------------------------------------------------------------------
+
+INode * DataBuilderContext::findProperty(rtl::OUString const & _aName)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ INode * pResult = findChild(_aName);
+ if (pResult && !isProperty(pResult))
+ {
+ raiseMalformedDataException("Component Builder Context: Found an existing inner node, where a property was expected");
+ }
+ return pResult;
+}
+// -----------------------------------------------------------------------------
+
+ISubtree * DataBuilderContext::findNode(rtl::OUString const & _aName)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ INode * pResult = findChild(_aName);
+
+ if (!pResult)
+ return NULL;
+
+ if (!isNode(pResult))
+ raiseMalformedDataException("Component Builder Context: Found an existing property, where an inner node was expected");
+
+ OSL_ASSERT(dynamic_cast< ISubtree * >(pResult) != 0);
+ return pResult->asISubtree();
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::pushNode(ISubtree * pTree)
+ SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(hasActiveComponent(), "Component Builder Context: Entering a node without having an active component");
+ OSL_PRECOND(pTree, "ERROR: Pushing a NULL tree");
+
+ if (pTree == NULL)
+ {
+ rtl::OUString sMsg = makeMessageWithName("INTERNAL ERROR (DataBuilderContext): Trying to push NULL tree",rtl::OUString() );
+ throw uno::RuntimeException( sMsg, m_pContext );
+ }
+ m_aParentStack.push(pTree);
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::popNode()
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(hasActiveComponent(), "Component Builder Context: Leaving a node without having an active component");
+ if (m_aParentStack.empty())
+ raiseMalformedDataException("Invalid Component Data: Unmatched end of node");
+
+ OSL_ENSURE( m_aParentStack.top(), "NULL tree on node-stack" );
+
+ m_aParentStack.pop();
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::startActiveComponent(rtl::OUString const & _aComponent)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(!hasActiveComponent(), "Component Builder Context: Component is already active");
+ OSL_PRECOND(m_aParentStack.empty(), "Component Builder Context: Starting Component/Template while inside a node");
+
+ if (!m_aParentStack.empty())
+ raiseMalformedDataException("Invalid Component Data: Starting component while node is still open");
+
+ if (m_aExpectedComponentName.getLength()!=0)
+ {
+ if (m_aExpectedComponentName.compareTo ( _aComponent)!= 0 )
+ raiseMalformedDataException("Invalid Component Data: Component name does not match request");
+ }
+ m_aActiveComponent = _aComponent;
+
+ OSL_POSTCOND(hasActiveComponent(), "Component Builder Context: Could not start Component/Template");
+}
+// -----------------------------------------------------------------------------
+
+void DataBuilderContext::endActiveComponent()
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND( hasActiveComponent(), "Component Builder Context: No Component active");
+ OSL_PRECOND(m_aParentStack.empty(), "Component Builder Context: Ending Component/Template while inside a node");
+
+ if (!m_aParentStack.empty())
+ raiseMalformedDataException("Invalid Component Data: Ending component while node is still open");
+
+ m_aActiveComponent = rtl::OUString();
+
+ OSL_POSTCOND(!hasActiveComponent(), "Component Builder Context: Could not end Component/Template");
+}
+// -----------------------------------------------------------------------------
+ResultHolder< TemplateInstance > DataBuilderContext::getTemplateData (TemplateRequest const & _aRequest )
+{
+ return(m_aTemplateProvider->getTemplateData (_aRequest));
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ComponentDataFactory::ComponentDataFactory()
+: m_rNodeFactory( getDefaultTreeNodeFactory() )
+{
+}
+// -----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ComponentDataFactory::createGroup( rtl::OUString const & _aName,
+ bool _bExtensible,
+ node::Attributes const & _aAttributes) const
+{
+ if (_bExtensible)
+ {
+ return getNodeFactory().createSetNode( _aName,
+ toTemplateName(TYPE_ANY,false),
+ TEMPLATE_MODULE_NATIVE_VALUE,
+ _aAttributes );
+ }
+ else
+ {
+ return getNodeFactory().createGroupNode( _aName,
+ _aAttributes );
+ }
+}
+// -----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ComponentDataFactory::createSet(rtl::OUString const & _aName,
+ backenduno::TemplateIdentifier const & _aItemType,
+ bool _bExtensible,
+ node::Attributes const & _aAttributes) const
+{
+ OSL_ENSURE(!_bExtensible, "DataBuilderContext: Unimplemented feature: Extensible Set node");
+ if (_bExtensible)
+ return std::auto_ptr<ISubtree>();
+
+ return getNodeFactory().createSetNode( _aName,
+ _aItemType.Name,
+ _aItemType.Component,
+ _aAttributes );
+}
+// -----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ComponentDataFactory::createLocalizedContainer( rtl::OUString const & _aName,
+ uno::Type const & _aValueType,
+ node::Attributes const & _aAttributes) const
+{
+ node::Attributes aLocalizedAttributes(_aAttributes);
+ aLocalizedAttributes.setLocalized (true);
+
+ return getNodeFactory().createSetNode( _aName,
+ toTemplateName(_aValueType),
+ TEMPLATE_MODULE_LOCALIZED_VALUE,
+ aLocalizedAttributes );
+
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+namespace
+{
+ DECLARE_CONSTASCII_USTRING(INSTANCE_MARKER);
+ IMPLEMENT_CONSTASCII_USTRING(INSTANCE_MARKER, "instantiate@");
+}
+// -----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ComponentDataFactory::createPlaceHolder(rtl::OUString const & _aName,
+ backenduno::TemplateIdentifier const & _aInstanceType) const
+{
+ return getNodeFactory().createSetNode( _aName,
+ INSTANCE_MARKER + _aInstanceType.Name,
+ _aInstanceType.Component,
+ node::Attributes());
+}
+// -----------------------------------------------------------------------------
+
+bool ComponentDataFactory::isInstancePlaceHolder(ISubtree const & _aInstanceTree)
+{
+ return !! _aInstanceTree.getElementTemplateName().match(INSTANCE_MARKER);
+}
+// -----------------------------------------------------------------------------
+
+backenduno::TemplateIdentifier ComponentDataFactory::getInstanceType(ISubtree const & _aInstanceTree)
+{
+ OSL_ENSURE( isInstancePlaceHolder(_aInstanceTree), "Instance placeholder tree expected" );
+
+ backenduno::TemplateIdentifier aResult;
+
+ if (isInstancePlaceHolder(_aInstanceTree))
+ {
+ aResult.Name = _aInstanceTree.getElementTemplateName().copy( INSTANCE_MARKER.getLength() );
+ aResult.Component = _aInstanceTree.getElementTemplateModule();
+ }
+
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/componentdatahelper.hxx b/configmgr/source/backend/componentdatahelper.hxx
new file mode 100644
index 000000000000..da342183601c
--- /dev/null
+++ b/configmgr/source/backend/componentdatahelper.hxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: componentdatahelper.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */
+
+#ifndef CONFIGMGR_BACKEND_COMPONENTDATAHELPER_HXX
+#define CONFIGMGR_BACKEND_COMPONENTDATAHELPER_HXX
+
+#include "valuenode.hxx"
+#include "utility.hxx"
+#include "stack.hxx"
+#include <com/sun/star/configuration/backend/TemplateIdentifier.hpp>
+#include <com/sun/star/configuration/backend/MalformedDataException.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+#include "mergeddataprovider.hxx"
+#ifndef CONFIGMGR_LOGGER_HXX_
+#include "logger.hxx"
+#endif
+#include "request.hxx"
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ class OTreeNodeFactory;
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+
+// -----------------------------------------------------------------------------
+
+ class DataBuilderContext
+ {
+ Logger m_aLogger;
+ Stack< ISubtree * > m_aParentStack;
+ rtl::OUString m_aActiveComponent;
+ uno::XInterface * m_pContext;
+ rtl::OUString m_aExpectedComponentName;
+ ITemplateDataProvider * m_aTemplateProvider;
+ public:
+ explicit DataBuilderContext(uno::Reference< uno::XComponentContext > const & xContext);
+ DataBuilderContext(uno::Reference< uno::XComponentContext > const & xContext, uno::XInterface * _pContext , ITemplateDataProvider* aTemplateProvider = NULL);
+ DataBuilderContext(uno::Reference< uno::XComponentContext > const & xContext, uno::XInterface * _pContext, const rtl::OUString& aExpectedComponentName,ITemplateDataProvider* aTemplateProvider = NULL );
+ DataBuilderContext(DataBuilderContext const & aBaseContext, uno::XInterface * _pContext);
+ ~DataBuilderContext();
+
+ bool isDone() const;
+
+ bool hasActiveComponent() const { return m_aActiveComponent.getLength() != 0; }
+ rtl::OUString getActiveComponent() const { return m_aActiveComponent; }
+
+ ISubtree & getCurrentParent()
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+ { return implGetCurrentParent(); }
+
+ ISubtree const & getCurrentParent() const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+ { return implGetCurrentParent(); }
+
+ node::Attributes getCurrentAttributes() const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+ { return implGetCurrentParent().getAttributes(); }
+
+ ITemplateDataProvider * getTemplateProvider() const
+ { return m_aTemplateProvider; }
+
+ rtl::OUString getTemplateComponent(backenduno::TemplateIdentifier const & aItemType ) const;
+
+ backenduno::TemplateIdentifier completeComponent(backenduno::TemplateIdentifier const & aItemType ) const;
+
+ backenduno::TemplateIdentifier getCurrentItemType() const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ backenduno::TemplateIdentifier getValidItemType(backenduno::TemplateIdentifier const & aItemType) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void startActiveComponent(rtl::OUString const & _aComponent)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ void endActiveComponent()
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ bool isProperty(INode * pProp) const
+ SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ bool isNode(INode * pNode) const SAL_THROW((com::sun::star::uno::RuntimeException))
+ { return !isProperty(pNode); }
+
+ void pushNode(ISubtree * pTree)
+ SAL_THROW((com::sun::star::uno::RuntimeException));
+ void popNode()
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ INode * findProperty(rtl::OUString const & _aName)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ ISubtree * findNode(rtl::OUString const & _aName)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ bool isWritable(INode const * pNode) const
+ SAL_THROW(());
+ bool isRemovable(ISubtree const * pItem) const
+ SAL_THROW(());
+
+ ISubtree * addNodeToCurrent(std::auto_ptr<ISubtree> _aNode)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ ISubtree * addLocalizedToCurrent(std::auto_ptr<ISubtree> _aNode)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ ValueNode * addPropertyToCurrent(std::auto_ptr<ValueNode> _aNode, bool _bMayReplace = false)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void markCurrentMerged();
+
+ // Logging support
+ Logger const & getLogger() const { return m_aLogger; }
+
+ rtl::OUString getNodeParentagePath() const;
+ rtl::OUString getNodePath(rtl::OUString const & aNodeName) const;
+
+ // Exception support
+ void raiseMalformedDataException (sal_Char const * _pText) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ void raiseIllegalArgumentException (sal_Char const * _pText, sal_Int16 _nPos = 0) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ void raiseElementExistException (sal_Char const * _pText, rtl::OUString const & _sElement) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ void raiseNoSuchElementException (sal_Char const * _pText, rtl::OUString const & _sElement) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ void raisePropertyExistException (sal_Char const * _pText, rtl::OUString const & _sElement) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ void raiseIllegalTypeException (sal_Char const * _pText) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ ResultHolder< TemplateInstance > getTemplateData (TemplateRequest const & _aRequest );
+ private:
+ INode * findChild(rtl::OUString const & _aName)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ rtl::OUString makeMessageWithPath(sal_Char const * _pText) const
+ SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ rtl::OUString makeMessageWithName(sal_Char const * _pText, rtl::OUString const & _aName) const
+ SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ ISubtree & implGetCurrentParent() const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ };
+// -----------------------------------------------------------------------------
+
+ class ComponentDataFactory
+ {
+ OTreeNodeFactory & m_rNodeFactory;
+ public:
+ ComponentDataFactory();
+
+ ComponentDataFactory(OTreeNodeFactory & _rNodeFactory)
+ : m_rNodeFactory(_rNodeFactory)
+ {}
+
+ public:
+ OTreeNodeFactory& getNodeFactory() const { return m_rNodeFactory; }
+
+ std::auto_ptr<ISubtree> createGroup(rtl::OUString const & _aName,
+ bool _bExtensible,
+ node::Attributes const & _aAttributes) const;
+
+ std::auto_ptr<ISubtree> createSet( rtl::OUString const & _aName,
+ backenduno::TemplateIdentifier const & aItemType,
+ bool _bExtensible,
+ node::Attributes const & _aAttributes) const;
+
+ std::auto_ptr<ISubtree> createLocalizedContainer(rtl::OUString const & _aName,
+ uno::Type const & _aValueType,
+ node::Attributes const & _aAttributes) const;
+
+ std::auto_ptr<ISubtree> createPlaceHolder(rtl::OUString const & _aName,
+ backenduno::TemplateIdentifier const & _aInstanceType) const;
+
+ static bool isInstancePlaceHolder(ISubtree const & _aInstanceTree);
+ static backenduno::TemplateIdentifier getInstanceType(ISubtree const & _aInstanceTree);
+ };
+// -----------------------------------------------------------------------------
+ } // namespace backend
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/emptylayer.cxx b/configmgr/source/backend/emptylayer.cxx
new file mode 100644
index 000000000000..50505763d297
--- /dev/null
+++ b/configmgr/source/backend/emptylayer.cxx
@@ -0,0 +1,228 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: emptylayer.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "emptylayerimpl.hxx"
+#include "emptylayer.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ // -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+
+ uno::Reference< backenduno::XLayer > createEmptyLayer()
+ {
+ return new EmptyLayer();
+ }
+ // -----------------------------------------------------------------------------
+
+ bool checkEmptyLayer(uno::Reference< backenduno::XLayer > const & xLayer )
+ {
+ OSL_ENSURE(xLayer.is(),"Unexpected NULL Layer");
+ if (!xLayer.is()) return false;
+
+ RequireEmptyLayer * const pChecker = new RequireEmptyLayer;
+ uno::Reference< backenduno::XLayerHandler > xChecker(pChecker);
+
+ try
+ {
+ xLayer->readData(xChecker);
+ }
+ catch (uno::Exception &)
+ {
+ OSL_ENSURE(!pChecker->wasEmpty(), "Checking for empty layer: exception occurred after empty layer was ended");
+ }
+
+ return pChecker->wasEmpty();
+ }
+
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+
+ EmptyLayer::~EmptyLayer( )
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL
+ EmptyLayer::readData( const uno::Reference< backenduno::XLayerHandler >& aHandler )
+ throw (backenduno::MalformedDataException, lang::NullPointerException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if (aHandler.is())
+ {
+ aHandler->startLayer();
+ aHandler->endLayer();
+ }
+ else
+ throw lang::NullPointerException(rtl::OUString::createFromAscii("EmptyLayer: Null Handler"),*this);
+ }
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+
+ RequireEmptyLayer::RequireEmptyLayer()
+ : m_bStarted(false)
+ , m_bInvalid(false)
+ , m_bEmpty(false)
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ RequireEmptyLayer::~RequireEmptyLayer( )
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::startLayer( )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ m_bInvalid = false;
+ m_bEmpty = false;
+
+ if (m_bStarted) fail("Layer started twice");
+ m_bStarted = true;
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::endLayer( )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ if (!m_bStarted) fail("Layer was not started");
+ m_bEmpty = !m_bInvalid;
+ m_bStarted = false;
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::overrideNode( const rtl::OUString& /*aName*/, sal_Int16 /*aAttributes*/, sal_Bool /*bClear*/ )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::addOrReplaceNode( const rtl::OUString& /*aName*/, sal_Int16 /*aAttributes*/ )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::addOrReplaceNodeFromTemplate( const rtl::OUString& /*aName*/, const backenduno::TemplateIdentifier& /*aTemplate*/, sal_Int16 /*aAttributes*/)
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::endNode( )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::dropNode( const rtl::OUString& /*aName*/ )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::addProperty( const rtl::OUString& /*aName*/, sal_Int16 /*aAttributes*/, const uno::Type& /*aType*/ )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::addPropertyWithValue( const rtl::OUString& /*aName*/, sal_Int16 /*aAttributes*/, const uno::Any& /*aValue*/ )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::overrideProperty( const rtl::OUString& /*aName*/, sal_Int16 /*aAttributes*/, const uno::Type& /*aType*/, sal_Bool /*bClear*/ )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::endProperty( )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::setPropertyValue( const uno::Any& /*aValue*/ )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL RequireEmptyLayer::setPropertyValueForLocale( const uno::Any& /*aValue*/, const rtl::OUString& /*aLocale*/ )
+ throw (backenduno::MalformedDataException, uno::RuntimeException)
+ {
+ failNotEmpty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void RequireEmptyLayer::fail(sal_Char const * pMsg)
+ {
+ if (!m_bStarted & !m_bInvalid) pMsg = "Layer was not started";
+ m_bInvalid = true;
+ m_bStarted = false;
+
+ OSL_ASSERT(pMsg);
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+
+ throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
+ }
+
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------
+ } // namespace
+
+ // -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/emptylayerimpl.hxx b/configmgr/source/backend/emptylayerimpl.hxx
new file mode 100644
index 000000000000..a6f2aa1197e8
--- /dev/null
+++ b/configmgr/source/backend/emptylayerimpl.hxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: emptylayerimpl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_EMPTYLAYERIMPL_HXX
+#define CONFIGMGR_BACKEND_EMPTYLAYERIMPL_HXX
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ // -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+ // -----------------------------------------------------------------------------
+
+ class EmptyLayer : public cppu::WeakImplHelper1<backenduno::XLayer>
+ {
+ public:
+ virtual ~EmptyLayer();
+
+ // XLayer
+ public:
+ virtual void SAL_CALL
+ readData( const uno::Reference< backenduno::XLayerHandler >& aHandler )
+ throw (backenduno::MalformedDataException, lang::NullPointerException, lang::WrappedTargetException, uno::RuntimeException);
+ };
+ // -----------------------------------------------------------------------------
+
+ class RequireEmptyLayer : public cppu::WeakImplHelper1<backenduno::XLayerHandler>
+ {
+ public:
+ RequireEmptyLayer();
+ virtual ~RequireEmptyLayer();
+
+ bool wasEmpty() const { return m_bEmpty; }
+ bool wasInvalid() const { return m_bInvalid; }
+ // XLayerHandler
+ public:
+ virtual void SAL_CALL
+ startLayer( )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endLayer( )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endProperty( )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, uno::RuntimeException);
+
+ private:
+ void failNotEmpty() { fail("layer is not empty"); }
+ void fail(sal_Char const * pMsg);
+
+ private:
+ bool m_bStarted;
+ bool m_bInvalid;
+ bool m_bEmpty;
+ };
+ // -----------------------------------------------------------------------------
+ } // namespace xml
+ // -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
diff --git a/configmgr/source/backend/importmergehandler.cxx b/configmgr/source/backend/importmergehandler.cxx
new file mode 100644
index 000000000000..9267292d666d
--- /dev/null
+++ b/configmgr/source/backend/importmergehandler.cxx
@@ -0,0 +1,299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: importmergehandler.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "importmergehandler.hxx"
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <rtl/ustrbuf.hxx>
+
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace beans = ::com::sun::star::beans;
+
+// -----------------------------------------------------------------------------
+
+ImportMergeHandler::ImportMergeHandler(
+ uno::Reference< backenduno::XBackend > const & xTargetBackend, Mode mode, rtl::OUString const & aEntity, sal_Bool const & bNotify )
+: BasicImportHandler(xTargetBackend,aEntity, bNotify)
+, m_xOutputHandler()
+, m_mode(mode)
+{
+}
+// -----------------------------------------------------------------------------
+
+void ImportMergeHandler::failNotStarted()
+{
+ OSL_ENSURE(!hasComponent(), "Import handler after failure to create output handler or after closing");
+ raiseMalformedDataException("configmgr::backend::ImportHandler: Trying to generate output before identifying the target component");
+}
+// -----------------------------------------------------------------------------
+
+inline bool ImportMergeHandler::isStarted() const
+{
+ return !! m_xOutputHandler.is();
+}
+// -----------------------------------------------------------------------------
+
+inline void ImportMergeHandler::checkStarted()
+{
+ if (!isStarted()) failNotStarted();
+}
+// -----------------------------------------------------------------------------
+
+inline uno::Reference< backenduno::XUpdateHandler > ImportMergeHandler::getOutputHandler()
+{
+ checkStarted();
+ return m_xOutputHandler;
+}
+// -----------------------------------------------------------------------------
+
+static
+bool setHandlerProperty(uno::Reference< uno::XInterface > const & xHandler, char const * property, sal_Bool value)
+{
+ OSL_ASSERT(property);
+ uno::Reference< lang::XInitialization > xInitHandler( xHandler, uno::UNO_QUERY );
+ if (xHandler.is())
+ try
+ {
+ uno::Sequence< uno::Any > aArgs(1);
+ aArgs[0] <<= beans::NamedValue( rtl::OUString::createFromAscii(property), uno::makeAny(value) );
+ xInitHandler->initialize(aArgs);
+ return true;
+ }
+ catch (uno::Exception & e)
+ {
+ OSL_TRACE("Configuration Import Handler - Could not set output handler property '%s': %s\n",
+ property,rtl::OUStringToOString(e.Message,RTL_TEXTENCODING_ASCII_US).getStr());
+
+ OSL_ENSURE(false, "Output Handler does not support expected property" );
+ }
+ else
+ {
+ OSL_TRACE("Configuration Import Handler - Could not set output handler property '%s': %s\n",
+ property,"Object does not support expected interface");
+
+ OSL_ENSURE(false, "Output Handler does not support expected interface" );
+ }
+ return false;
+}
+// -----------------------------------------------------------------------------
+uno::Reference< backenduno::XUpdateHandler > ImportMergeHandler::createOutputHandler()
+{
+ OSL_PRECOND( hasComponent(), "Trying to create output-handler for Import Merger without setting a component first") ;
+ rtl::OUString const aComponentName = this->getComponent();
+
+ uno::Reference< backenduno::XUpdateHandler > xOutputHandler;
+ try
+ {
+ xOutputHandler = hasEntity() ? getBackend()->getUpdateHandler(aComponentName,getEntity())
+ : getBackend()->getOwnUpdateHandler(aComponentName);
+ }
+ catch (lang::NoSupportException & e)
+ {
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("configmgr::backend::ImportHandler: ");
+ sMessage.appendAscii("Could not get output handler for component ").append(aComponentName);
+ sMessage.appendAscii(": Backend does not support updates - ").append( e.Message );
+
+ throw lang::WrappedTargetException(sMessage.makeStringAndClear(), *this, uno::makeAny(e));
+ }
+ catch (lang::IllegalArgumentException & e)
+ {
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("configmgr::backend::ImportHandler: ");
+ sMessage.appendAscii("Could not get output handler for component ").append(aComponentName);
+ sMessage.appendAscii(" due to a backend exception: ").append( e.Message );
+
+ throw lang::WrappedTargetException(sMessage.makeStringAndClear(), *this, uno::makeAny(e));
+ }
+
+ if (!xOutputHandler.is())
+ {
+ rtl::OUStringBuffer sMessage;
+ sMessage.appendAscii("configmgr::backend::ImportHandler: ");
+ sMessage.appendAscii("Cannot import. ERROR - The backend returns a NULL handler for component ")
+ .append(aComponentName).append( sal_Unicode('.') );
+
+ throw uno::RuntimeException(sMessage.makeStringAndClear(), *this);
+ }
+
+ switch (m_mode)
+ {
+ case merge: break;
+ case copy: setHandlerProperty(xOutputHandler,"Truncate", sal_True); break;
+ case no_overwrite: setHandlerProperty(xOutputHandler,"Overwrite",sal_False); break;
+
+ default: OSL_ASSERT(false); break;
+ }
+
+ return xOutputHandler;
+}
+// -----------------------------------------------------------------------------
+
+// XLayerHandler
+
+void SAL_CALL ImportMergeHandler::startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ m_xOutputHandler.clear();
+
+ BasicImportHandler::startLayer();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (isStarted())
+ try
+ {
+ getOutputHandler()->endUpdate();
+ }
+ catch (lang::IllegalAccessException & iae)
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM("ImportHandler - no write access to layer: "));
+ throw lang::WrappedTargetException(sMsg.concat(iae.Message),*this,uno::makeAny(iae));
+ }
+
+ BasicImportHandler::endLayer();
+ m_xOutputHandler.clear();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!isStarted() && startComponent(aName))
+ try
+ {
+ (m_xOutputHandler = createOutputHandler())->startUpdate( );
+ }
+ catch (lang::IllegalAccessException & iae)
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM("ImportHandler - no write access to layer: "));
+ throw lang::WrappedTargetException(sMsg.concat(iae.Message),*this,uno::makeAny(iae));
+ }
+
+ OSL_ENSURE(!bClear,"'clear' operation not supported properly on import");
+
+ bool bReset = (m_mode != merge) || bClear; // is not relevant for no_overwrite,but might be cheaper there
+ getOutputHandler()->modifyNode(aName,aAttributes,aAttributes,bReset);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->addOrReplaceNode(aName,aAttributes);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->addOrReplaceNodeFromTemplate(aName,aAttributes,aTemplate);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->endNode();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->removeNode(aName);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ (void) bClear; // avoid warning about unused parameter
+ OSL_ENSURE(!bClear,"'clear' operation not supported on import");
+ getOutputHandler()->modifyProperty(aName,aAttributes,aAttributes,aType);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->endProperty();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->setPropertyValue(aValue);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->setPropertyValueForLocale(aValue,aLocale);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->addOrReplaceProperty(aName, aAttributes, aType);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL ImportMergeHandler::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ getOutputHandler()->addOrReplacePropertyWithValue(aName, aAttributes, aValue);
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/importmergehandler.hxx b/configmgr/source/backend/importmergehandler.hxx
new file mode 100644
index 000000000000..43dbc4da4504
--- /dev/null
+++ b/configmgr/source/backend/importmergehandler.hxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: importmergehandler.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_IMPORTMERGEHANDLER_HXX
+#define CONFIGMGR_BACKEND_IMPORTMERGEHANDLER_HXX
+
+#include "basicimporthandler.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+ class ImportMergeHandler : public BasicImportHandler
+ {
+ public:
+ enum Mode
+ {
+ merge, // merge as update into existing data
+ copy, // reset existing data first -> copy imported data
+ no_overwrite // copy/merge only if no data is in the layer
+ };
+
+ explicit
+ ImportMergeHandler(uno::Reference< backenduno::XBackend > const & xTargetBackend, Mode mode,
+ rtl::OUString const & aEntity = rtl::OUString(), sal_Bool const & bNotify = sal_False);
+
+ // XLayerHandler
+ protected:
+ virtual void SAL_CALL
+ startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+ private:
+ bool isStarted() const;
+ void checkStarted();
+ void failNotStarted();
+
+ uno::Reference< backenduno::XUpdateHandler > getOutputHandler();
+
+ uno::Reference< backenduno::XUpdateHandler > createOutputHandler();
+ private:
+ uno::Reference< backenduno::XUpdateHandler > m_xOutputHandler;
+ Mode m_mode;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/importsvc.cxx b/configmgr/source/backend/importsvc.cxx
new file mode 100644
index 000000000000..d6eb9a2575b8
--- /dev/null
+++ b/configmgr/source/backend/importsvc.cxx
@@ -0,0 +1,338 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: importsvc.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "importsvc.hxx"
+#include "importmergehandler.hxx"
+#include "backendfactory.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include <com/sun/star/beans/NamedValue.hpp>
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace beans = ::com::sun::star::beans;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+sal_Char const * const aMergeImporterServices[] =
+{
+ "com.sun.star.configuration.backend.MergeImporter",
+ 0,
+ "com.sun.star.configuration.backend.Importer",
+ 0
+};
+const ServiceImplementationInfo aMergeImporterSI =
+{
+ "com.sun.star.comp.configuration.backend.MergeImporter",
+ aMergeImporterServices, aMergeImporterServices + 2
+};
+// -----------------------------------------------------------------------------
+
+const ServiceRegistrationInfo* getMergeImportServiceInfo()
+{ return getRegistrationInfo(& aMergeImporterSI); }
+// -----------------------------------------------------------------------------
+
+MergeImportService::MergeImportService(uno::Reference< uno::XComponentContext > const & _xContext)
+: ImportService(_xContext, &aMergeImporterSI)
+{
+}
+// -----------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > SAL_CALL instantiateMergeImporter
+( uno::Reference< uno::XComponentContext > const& xContext )
+{
+ return * new MergeImportService( xContext );
+}
+// -----------------------------------------------------------------------------
+
+uno::Reference< backenduno::XLayerHandler > MergeImportService::createImportHandler(uno::Reference< backenduno::XBackend > const & xBackend, rtl::OUString const & aEntity)
+{
+ if (!xBackend.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("configmgr::backend::ImportService: Trying to import without a backend. No default backend could be created") );
+ throw lang::NullPointerException(sMessage,*this);
+ }
+
+ uno::Reference< backenduno::XLayerHandler > aHandler( new ImportMergeHandler(xBackend, ImportMergeHandler::merge, aEntity, m_bSendNotification) );
+
+ return aHandler;
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+sal_Char const * const aCopyImporterServices[] =
+{
+ "com.sun.star.configuration.backend.CopyImporter",
+ 0,
+ "com.sun.star.configuration.backend.Importer",
+ 0
+};
+const ServiceImplementationInfo aCopyImporterSI =
+{
+ "com.sun.star.comp.configuration.backend.CopyImporter",
+ aCopyImporterServices, aCopyImporterServices + 2
+};
+// -----------------------------------------------------------------------------
+
+const ServiceRegistrationInfo* getCopyImportServiceInfo()
+{ return getRegistrationInfo(& aCopyImporterSI); }
+// -----------------------------------------------------------------------------
+
+CopyImportService::CopyImportService(uno::Reference< uno::XComponentContext > const & _xContext)
+: ImportService(_xContext, &aCopyImporterSI)
+{
+}
+// -----------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > SAL_CALL instantiateCopyImporter
+( uno::Reference< uno::XComponentContext > const& xContext )
+{
+ return * new CopyImportService( xContext );
+}
+// -----------------------------------------------------------------------------
+
+uno::Reference< backenduno::XLayerHandler > CopyImportService::createImportHandler(uno::Reference< backenduno::XBackend > const & xBackend, rtl::OUString const & aEntity)
+{
+ if (!xBackend.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("configmgr::backend::ImportService: Trying to import without a backend. No default backend could be created") );
+ throw lang::NullPointerException(sMessage,*this);
+ }
+
+ ImportMergeHandler::Mode aMode = m_bOverwrite ? ImportMergeHandler::copy : ImportMergeHandler::no_overwrite;
+ uno::Reference< backenduno::XLayerHandler > aHandler( new ImportMergeHandler(xBackend,aMode,aEntity) );
+
+ return aHandler;
+}
+// -----------------------------------------------------------------------------
+
+sal_Bool CopyImportService::setImplementationProperty(rtl::OUString const & aName, uno::Any const & aValue)
+{
+ if (aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Overwrite")))
+ {
+ return (aValue >>= m_bOverwrite);
+ }
+
+ return ImportService::setImplementationProperty(aName,aValue);
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+ImportService::ImportService(uno::Reference< uno::XComponentContext > const & _xContext, ServiceInfoHelper const & aSvcInfo )
+: m_bSendNotification(false)
+, m_aMutex()
+, m_xContext(_xContext)
+, m_xDestinationBackend()
+, m_aServiceInfo(aSvcInfo)
+{
+ if (!m_xContext.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration Importer: Unexpected NULL context"));
+ throw lang::NullPointerException(sMessage,NULL);
+ }
+}
+// -----------------------------------------------------------------------------
+
+ImportService::~ImportService()
+{}
+// -----------------------------------------------------------------------------
+
+uno::Reference< backenduno::XBackend > ImportService::createDefaultBackend() const
+{
+ return BackendFactory::instance( m_xContext ).getUnoBackend();
+}
+// -----------------------------------------------------------------------------
+
+sal_Bool ImportService::setImplementationProperty(rtl::OUString const & aName, uno::Any const & aValue)
+{
+ if (aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Notify")))
+ {
+ return (aValue >>= m_bSendNotification);
+ }
+
+ return false;
+}
+// -----------------------------------------------------------------------------
+
+// XInitialize
+
+void SAL_CALL
+ ImportService::initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException)
+{
+ sal_Int16 const nCount = static_cast<sal_Int16>(aArguments.getLength());
+
+ if (sal_Int32(nCount) != aArguments.getLength())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Too many arguments to initialize a Configuration Importer"));
+ throw lang::IllegalArgumentException(sMessage,*this,0);
+ }
+
+ for (sal_Int16 i = 0; i < nCount; ++i)
+ {
+ beans::NamedValue aExtraArg;
+ if (aArguments[i] >>= aExtraArg)
+ {
+ OSL_VERIFY( setImplementationProperty(aExtraArg.Name, aExtraArg.Value) );
+
+ continue;
+ }
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Cannot use argument to initialize a Configuration Importer"
+ "- NamedValue expected"));
+ throw lang::IllegalArgumentException(sMessage,*this,i+1);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+// XLayerImporter
+
+uno::Reference< backenduno::XBackend > SAL_CALL
+ ImportService::getTargetBackend( )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< backenduno::XBackend > xRet;
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ xRet = m_xDestinationBackend;
+ }
+
+ if (!xRet.is())
+ {
+ xRet = createDefaultBackend();
+
+ osl::MutexGuard aGuard(m_aMutex);
+ if (!m_xDestinationBackend.is())
+ m_xDestinationBackend = xRet;
+ }
+ return xRet;
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ ImportService::setTargetBackend( const uno::Reference< backenduno::XBackend >& aBackend )
+ throw (lang::NullPointerException, uno::RuntimeException)
+{
+ if (!aBackend.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("configmgr::backend::ImportService: Trying to set a NULL backend") );
+ throw lang::NullPointerException(sMessage,*this);
+ }
+
+ osl::MutexGuard aGuard(m_aMutex);
+ m_xDestinationBackend = aBackend;
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ ImportService::importLayer( const uno::Reference< backenduno::XLayer >& aLayer )
+ throw ( backenduno::MalformedDataException,
+ lang::WrappedTargetException, lang::IllegalArgumentException,
+ lang::NullPointerException, uno::RuntimeException)
+{
+ if (!aLayer.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("configmgr::backend::ImportService: Trying to import a NULL layer") );
+ throw lang::NullPointerException(sMessage,*this);
+ }
+
+ uno::Reference< backenduno::XLayerHandler > aInputHandler = createImportHandler( getTargetBackend() );
+ aLayer->readData( aInputHandler );
+
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ ImportService::importLayerForEntity( const uno::Reference< backenduno::XLayer >& aLayer, const rtl::OUString& aEntity )
+ throw ( backenduno::MalformedDataException,
+ lang::WrappedTargetException, lang::IllegalArgumentException,
+ lang::NullPointerException, uno::RuntimeException)
+{
+ if (!aLayer.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("configmgr::backend::ImportService: Trying to import a NULL layer") );
+ throw lang::NullPointerException(sMessage,*this);
+ }
+
+ uno::Reference< backenduno::XLayerHandler > aInputHandler = createImportHandler( getTargetBackend(), aEntity );
+ aLayer->readData( aInputHandler );
+}
+// -----------------------------------------------------------------------------
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL
+ ImportService::getImplementationName( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getImplementationName( );
+}
+// -----------------------------------------------------------------------------
+
+
+sal_Bool SAL_CALL
+ ImportService::supportsService( const rtl::OUString& ServiceName )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().supportsService( ServiceName );
+}
+// -----------------------------------------------------------------------------
+
+
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ ImportService::getSupportedServiceNames( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getSupportedServiceNames( );
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/importsvc.hxx b/configmgr/source/backend/importsvc.hxx
new file mode 100644
index 000000000000..a76a44fe75d6
--- /dev/null
+++ b/configmgr/source/backend/importsvc.hxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: importsvc.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_IMPORTSVC_HXX
+#define CONFIGMGR_BACKEND_IMPORTSVC_HXX
+
+#include "serviceinfohelper.hxx"
+#include <cppuhelper/implbase3.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/configuration/backend/XLayerImporter.hpp>
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+ class ImportService : public ::cppu::WeakImplHelper3<
+ backenduno::XLayerImporter,
+ lang::XInitialization,
+ lang::XServiceInfo
+ >
+ {
+ public:
+ explicit
+ ImportService(uno::Reference< uno::XComponentContext > const & _xContext, ServiceInfoHelper const & aSvcInfo);
+ ~ImportService();
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& ServiceName )
+ throw (uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException);
+
+ // XLayerImporter
+ virtual uno::Reference< backenduno::XBackend > SAL_CALL
+ getTargetBackend( )
+ throw (uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setTargetBackend( const uno::Reference< backenduno::XBackend >& aBackend )
+ throw (lang::NullPointerException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ importLayer( const uno::Reference< backenduno::XLayer >& aLayer )
+ throw ( backenduno::MalformedDataException,
+ lang::WrappedTargetException, lang::IllegalArgumentException,
+ lang::NullPointerException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ importLayerForEntity( const uno::Reference< backenduno::XLayer >& aLayer, const rtl::OUString& aEntity )
+ throw ( backenduno::MalformedDataException,
+ lang::WrappedTargetException, lang::IllegalArgumentException,
+ lang::NullPointerException, uno::RuntimeException);
+ protected:
+ uno::Reference< backenduno::XBackend > createDefaultBackend() const;
+
+ //uno::Reference< lang::XMultiServiceFactory > getServiceFactory() const
+
+ virtual sal_Bool setImplementationProperty( rtl::OUString const & aName, uno::Any const & aValue);
+ /** Notify backend of import */
+ sal_Bool m_bSendNotification;
+ private:
+ // is pure virtual to allow different import services
+ virtual uno::Reference< backenduno::XLayerHandler > createImportHandler(uno::Reference< backenduno::XBackend > const & xBackend, rtl::OUString const & aEntity = rtl::OUString()) = 0;
+
+ private:
+ osl::Mutex m_aMutex;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ uno::Reference< backenduno::XBackend > m_xDestinationBackend;
+
+
+ ServiceInfoHelper m_aServiceInfo;
+
+ ServiceInfoHelper const & getServiceInfo() const { return m_aServiceInfo; }
+ };
+// -----------------------------------------------------------------------------
+
+ class MergeImportService : public ImportService
+ {
+ public:
+ explicit MergeImportService(uno::Reference< uno::XComponentContext > const & _xContext);
+ private:
+ uno::Reference< backenduno::XLayerHandler > createImportHandler(uno::Reference< backenduno::XBackend > const & xBackend, rtl::OUString const & aEntity);
+ };
+// -----------------------------------------------------------------------------
+
+ class CopyImportService : public ImportService
+ {
+ public:
+ explicit CopyImportService(uno::Reference< uno::XComponentContext > const & _xContext);
+ private:
+ uno::Reference< backenduno::XLayerHandler > createImportHandler(uno::Reference< backenduno::XBackend > const & xBackend, rtl::OUString const & aEntity);
+ sal_Bool setImplementationProperty( rtl::OUString const & aName, uno::Any const & aValue);
+ private:
+ sal_Bool m_bOverwrite;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/layerdefaultremover.cxx b/configmgr/source/backend/layerdefaultremover.cxx
new file mode 100644
index 000000000000..0e6bf73176b4
--- /dev/null
+++ b/configmgr/source/backend/layerdefaultremover.cxx
@@ -0,0 +1,278 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerdefaultremover.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "layerdefaultremover.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ // -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ // -----------------------------------------------------------------------------
+
+ LayerDefaultRemover::LayerDefaultRemover(uno::Reference< backenduno::XLayerHandler > const & _xResultHandler)
+ :m_xResultHandler(_xResultHandler)
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ LayerDefaultRemover::~LayerDefaultRemover( )
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ bool LayerDefaultRemover::hasPendingProperty()
+ {
+ return m_aPropName.Name.getLength()!=0;
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerDefaultRemover::clearPendingProperty()
+ {
+ m_aPropName = PropertyStruct();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ clearPendingProperty();
+ m_xResultHandler->startLayer();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if (hasPendingProperty())
+ {
+ sal_Char const * pMsg =
+ "LayerDefaultRemover: Illegal property started operation";
+ raiseMalformedDataException(pMsg);
+ }
+ if (!m_aNodeStack.empty())
+ {
+ sal_Char const * pMsg =
+ "LayerDefaultRemover: Illegal node started operation";
+ raiseMalformedDataException(pMsg);
+ }
+ m_xResultHandler->endLayer();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if (hasPendingProperty())
+ {
+ sal_Char const * pMsg =
+ "LayerDefaultRemover: Illegal property started operation";
+ raiseMalformedDataException(pMsg);
+ }
+ if (aAttributes == 0 && !bClear)
+ {
+ m_aNodeStack.push_back(aName);
+ }
+ else
+ {
+ playBackNodeStack();
+ m_xResultHandler->overrideNode(aName,aAttributes,bClear);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ playBackNodeStack();
+ m_xResultHandler->addOrReplaceNode(aName, aAttributes);
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ playBackNodeStack();
+ m_xResultHandler->addOrReplaceNodeFromTemplate(aName,aTemplate,aAttributes);
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if (hasPendingProperty())
+ {
+ sal_Char const * pMsg =
+ "LayerDefaultRemover: Illegal property started operation";
+ raiseMalformedDataException(pMsg);
+ }
+ if (m_aNodeStack.empty())
+ {
+ m_xResultHandler->endNode();
+ }
+ else
+ {
+ m_aNodeStack.pop_back();
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ playBackNodeStack();
+ m_xResultHandler->dropNode(aName);
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ playBackNodeStack();
+ m_xResultHandler->addProperty (aName,aAttributes,aType);
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ playBackNodeStack();
+ m_xResultHandler->addPropertyWithValue(aName,aAttributes,aValue);
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if (hasPendingProperty())
+ {
+ sal_Char const * pMsg =
+ "LayerDefaultRemover: Illegal property started operation";
+ raiseMalformedDataException(pMsg);
+ }
+ if (aAttributes != 0 || bClear)
+ {
+ m_aPropName.Name=rtl::OUString();
+ playBackNodeStack();
+ m_xResultHandler->overrideProperty(aName,aAttributes,aType,bClear);
+ }
+ else
+ {
+ m_aPropName.Name = aName;
+ m_aPropName.Type = aType;
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ if (hasPendingProperty())
+ {
+ clearPendingProperty();
+ }
+ else
+ m_xResultHandler->endProperty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ playBackNodeStack(true);
+ m_xResultHandler->setPropertyValue(aValue);
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerDefaultRemover::setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+ {
+ playBackNodeStack(true);
+ m_xResultHandler->setPropertyValueForLocale(aValue,aLocale);
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerDefaultRemover::playBackNodeStack(bool bPlayProperty)
+ {
+ if (!bPlayProperty && hasPendingProperty())
+ {
+ sal_Char const * pMsg =
+ "LayerDefaultRemover: Illegal property started operation";
+ raiseMalformedDataException(pMsg);
+ }
+ if ( !hasPendingProperty() && bPlayProperty && !m_aNodeStack.empty() )
+ {
+ sal_Char const * pMsg =
+ "LayerDefaultRemover: Illegal Operation: Operation requires a started property";
+ raiseMalformedDataException(pMsg);
+ }
+ if (!m_aNodeStack.empty())
+ {
+ for (std::vector<rtl::OUString>::iterator aIter = m_aNodeStack.begin();
+ aIter != m_aNodeStack.end(); aIter++)
+ {
+ m_xResultHandler->overrideNode(*aIter, 0,false);
+ }
+ m_aNodeStack.clear();
+ }
+ if (bPlayProperty)
+ {
+ if (hasPendingProperty())
+ {
+ m_xResultHandler->overrideProperty(m_aPropName.Name,0,m_aPropName.Type,false);
+ clearPendingProperty();
+ }
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerDefaultRemover::raiseMalformedDataException(sal_Char const * pMsg)
+ {
+ OSL_ASSERT(pMsg);
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+
+ throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
+ }
+
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ } // namespace
+
+ // -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/layerdefaultremover.hxx b/configmgr/source/backend/layerdefaultremover.hxx
new file mode 100644
index 000000000000..be0839ab9bb1
--- /dev/null
+++ b/configmgr/source/backend/layerdefaultremover.hxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerdefaultremover.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_LAYERDECORATOR_HXX
+#define CONFIGMGR_XML_LAYERDECORATOR_HXX
+
+#include <cppuhelper/implbase1.hxx>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ // -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+ // -----------------------------------------------------------------------------
+
+ class LayerDefaultRemover : public cppu::WeakImplHelper1<backenduno::XLayerHandler>
+ {
+ public:
+ explicit
+ LayerDefaultRemover(uno::Reference< backenduno::XLayerHandler > const & _xResultHandler);
+ virtual ~LayerDefaultRemover();
+
+ // XLayerHandler
+ public:
+ virtual void SAL_CALL
+ startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ private:
+ void playBackNodeStack( bool bPlayProperty=false);
+ void raiseMalformedDataException(sal_Char const * pMsg);
+ inline bool hasPendingProperty();
+ inline void clearPendingProperty();
+ private:
+ uno::Reference< backenduno::XLayerHandler > m_xResultHandler;
+ std::vector<rtl::OUString> m_aNodeStack;
+ struct PropertyStruct
+ {
+ rtl::OUString Name;
+ uno::Type Type;
+ }m_aPropName;
+ };
+ // -----------------------------------------------------------------------------
+ } // namespace xml
+ // -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
diff --git a/configmgr/source/backend/layermerge.cxx b/configmgr/source/backend/layermerge.cxx
new file mode 100644
index 000000000000..e906d869b5f8
--- /dev/null
+++ b/configmgr/source/backend/layermerge.cxx
@@ -0,0 +1,1039 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layermerge.cxx,v $
+ * $Revision: 1.28 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "layermerge.hxx"
+#include "treenodefactory.hxx"
+#include "matchlocale.hxx"
+#include "valuetypeconverter.hxx"
+#include "typeconverter.hxx"
+#include <com/sun/star/configuration/backend/SchemaAttribute.hpp>
+#include <com/sun/star/configuration/backend/NodeAttribute.hpp>
+
+#include <rtl/ustrbuf.hxx>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+ namespace SchemaAttribute = backenduno::SchemaAttribute;
+ namespace NodeAttribute = backenduno::NodeAttribute;
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//#if OSL_DEBUG_LEVEL > 0
+// currently not used in debug builds
+#if 0
+ static void check_if_complete(uno::Reference< uno::XComponentContext > const & _xContext)
+ {
+ MergedComponentData aData;
+
+ uno::Reference< backenduno::XLayerHandler >
+ test(new LayerMergeHandler(_xContext, aData));
+ }
+#endif
+
+// -----------------------------------------------------------------------------
+
+struct LayerMergeHandler::Converter
+{
+ explicit
+ Converter(uno::Reference< uno::XComponentContext > const & xContext);
+
+ uno::Any convertValue(uno::Type const & _aTargetType, uno::Any const & _aValue);
+
+ static uno::Reference< com::sun::star::script::XTypeConverter > createTCV(uno::Reference< uno::XComponentContext > const & xContext);
+
+ ValueConverter m_aConverter;
+ bool m_bConvertData;
+};
+// -----------------------------------------------------------------------------
+LayerMergeHandler::LayerMergeHandler(uno::Reference< uno::XComponentContext > const & xContext, MergedComponentData & _rData, ITemplateDataProvider* aTemplateProvider )
+: m_rData(_rData)
+//, m_aContext(xContext,static_cast<backenduno::XLayerHandler*>(this),aTemplateProvider )
+, m_aContext(xContext)
+, m_aFactory()
+, m_aLocale()
+, m_pProperty(NULL)
+, m_pConverter( new Converter(xContext) )
+, m_nSkipping(0)
+, m_bSublayer(false)
+{
+ m_aContext = DataBuilderContext(xContext,static_cast<backenduno::XLayerHandler*>(this),aTemplateProvider );
+ OSL_ENSURE( m_rData.hasSchema(), "Creating layer merger without default data" );
+}
+// -----------------------------------------------------------------------------
+
+LayerMergeHandler::~LayerMergeHandler( )
+{
+ delete m_pConverter;
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::prepareLayer()
+{
+ OSL_ENSURE(isDone(), "LayerMergeHandler: Warning: Previous layer or schema not terminated properly");
+ if (!isDone())
+ m_aContext.getLogger().error("Previous layer or schema not terminated properly", "prepareLayer()", "configmgr::LayerMergeHandler");
+
+ m_aLocale = localehelper:: getDefaultLanguage();
+ m_bSublayer = false;
+
+ promoteToDefault(m_rData);
+}
+// -----------------------------------------------------------------------------
+
+bool LayerMergeHandler::prepareSublayer(rtl::OUString const & aLocale)
+{
+ OSL_ENSURE(isDone(), "LayerMergeHandler: Warning: Previous layer not terminated properly");
+ if (!isDone())
+ m_aContext.getLogger().error("Previous layer not terminated properly", "prepareSublayer()", "configmgr::LayerMergeHandler");
+
+ m_aLocale = aLocale;
+ m_bSublayer = (aLocale.getLength() != 0);
+
+ return m_bSublayer;
+}
+// -----------------------------------------------------------------------------
+
+namespace
+{
+ struct CheckRestrictedAccessVisitor : NodeAction
+ {
+ node::Access m_access;
+
+ CheckRestrictedAccessVisitor(node::Access _access) : m_access(_access) {}
+
+ void handle(ValueNode const & _aNode) { check(_aNode); }
+
+ void handle(ISubtree const & _aNode)
+ {
+ node::Access aNext = check(_aNode);
+ CheckRestrictedAccessVisitor(aNext).applyToChildren(_aNode);
+ }
+
+ node::Access check(INode const & _aNode)
+ {
+ node::Attributes const aFoundAttr = _aNode.getAttributes();
+ node::Access const aFoundAccess = aFoundAttr.getAccess();
+ OSL_ENSURE(m_access <= aFoundAccess, "Subnode has more access than its parent");
+
+ return aFoundAccess;
+ }
+ };
+// --------------------
+ struct RestrictAccessVisitor : NodeModification
+ {
+ node::Access m_access;
+
+ RestrictAccessVisitor(bool _bFinalize)
+ : m_access(_bFinalize ? node::accessFinal : node::accessReadonly)
+ {}
+
+ void handle(ValueNode & _aNode) { restrict(_aNode); }
+
+ void handle(ISubtree & _aNode)
+ {
+ if (restrict(_aNode))
+ this->applyToChildren(_aNode);
+ else
+ OSL_DEBUG_ONLY(CheckRestrictedAccessVisitor(m_access).applyToNode(_aNode));
+ }
+
+ bool restrict(INode & _aNode)
+ {
+ node::Attributes const aFoundAttr = _aNode.getAttributes();
+
+ if (aFoundAttr.getAccess() >= m_access) return false; // already restricted enough
+
+ _aNode.modifyAccess(m_access);
+ return true;
+ }
+ };
+}
+// -----------------------------------------------------------------------------
+void LayerMergeHandler::propagateAttributes(ISubtree & _rParent)
+{
+ node::Attributes aAttributes = _rParent.getAttributes();
+
+ if (aAttributes.isReadonly() || aAttributes.isFinalized())
+ RestrictAccessVisitor(aAttributes.isWritable()).applyToChildren(_rParent);
+}
+// -----------------------------------------------------------------------------
+
+node::Attributes LayerMergeHandler::makePropertyAttributes(sal_Int16 aSchemaAttributes)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ const sal_uInt16 k_allPropertySchemaAttributes =
+ SchemaAttribute::REQUIRED;
+
+ if ((aSchemaAttributes & k_allPropertySchemaAttributes) !=
+ (aSchemaAttributes & SchemaAttribute::MASK))
+ {
+ sal_Char const * pMsg = (aSchemaAttributes & SchemaAttribute::LOCALIZED) ?
+ "Layer merging: Cannot add localized property to extensible node" :
+ "Layer merging: Unreckognized Schema Attribute for new Property" ;
+
+ m_aContext.raiseIllegalArgumentException(pMsg,2);
+ }
+ OSL_ASSERT( !(aSchemaAttributes & SchemaAttribute::LOCALIZED) ); // check the check
+
+ node::Attributes aAttributes = m_aContext.getCurrentAttributes();
+
+ if (aSchemaAttributes & SchemaAttribute::REQUIRED)
+ aAttributes.setNullable (false);
+
+ //Set state, removable and mandatory attribute flags
+ aAttributes.setState(node::isAdded);
+ aAttributes.setRemovability(true,true);
+
+
+ return aAttributes;
+
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::checkPropertyType(uno::Type const & _aType)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_ASSERT(m_pProperty);
+
+ if (ValueNode * pValue = m_pProperty->asValueNode())
+ {
+ if (pValue->getValueType() != _aType)
+ {
+ if (pValue->getValueType().getTypeClass() == uno::TypeClass_ANY)
+ {
+ OSL_ENSURE( pValue->isNull(), "Layer merging: Non-null 'any' value" );
+
+ if (_aType != uno::Type())
+ OSL_VERIFY( pValue->setValueType(_aType) );
+
+ else
+ {
+ OSL_TRACE("Layer merging: Illegal property type: VOID overriding ANY");
+ m_aContext.getLogger().warning("Illegal property type: VOID overriding ANY - ignoring",
+ "checkPropertyType()", "configmgr::LayerMergeHandler");
+ // m_aContext.raiseIllegalTypeException("Layer merging: Illegal property type: VOID overriding ANY");
+ }
+ }
+ else if (_aType == uno::Type() && m_pConverter)
+ m_pConverter->m_bConvertData = true;
+
+ else
+ m_aContext.raiseIllegalTypeException("Layer merging: Cannot merge property value: types does not match");
+ }
+ }
+ else if (ISubtree *localisedSet = m_pProperty->asISubtree()) {
+ // We're dealing with localised data.
+ uno::Type valueType = parseTemplateName(
+ localisedSet->getElementTemplateName()) ;
+
+ if (valueType != _aType) {
+ if (valueType.getTypeClass() == uno::TypeClass_ANY) {
+ if (_aType == uno::Type()) {
+ // VOID value
+ m_aContext.raiseIllegalTypeException(
+ "Layer merging: VOID value for localised ANY type") ;
+ }
+ // TODO Could we have to set the localised data type?
+ }
+ else if (_aType == uno::Type() && m_pConverter) {
+ m_pConverter->m_bConvertData = sal_True ;
+ }
+ else {
+ m_aContext.raiseIllegalTypeException("Layer merging: property value does not match localised type") ;
+ }
+ }
+ }
+
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::setValueAndCheck(ValueNode& _rValueNode, uno::Any const & _aValue)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ if (_aValue.hasValue() && m_pConverter && m_pConverter->m_bConvertData)
+ {
+ uno::Any aConvertedValue = m_pConverter->convertValue(_rValueNode.getValueType(),_aValue);
+ if (!aConvertedValue.hasValue())
+ m_aContext.raiseIllegalTypeException("Layer merging: Cannot merge property value: cannot convert data to type of property");
+
+ if (! _rValueNode.setValue(aConvertedValue) )
+ m_aContext.raiseIllegalTypeException("Layer merging: Cannot merge property value: converted type does not match");
+ }
+ else if (! _rValueNode.setValue(_aValue) )
+ {
+ m_aContext.raiseIllegalTypeException("Layer merging: Cannot merge property value: type does not match");
+ }
+
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::setLocalizedValue(ISubtree * pProperty, uno::Any const & _aValue, rtl::OUString const & _aLocale)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ if (ISubtree * pLocalizedCont = pProperty->asISubtree())
+ {
+ OSL_ENSURE(isLocalizedValueSet(*pLocalizedCont),"Layer merging: property node is not a value");
+
+ if (INode * pLocale = pLocalizedCont->getChild(_aLocale))
+ {
+ if (ValueNode * pLocValue = pLocale->asValueNode())
+ {
+ setValueAndCheck(*pLocValue,_aValue);
+ }
+ else
+ {
+ OSL_ENSURE(false,"Layer merging: Localized subnode is not a value");
+ m_aContext.getLogger().error("Localized subnode is not a value - ignoring data",
+ "setLocalizedValue()", "configmgr::LayerMergeHandler");
+ }
+ }
+ else {
+ node::Attributes attributes = pLocalizedCont->getAttributes() ;
+ uno::Type valueType = parseTemplateName(
+ pLocalizedCont->getElementTemplateName()) ;
+
+ attributes.setLocalized(false) ;
+ OSL_ENSURE(valueType != uno::Type(),
+ "Cannot determine type for localised value") ;
+ std::auto_ptr<ValueNode> localisedValue =
+ m_aFactory.getNodeFactory().createNullValueNode(_aLocale,
+ valueType,
+ attributes) ;
+
+ if (_aValue.hasValue()) {
+ setValueAndCheck(*localisedValue, _aValue) ;
+ }
+ pLocalizedCont->addChild(base_ptr(localisedValue)) ;
+ }
+ }
+
+ else if (ValueNode * pValue = pProperty->asValueNode())
+ {
+ OSL_ENSURE(false, "Layer merging: Got locale-dependent value for non-localized node");
+ m_aContext.getLogger().error("Got locale-dependent value for non-localized node",
+ "setLocalizedValue()", "configmgr::LayerMergeHandler");
+ setValueAndCheck(*pValue,_aValue);
+ }
+
+ else
+ {
+ OSL_ENSURE(false, "Layer merging: Unknown node type for localized node");
+ m_aContext.getLogger().error("Unknown node type for localized node",
+ "setLocalizedValue()", "configmgr::LayerMergeHandler");
+ }
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::applyPropertyValue(uno::Any const & _aValue)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_ASSERT(m_pProperty);
+
+ if (ValueNode * pValue = m_pProperty->asValueNode())
+ {
+ setValueAndCheck(*pValue,_aValue);
+ }
+
+ else if (ISubtree * pLocalizedCont = m_pProperty->asISubtree())
+ {
+ setLocalizedValue(pLocalizedCont,_aValue,m_aLocale);
+ }
+
+ else
+ {
+ OSL_ENSURE(false, "Layer merging: Unknown node type for property");
+ m_aContext.getLogger().error("Unknown node type for property",
+ "applyPropertyValue()", "configmgr::LayerMergeHandler");
+ }
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::applyPropertyValue(uno::Any const & _aValue, rtl::OUString const & _aLocale)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_ASSERT(m_pProperty);
+
+ if (_aLocale.getLength() == 0)
+ m_aContext.raiseIllegalArgumentException("Locale string is empty");
+
+ if (ISubtree * pLocalizedCont = m_pProperty->asISubtree())
+ {
+ setLocalizedValue(pLocalizedCont,_aValue, _aLocale);
+ }
+
+ else if (ValueNode * pValue = m_pProperty->asValueNode())
+ {
+ //OSL_ENSURE(false, "Layer merging: Got locale-dependent value for non localized node");
+ setValueAndCheck(*pValue,_aValue);
+ }
+
+ else
+ {
+ OSL_ENSURE(false, "Layer merging: Unknown node type for localized property");
+ m_aContext.getLogger().error("Unknown node type for localized property",
+ "applyPropertyValue()", "configmgr::LayerMergeHandler");
+ }
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::applyAttributes(INode * pNode, sal_Int16 aNodeAttributes)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ sal_Int16 const k_allNodeAttributes =
+ NodeAttribute::MANDATORY |
+ NodeAttribute::FINALIZED |
+ NodeAttribute::READONLY;
+
+ if ((aNodeAttributes & k_allNodeAttributes) !=
+ (aNodeAttributes & NodeAttribute::MASK))
+ {
+ sal_Char const * pMsg =
+ "Layer merging: Unreckognized Node Attribute" ;
+
+ m_aContext.raiseIllegalArgumentException(pMsg,2);
+ }
+
+ if (aNodeAttributes & NodeAttribute::READONLY)
+ {
+ OSL_ENSURE(!(aNodeAttributes & NodeAttribute::FINALIZED),
+ "Layer merging: Warning: Node is both read-only and finalized");
+ if (aNodeAttributes & NodeAttribute::FINALIZED)
+ m_aContext.getLogger().warning("Node is both read-only and finalized - treating as readonly",
+ "applyAttributes()", "configmgr::LayerMergeHandler");
+
+ pNode->modifyAccess(node::accessReadonly);
+ }
+ else if (aNodeAttributes & NodeAttribute::FINALIZED)
+ {
+ pNode->modifyAccess(node::accessFinal);
+ }
+
+ if ( m_aContext.isNode(pNode) )
+ {
+ if (aNodeAttributes & NodeAttribute::MANDATORY)
+ {
+ pNode->markMandatory();
+ }
+ }
+ else if (aNodeAttributes) // do this only if there actually was something to do
+ {
+ if (ISubtree * pLocCont = pNode->asISubtree())
+ {
+ OSL_ENSURE(isLocalizedValueSet(*pLocCont),"Layer merging: Property subtree must be a localized value set");
+ propagateAttributes(*pLocCont);
+ }
+ }
+
+
+}
+// -----------------------------------------------------------------------------
+
+static
+void doLogRejection(sal_Int16 loglevel, DataBuilderContext const & aContext,
+ INode * pNode, bool bMandatory)
+{
+ rtl::OUStringBuffer aMessage;
+ aMessage.appendAscii("Rejecting override: Node/Property ")
+ .append(aContext.getNodePath(pNode->getName()))
+ .appendAscii(" is ").appendAscii(bMandatory ? "mandatory" : "finalized")
+ .appendAscii(" in a prior layer.");
+
+ aContext.getLogger().log(loglevel,aMessage.makeStringAndClear(),
+ bMandatory ? "addOrReplace/dropNode()" : "startOverride()",
+ "configmgr::LayerMergeHandler");
+}
+
+static inline
+void logRejection(DataBuilderContext const & aContext, INode * pNode, bool bMandatory=false)
+{
+ const sal_Int16 loglevel = LogLevel::INFO;
+ if (aContext.getLogger().isLogging(loglevel))
+ {
+ doLogRejection(loglevel, aContext, pNode, bMandatory);
+ }
+}
+// -----------------------------------------------------------------------------
+
+bool LayerMergeHandler::startOverride(INode * pNode, sal_Bool bClear) /* ensure writable, mark merged */
+ SAL_THROW(())
+{
+ OSL_PRECOND(pNode,"startOverride: non-NULL base node required");
+ if (!m_aContext.isWritable(pNode))
+ {
+ // #i41700# write-protection is enforced, unless merging localizations
+ if (!m_bSublayer)
+ {
+ logRejection(m_aContext,pNode);
+ return false;
+ }
+ else
+ OSL_ASSERT(m_aLocale.getLength() != 0);
+ }
+
+ OSL_ENSURE(!bClear,"'clear' operation is not yet supported");
+ if (bClear)
+ m_aContext.getLogger().warning("'clear' operation is not yet supported",
+ "startOverride()", "configmgr::LayerMergeHandler");
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::ensureUnchanged(INode const * pNode) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ // to do: change state handling to detect this within sets
+ OSL_PRECOND(pNode,"INTERNAL ERROR: Unexpected NULL node pointer");
+
+ if (!this->isInSublayer())
+ if (pNode->getAttributes().state() == node::isMerged)
+ m_aContext.raiseMalformedDataException("Layer merging: Duplicate node or property in this layer");
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// XLayerHandler
+
+void SAL_CALL LayerMergeHandler::startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ ISubtree * pSchema = m_rData.getSchemaTree();
+ OSL_ENSURE(pSchema,"No base data to merge layer into");
+
+ if (!pSchema)
+ {
+ m_aContext.getLogger().error("No schema data for merging layer", "startLayer", "configmgr::LayerMergeHandler");
+ throw uno::RuntimeException(rtl::OUString::createFromAscii("Layer merging: No data to merge with"),*this);
+ }
+
+ m_aContext.startActiveComponent(pSchema->getName());
+
+ m_pProperty = NULL;
+ m_nSkipping = 0;
+
+ OSL_POSTCOND( m_aContext.hasActiveComponent(), "Layer merging: could not set active component");
+ OSL_POSTCOND( m_aContext.isDone(), "Layer merging: newly started component is not empty");
+ OSL_POSTCOND( !this->isSkipping(), "Layer merging: newly started component is in skipping state");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ m_aContext.raiseMalformedDataException("Layer merging: Unmatched data being skipped was not terminated properly.");
+
+ m_aContext.endActiveComponent();
+
+ m_bSublayer = false;
+
+ OSL_POSTCOND( !m_aContext.hasActiveComponent(), "Layer merging: could not clear active component");
+ OSL_POSTCOND( m_aContext.isDone(), "Layer merging: could not finish processing");
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::overrideLayerRoot( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND( m_aContext.hasActiveComponent(), "Layer merging: active component is not set");
+ OSL_PRECOND( m_aContext.isDone(), "Layer merging: node is not root");
+
+ if (m_aContext.getActiveComponent() != aName)
+ m_aContext.raiseIllegalArgumentException("Layer merging: Name of layer being merged does not match component name",1);
+
+ // check the argument
+ if (ISubtree * pSchema = m_rData.getSchemaTree())
+ {
+ OSL_ENSURE(pSchema->getName() == aName,"Schema name does not match active component");
+
+ ensureUnchanged(pSchema);
+
+ if (startOverride(pSchema,bClear))
+ {
+ applyAttributes(pSchema,aAttributes);
+
+ m_aContext.pushNode(pSchema);
+
+ OSL_POSTCOND( m_aContext.hasActiveComponent(), "Layer merging: could not set active component");
+ OSL_POSTCOND( !m_aContext.isDone(), "Layer merging: could not start component");
+ }
+ else
+ this->skipNode();
+ }
+ else
+ {
+ OSL_ENSURE(false,"No base data to merge layer into");
+ m_aContext.getLogger().warning("No component data in schema for merging layer",
+ "overrideNode() [for layer root]", "configmgr::LayerMergeHandler");
+ this->skipNode();
+ }
+}
+// -----------------------------------------------------------------------------
+
+static inline
+sal_Int16 getOverrideViolationLogLevel(bool bIsSublayer)
+{ return bIsSublayer ? LogLevel::FINER : LogLevel::INFO; }
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::implOverrideNode(
+ ISubtree * node, sal_Int16 attributes, bool clear)
+{
+ ensureUnchanged(node);
+ if (startOverride(node, clear)) {
+ applyAttributes(node, attributes);
+ m_aContext.pushNode(node);
+ } else {
+ skipNode();
+ }
+}
+
+void SAL_CALL LayerMergeHandler::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ {
+ this->skipNode();
+ }
+ else if (m_aContext.isDone())
+ {
+ this->overrideLayerRoot(aName,aAttributes,bClear);
+ }
+ else if (ISubtree * pNode = m_aContext.findNode(aName))
+ {
+ implOverrideNode(pNode, aAttributes, bClear);
+ }
+ else // ignore non-matched data
+ {
+ const sal_Int16 loglevel = getOverrideViolationLogLevel(m_bSublayer);
+ if (m_aContext.getLogger().isLogging(loglevel))
+ {
+ rtl::OUStringBuffer aMessage;
+ aMessage.appendAscii("Node ").append(m_aContext.getNodePath(aName))
+ .appendAscii(" to be overridden does not exist - skipping");
+
+ m_aContext.getLogger().log(loglevel,aMessage.makeStringAndClear(), "overrideNode()", "configmgr::LayerMergeHandler");
+ }
+ // m_aContext.raiseNoSuchElementException("Layer merging: The node to be overridden does not exist.",aName);
+ this->skipNode();
+ }
+}
+// -----------------------------------------------------------------------------
+
+void LayerMergeHandler::implAddOrReplaceNode( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException))
+{
+ ISubtree * pReplacedNode = m_aContext.findNode(aName);
+ if (pReplacedNode)
+ {
+ if ((aAttributes & NodeAttribute::FUSE) == 0) {
+ this->ensureUnchanged(pReplacedNode);
+
+ if (!m_aContext.isRemovable(pReplacedNode))
+ {
+ logRejection(m_aContext,pReplacedNode,true);
+ this->skipNode();
+ return;
+ }
+ } else {
+ implOverrideNode(
+ pReplacedNode, aAttributes & ~NodeAttribute::FUSE, false);
+ return;
+ }
+ }
+
+ std::auto_ptr<INode> apNewInstance;
+ if (aTemplate.Component == m_aContext.getActiveComponent())
+ {
+ apNewInstance = m_rData.instantiateTemplate(aName, aTemplate.Name);
+ }
+ else
+ {
+ TemplateRequest aTemplateRequest(aTemplate.Name, aTemplate.Component);
+ apNewInstance = m_aContext.getTemplateData( aTemplateRequest ).extractDataAndClear();
+ if (apNewInstance.get())
+ apNewInstance->setName( aName );
+ }
+
+ if (NULL == apNewInstance.get())
+ m_aContext.raiseNoSuchElementException("Layer merging: Cannot instantiate template.", aTemplate.Name);
+
+ applyAttributes(apNewInstance.get(), aAttributes & ~NodeAttribute::FUSE);
+ //Set removable flag
+ apNewInstance->markRemovable();
+
+ m_aContext.markCurrentMerged();
+
+ if (pReplacedNode) m_aContext.getCurrentParent().removeChild( aName );
+
+ INode * pAddedInstance = m_aContext.getCurrentParent().addChild( apNewInstance );
+
+ m_aContext.pushNode(pAddedInstance->asISubtree());
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ {
+ this->skipNode();
+ return;
+ }
+
+ implAddOrReplaceNode( aName, m_aContext.getCurrentItemType(), aAttributes);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ {
+ this->skipNode();
+ return;
+ }
+
+ // TODO: correct argument position (from 2 to 3) for an illegal argument exception wrt attributes
+ implAddOrReplaceNode( aName, m_aContext.getValidItemType(aTemplate), aAttributes);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->leaveSkippedNode())
+ return;
+
+ this->propagateAttributes(m_aContext.getCurrentParent());
+
+ m_aContext.popNode();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ return;
+
+ if (!m_aContext.getCurrentParent().isSetNode())
+ m_aContext.raiseMalformedDataException("Layer merging: Removing child nodes is only possible in set nodes.");
+
+ if (ISubtree * pDropped = m_aContext.findNode(aName))
+ {
+ this->ensureUnchanged(pDropped);
+ if (!m_aContext.isRemovable(pDropped))
+ {
+ logRejection(m_aContext,pDropped,true);
+ return;
+ }
+ }
+ else
+ {
+ const sal_Int16 loglevel = getOverrideViolationLogLevel(m_bSublayer);
+ if (m_aContext.getLogger().isLogging(loglevel))
+ {
+ rtl::OUStringBuffer aMessage;
+ aMessage.appendAscii("Node ").append(m_aContext.getNodePath(aName))
+ .appendAscii(" to be removed does not exist - ignoring");
+
+ m_aContext.getLogger().log(loglevel,aMessage.makeStringAndClear(), "dropNode()", "configmgr::LayerMergeHandler");
+ }
+ // m_aContext.raiseNoSuchElementException("Layer merging: The node to be removed does not exist.",aName);
+ }
+ m_aContext.markCurrentMerged();
+ m_aContext.getCurrentParent().removeChild(aName);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ {
+ this->skipNode();
+ }
+ else if (INode * pProp = m_aContext.findProperty(aName))
+ {
+ ensureUnchanged(pProp);
+
+ if (startOverride(pProp,bClear))
+ {
+ applyAttributes(pProp,aAttributes);
+
+ m_pProperty = pProp;
+
+ checkPropertyType(aType);
+ }
+ else
+ this->skipNode();
+ }
+ else // ignore non-matched data
+ {
+ const sal_Int16 loglevel = getOverrideViolationLogLevel(m_bSublayer);
+ if (m_aContext.getLogger().isLogging(loglevel))
+ {
+ rtl::OUStringBuffer aMessage;
+ aMessage.appendAscii("Property ").append(m_aContext.getNodePath(aName))
+ .appendAscii(" to be overridden does not exist - skipping");
+
+ m_aContext.getLogger().log(loglevel,aMessage.makeStringAndClear(), "overrideNode()", "configmgr::LayerMergeHandler");
+ }
+ // m_aContext.raiseUnknownPropertyException("Layer merging: The property to be overridden does not exist.",aName);
+ this->skipNode();
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->leaveSkippedNode())
+ return;
+
+ if (!m_pProperty)
+ m_aContext.raiseMalformedDataException("Layer merging: Invalid data: Ending a property that wasn't started.");
+
+ if (ISubtree * pLocalizedSet = m_pProperty->asISubtree())
+ this->propagateAttributes(*pLocalizedSet);
+
+ m_pProperty = NULL;
+ if (m_pConverter) m_pConverter->m_bConvertData = false;
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ return;
+
+ // TODO: add type validation
+ node::Attributes aValueAttributes = makePropertyAttributes(aAttributes & SchemaAttribute::MASK);
+
+ std::auto_ptr<ValueNode> aPropertyValue =
+ m_aFactory.getNodeFactory().createNullValueNode(aName,aType,aValueAttributes);
+
+ applyAttributes(aPropertyValue.get(),aAttributes & NodeAttribute::MASK);
+
+ // can be a replace for dynamic properties (current update limitation)
+ m_aContext.markCurrentMerged();
+ m_aContext.addPropertyToCurrent(aPropertyValue, true);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ return;
+
+ node::Attributes aValueAttributes = makePropertyAttributes(aAttributes & SchemaAttribute::MASK);
+
+ std::auto_ptr<ValueNode> aPropertyValue =
+ m_aFactory.getNodeFactory().createValueNode(aName,aValue,aValueAttributes);
+
+ applyAttributes(aPropertyValue.get(),aAttributes & NodeAttribute::MASK);
+
+ // can be a replace for dynamic properties (current update limitation)
+ m_aContext.markCurrentMerged();
+ m_aContext.addPropertyToCurrent(aPropertyValue, true);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ return;
+
+ if (!m_pProperty)
+ m_aContext.raiseMalformedDataException("Layer merging: Invalid data: Overriding a value without a property.");
+
+ OSL_ASSERT( !m_pProperty->getAttributes().isReplacedForUser() );
+ m_pProperty->modifyState( node::isMerged );
+ m_aContext.markCurrentMerged();
+
+ applyPropertyValue(aValue);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerMergeHandler::setPropertyValueForLocale( const uno::Any& aValue, rtl::OUString const & aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (this->isSkipping())
+ return;
+
+ if (!m_pProperty)
+ m_aContext.raiseMalformedDataException("Layer merging: Invalid data: Overriding a (localized) value without a property.");
+
+ OSL_ASSERT( !m_pProperty->getAttributes().isReplacedForUser() );
+ m_pProperty->modifyState( node::isMerged );
+ m_aContext.markCurrentMerged();
+
+ applyPropertyValue(aValue,aLocale);
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+uno::Reference< com::sun::star::script::XTypeConverter >
+ LayerMergeHandler::Converter::createTCV(uno::Reference< uno::XComponentContext > const & xContext)
+{
+ OSL_ENSURE(xContext.is(),"Cannot create TypeConverter for LayerMergeHandler without a Context");
+
+ uno::Reference< lang::XMultiComponentFactory > xFactory = xContext->getServiceManager();
+ OSL_ENSURE(xFactory.is(),"Cannot create TypeConverter for LayerMergeHandler without a ServiceManager");
+
+ uno::Reference< com::sun::star::script::XTypeConverter > xTCV;
+ if (xFactory.is())
+ {
+ static const rtl::OUString k_sTCVService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter"));
+
+ xTCV = uno::Reference< com::sun::star::script::XTypeConverter >::query(xFactory->createInstanceWithContext(k_sTCVService,xContext));
+ }
+ return xTCV;
+}
+// -----------------------------------------------------------------------------
+
+LayerMergeHandler::Converter::Converter(uno::Reference< uno::XComponentContext > const & xContext)
+: m_aConverter( createTCV(xContext) )
+, m_bConvertData(false)
+{
+}
+// -----------------------------------------------------------------------------
+static
+inline
+uno::Type getBinaryDataType()
+{
+ uno::Sequence< sal_Int8 > const * const forBinary = 0;
+ return ::getCppuType(forBinary);
+}
+// -----------------------------------------------------------------------------
+
+uno::Any LayerMergeHandler::Converter::convertValue(uno::Type const & _aTargetType, uno::Any const & _aValue)
+{
+ OSL_ENSURE( m_bConvertData, "Unexpected: Calling convert data, when data conversion is not active");
+ OSL_ENSURE( _aValue.hasValue(), "Unexpected: Calling convert data, when data to convert is VOID");
+
+ if (_aTargetType == _aValue.getValueType()) return _aValue;
+
+ m_aConverter.reset(_aTargetType);
+
+ if (m_aConverter.isList())
+ {
+ uno::Sequence< rtl::OUString > aStringList;
+ if (_aValue >>= aStringList)
+ return m_aConverter.convertListToAny(aStringList);
+ }
+
+ rtl::OUString aContent;
+ if (_aValue >>= aContent)
+ return m_aConverter.convertToAny(aContent);
+
+
+ OSL_ENSURE(false, "Cannot convert typed value (not a string)");
+
+ return uno::Any();
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+namespace
+{
+// -----------------------------------------------------------------------------
+ static inline bool isFinal(node::Attributes const& _aAttributes)
+ {
+ return _aAttributes.isFinalized() || _aAttributes.isReadonly();
+ }
+ // --------------------------------- AttributeSetter ---------------------------------
+
+ class DefaultPromoter : NodeModification
+ {
+ public:
+ explicit
+ DefaultPromoter()
+ {}
+
+ void adjustAccess(INode& _rNode);
+
+ using NodeModification::applyToNode;
+ private:
+ void handle(ValueNode& _rValueNode);
+ void handle(ISubtree& _rSubtree);
+ };
+// -----------------------------------------------------------------------------
+
+ void DefaultPromoter::adjustAccess(INode& _rNode)
+ {
+ _rNode.promoteAccessToDefault();
+ }
+// -----------------------------------------------------------------------------
+
+ void DefaultPromoter::handle(ValueNode& _rValueNode)
+ {
+ _rValueNode.promoteToDefault();
+ adjustAccess(_rValueNode);
+ }
+// -----------------------------------------------------------------------------
+
+ void DefaultPromoter::handle(ISubtree& _rSubtree)
+ {
+ _rSubtree.markAsDefault();
+ this->applyToChildren(_rSubtree);
+ adjustAccess(_rSubtree);
+ }
+//--------------------------------------------------------------------------
+
+}
+// -----------------------------------------------------------------------------
+void promoteToDefault(MergedComponentData & _rTree)
+{
+ if (ISubtree * pTreeData = _rTree.getSchemaTree())
+ DefaultPromoter().applyToNode(*pTreeData);
+
+ else
+ OSL_ENSURE(false,"No Data to promote to default");
+
+}
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/layermerge.hxx b/configmgr/source/backend/layermerge.hxx
new file mode 100644
index 000000000000..302edd95933a
--- /dev/null
+++ b/configmgr/source/backend/layermerge.hxx
@@ -0,0 +1,191 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layermerge.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_LAYERMERGE_HXX
+#define CONFIGMGR_BACKEND_LAYERMERGE_HXX
+
+#include "mergedcomponentdata.hxx"
+#include "componentdatahelper.hxx"
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ class OTreeNodeFactory;
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+ class LayerMergeHandler
+ : public cppu::WeakImplHelper1<backenduno::XLayerHandler>
+ {
+ public:
+ explicit
+ LayerMergeHandler(uno::Reference< uno::XComponentContext > const & _xContext, MergedComponentData & _rData, ITemplateDataProvider* aTemplateProvider = NULL);
+ virtual ~LayerMergeHandler();
+
+ // prepare merging
+ void prepareLayer();
+ bool prepareSublayer(rtl::OUString const & aLocale);
+
+ // checking the result
+ bool isDone() const { return m_aContext.isDone(); }
+ bool isInSublayer() const { return m_bSublayer; }
+
+ // XLayerHandler
+ public:
+ virtual void SAL_CALL
+ startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ private:
+ void propagateAttributes(ISubtree & _rParent);
+
+ node::Attributes makePropertyAttributes(sal_Int16 aSchemaAttributes)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void checkPropertyType(uno::Type const & _aType)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void applyPropertyValue(uno::Any const & _aValue)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void applyPropertyValue(uno::Any const & _aValue, rtl::OUString const & _aLocale)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void applyAttributes(INode * pNode, sal_Int16 aNodeAttributes)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void overrideLayerRoot( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ bool startOverride(INode * pNode, sal_Bool bClear) /* check if writable, mark merged */
+ SAL_THROW(());
+
+ void implOverrideNode(
+ ISubtree * node, sal_Int16 attributes, bool clear);
+
+ void implAddOrReplaceNode(const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void ensureUnchanged(INode const * pNode) const
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void setLocalizedValue(ISubtree * pProperty, uno::Any const & _aValue, rtl::OUString const & _aLocale)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+
+ void setValueAndCheck(ValueNode & _rValueNode, uno::Any const & _aValue)
+ SAL_THROW((com::sun::star::configuration::backend::MalformedDataException , com::sun::star::uno::RuntimeException));
+ private:
+ void skipNode() { ++m_nSkipping; }
+ bool isSkipping() const { return m_nSkipping != 0; }
+ bool leaveSkippedNode() { return m_nSkipping && m_nSkipping--; }
+ private:
+ struct Converter;
+ MergedComponentData & m_rData;
+ DataBuilderContext m_aContext;
+ ComponentDataFactory m_aFactory;
+ rtl::OUString m_aLocale;
+ INode * m_pProperty;
+ Converter * m_pConverter;
+
+ sal_uInt32 m_nSkipping;
+ bool m_bSublayer;
+ };
+// -----------------------------------------------------------------------------
+
+ /// change attributes and states of the tree to make it a proper default layer
+ void promoteToDefault(MergedComponentData & _rTree);
+// -----------------------------------------------------------------------------
+ } // namespace backend
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/layerupdate.cxx b/configmgr/source/backend/layerupdate.cxx
new file mode 100644
index 000000000000..2f294335be24
--- /dev/null
+++ b/configmgr/source/backend/layerupdate.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerupdate.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "layerupdate.hxx"
+#include "updatedata.hxx"
+#include "configpath.hxx"
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+LayerUpdate::LayerUpdate()
+: m_xContextNode()
+{
+}
+// -----------------------------------------------------------------------------
+
+LayerUpdate::LayerUpdate(LayerUpdate const & _aOther)
+: m_xContextNode(_aOther.m_xContextNode)
+, m_aContextPath(_aOther.m_aContextPath)
+{
+}
+// -----------------------------------------------------------------------------
+
+LayerUpdate::~LayerUpdate()
+{
+}
+// -----------------------------------------------------------------------------
+
+LayerUpdate & LayerUpdate::operator =(LayerUpdate const & _aOther)
+{
+ m_xContextNode = _aOther.m_xContextNode;
+ return *this;
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdate::setContextNode(rtl::Reference<NodeUpdate> const & _xContextNode)
+{
+ m_xContextNode = _xContextNode;
+ if (_xContextNode.is())
+ makeContextPath(_xContextNode->getName());
+
+ else
+ m_aContextPath.clear();
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdate::makeContextPath(rtl::OUString const & _aPath)
+{
+ configuration::AbsolutePath const aParsedPath = configuration::AbsolutePath::parse(_aPath);
+
+ m_aContextPath.clear();
+ m_aContextPath.reserve( aParsedPath.getDepth() );
+ for (std::vector<configuration::Path::Component>::const_reverse_iterator it = aParsedPath.begin(); it != aParsedPath.end(); ++it)
+ {
+ m_aContextPath.push_back( it->getName() );
+ }
+}
+// -----------------------------------------------------------------------------
+
+rtl::Reference<NodeUpdate> LayerUpdate::getContextNode() const
+{
+ return m_xContextNode;
+}
+// -----------------------------------------------------------------------------
+
+std::vector<rtl::OUString> const & LayerUpdate::getContextPath() const
+{
+ OSL_PRECOND( m_xContextNode.is(), "Cannot get context path without context node" );
+
+ return m_aContextPath;
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/layerupdate.hxx b/configmgr/source/backend/layerupdate.hxx
new file mode 100644
index 000000000000..ef960988d3c3
--- /dev/null
+++ b/configmgr/source/backend/layerupdate.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerupdate.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_LAYERUPDATE_HXX
+#define CONFIGMGR_BACKEND_LAYERUPDATE_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/ustring.hxx>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace com { namespace sun { namespace star { namespace configuration { namespace backend {
+ class XLayerHandler;
+} } } } }
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+ class NodeUpdate;
+
+ class LayerUpdate
+ {
+ public:
+ LayerUpdate();
+ LayerUpdate(LayerUpdate const & _aOther);
+ ~LayerUpdate();
+ LayerUpdate & operator =(LayerUpdate const & _aOther);
+ public:
+ bool isEmpty() const { return ! m_xContextNode.is(); }
+
+ rtl::Reference<NodeUpdate> getContextNode() const;
+ std::vector<rtl::OUString> const & getContextPath() const;
+
+ void setContextNode(rtl::Reference<NodeUpdate> const & _xContextNode);
+
+ private:
+ void makeContextPath(rtl::OUString const & _aContextPath);
+
+ private:
+ rtl::Reference<NodeUpdate> m_xContextNode;
+ std::vector<rtl::OUString> m_aContextPath;
+ };
+// -----------------------------------------------------------------------------
+
+ } // namespace backend
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/layerupdatebuilder.cxx b/configmgr/source/backend/layerupdatebuilder.cxx
new file mode 100644
index 000000000000..a734e2fe7491
--- /dev/null
+++ b/configmgr/source/backend/layerupdatebuilder.cxx
@@ -0,0 +1,302 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerupdatebuilder.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "layerupdatebuilder.hxx"
+#include "updatedata.hxx"
+#include "layerupdate.hxx"
+#include <com/sun/star/configuration/backend/TemplateIdentifier.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+LayerUpdateBuilder::LayerUpdateBuilder()
+: m_aUpdate()
+, m_pCurrentNode(NULL)
+, m_pCurrentProp(NULL)
+{
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdateBuilder::clear()
+{
+ m_pCurrentProp = NULL;
+ m_pCurrentNode = NULL;
+ m_aUpdate = LayerUpdate();
+
+ OSL_POSTCOND( this->isEmpty(), "LayerUpdateBuilder: Could not reset the stored update.");
+}
+// -----------------------------------------------------------------------------
+
+LayerUpdate const & LayerUpdateBuilder::result() const
+{
+ OSL_ENSURE(this->isComplete(),
+ "LayerUpdateBuilder: There is no result to retrieve"
+ " - building the data is still in progress.");
+
+ return m_aUpdate;
+}
+// -----------------------------------------------------------------------------
+
+inline
+LayerUpdate & LayerUpdateBuilder::data()
+{
+ return m_aUpdate;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::init()
+{
+ if (m_pCurrentNode) return false;
+
+ LayerUpdate & update = data();
+ m_pCurrentNode = new NodeModification(NULL, rtl::OUString(), 0, 0, false);
+ update.setContextNode(m_pCurrentNode);
+
+ OSL_ENSURE(m_pCurrentProp == NULL, "LayerUpdateBuilder: Internal error: got a current property for a new context");
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::modifyNode(rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, sal_Bool _bReset)
+{
+ OSL_PRECOND(m_pCurrentNode && !m_pCurrentProp, "LayerUpdateBuilder: Illegal state for this operation");
+
+ NodeUpdate * pNewNode = new NodeModification(m_pCurrentNode,_aName,_nFlags,_nFlagsMask,_bReset);
+ rtl::Reference<ElementUpdate> xNewNode(pNewNode);
+
+ if (!m_pCurrentNode->addNodeUpdate(xNewNode))
+ return false;
+
+ m_pCurrentNode = pNewNode;
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::replaceNode(rtl::OUString const & _aName, sal_Int16 _nFlags, backenduno::TemplateIdentifier const * _pTemplate)
+{
+ OSL_PRECOND(m_pCurrentNode && !m_pCurrentProp, "LayerUpdateBuilder: Illegal state for this operation");
+
+ NodeUpdate * pNewNode = _pTemplate ?
+ new NodeReplace(m_pCurrentNode,_aName,_nFlags,_pTemplate->Name,_pTemplate->Component) :
+ new NodeReplace(m_pCurrentNode,_aName,_nFlags);
+
+ rtl::Reference<ElementUpdate> xNewNode(pNewNode);
+
+ if (!m_pCurrentNode->addNodeUpdate(xNewNode))
+ return false;
+
+ m_pCurrentNode = pNewNode;
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::finishNode()
+{
+ OSL_PRECOND(m_pCurrentNode && !m_pCurrentProp, "LayerUpdateBuilder: Illegal state for this operation");
+
+ if (m_pCurrentProp || !m_pCurrentNode) return false;
+
+ m_pCurrentNode = m_pCurrentNode->getParent();
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::removeNode(rtl::OUString const & _aName)
+{
+ OSL_PRECOND(m_pCurrentNode && !m_pCurrentProp, "LayerUpdateBuilder: Illegal state for this operation");
+
+ NodeDrop * pNewNode = new NodeDrop(m_pCurrentNode,_aName);
+
+ rtl::Reference<ElementUpdate> xNewNode(pNewNode);
+
+ if (!m_pCurrentNode->addNodeUpdate(xNewNode))
+ return false;
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::modifyProperty(rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, uno::Type const & _aType)
+{
+ OSL_PRECOND(m_pCurrentNode && !m_pCurrentProp, "LayerUpdateBuilder: Illegal state for this operation");
+
+ PropertyUpdate * pNewProp = new PropertyUpdate(m_pCurrentNode,_aName,_nFlags,_nFlagsMask,_aType);
+ rtl::Reference<ElementUpdate> xNewProp(pNewProp);
+
+ if (!m_pCurrentNode->addPropertyUpdate(xNewProp))
+ return false;
+
+ m_pCurrentProp = pNewProp;
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::setPropertyValue(uno::Any const & _aValue)
+{
+ OSL_PRECOND(m_pCurrentProp, "LayerUpdateBuilder: Illegal state for property operation");
+
+ return m_pCurrentProp->setValue(_aValue);
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::setPropertyValueForLocale(uno::Any const & _aValue, rtl::OUString const & _aLocale)
+{
+ OSL_PRECOND(m_pCurrentProp, "LayerUpdateBuilder: Illegal state for property operation");
+
+ return m_pCurrentProp->setValueFor(_aLocale, _aValue);
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::resetPropertyValue()
+{
+ OSL_PRECOND(m_pCurrentProp, "LayerUpdateBuilder: Illegal state for property operation");
+
+ return m_pCurrentProp->resetValue();
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::resetPropertyValueForLocale(rtl::OUString const & _aLocale)
+{
+ OSL_PRECOND(m_pCurrentProp, "LayerUpdateBuilder: Illegal state for property operation");
+
+ return m_pCurrentProp->resetValueFor(_aLocale);
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::finishProperty()
+{
+ OSL_PRECOND(m_pCurrentProp, "LayerUpdateBuilder: Illegal state for property operation");
+ if (!m_pCurrentProp) return false;
+ m_pCurrentProp->finishValue();
+
+ OSL_ASSERT(m_pCurrentNode == m_pCurrentProp->getParent());
+
+ m_pCurrentProp = NULL;
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::addNullProperty(rtl::OUString const & _aName, sal_Int16 _nFlags, uno::Type const & _aType)
+{
+ OSL_PRECOND(m_pCurrentNode && !m_pCurrentProp, "LayerUpdateBuilder: Illegal state for this operation");
+
+ PropertyAdd * pNewProp = new PropertyAdd(m_pCurrentNode,_aName,_nFlags,_aType);
+
+ rtl::Reference<ElementUpdate> xNewProp(pNewProp);
+
+ if (!m_pCurrentNode->addPropertyUpdate(xNewProp))
+ return false;
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::addProperty(rtl::OUString const & _aName, sal_Int16 _nFlags, uno::Any const & _aValue)
+{
+ OSL_PRECOND(m_pCurrentNode && !m_pCurrentProp, "LayerUpdateBuilder: Illegal state for this operation");
+
+ PropertyAdd * pNewProp = new PropertyAdd(m_pCurrentNode,_aName,_nFlags,_aValue);
+
+ rtl::Reference<ElementUpdate> xNewProp(pNewProp);
+
+ if (!m_pCurrentNode->addPropertyUpdate(xNewProp))
+ return false;
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::resetProperty(rtl::OUString const & _aName)
+{
+ OSL_PRECOND(m_pCurrentNode && !m_pCurrentProp, "LayerUpdateBuilder: Illegal state for this operation");
+
+ PropertyReset * pNewProp = new PropertyReset(m_pCurrentNode,_aName);
+
+ rtl::Reference<ElementUpdate> xNewProp(pNewProp);
+
+ if (!m_pCurrentNode->addPropertyUpdate(xNewProp))
+ return false;
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::finish()
+{
+ if (!this->finishNode()) return false;
+
+ return m_pCurrentNode == NULL;
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::isEmpty() const
+{
+ OSL_ENSURE( !m_pCurrentNode || !m_aUpdate.isEmpty(), "LayerUpdateBuilder: Invariant violation: got a current node without a layer");
+ return m_aUpdate.isEmpty();
+}
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::isActive() const
+{
+ OSL_ENSURE( !m_pCurrentNode || !m_aUpdate.isEmpty(), "LayerUpdateBuilder: Invariant violation: got a current node without a layer");
+ return m_pCurrentNode != 0;
+}
+// -----------------------------------------------------------------------------
+#if OSL_DEBUG_LEVEL > 0
+bool LayerUpdateBuilder::isComplete() const
+{
+ OSL_ENSURE( !m_pCurrentNode || !m_aUpdate.isEmpty(), "LayerUpdateBuilder: Invariant violation: got a current node without a layer");
+ return !m_aUpdate.isEmpty() && m_pCurrentNode == NULL;
+}
+#endif
+// -----------------------------------------------------------------------------
+
+bool LayerUpdateBuilder::isPropertyActive() const
+{
+ OSL_ENSURE( !m_pCurrentNode || !m_aUpdate.isEmpty(), "LayerUpdateBuilder: Invariant violation: got a current node without a layer");
+ OSL_ENSURE(m_pCurrentNode || !m_pCurrentProp, "LayerUpdateBuilder: Invariant violation: got a current property without a node");
+ return m_pCurrentProp != 0;
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/layerupdatebuilder.hxx b/configmgr/source/backend/layerupdatebuilder.hxx
new file mode 100644
index 000000000000..841b90f9df69
--- /dev/null
+++ b/configmgr/source/backend/layerupdatebuilder.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerupdatebuilder.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_LAYERUPDATEBUILDER_HXX
+#define CONFIGMGR_BACKEND_LAYERUPDATEBUILDER_HXX
+
+#include "layerupdate.hxx"
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include <rtl/ustring.hxx>
+
+namespace com { namespace sun { namespace star { namespace configuration { namespace backend {
+ struct TemplateIdentifier;
+} } } } }
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+ class NodeUpdate;
+ class PropertyUpdate;
+
+ class LayerUpdateBuilder
+ {
+ LayerUpdate m_aUpdate;
+ NodeUpdate * m_pCurrentNode;
+ PropertyUpdate * m_pCurrentProp;
+ public:
+ LayerUpdateBuilder();
+
+ public:
+ /// initialize the update
+ bool init();
+
+ bool modifyNode(rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, sal_Bool _bReset);
+ bool replaceNode(rtl::OUString const & _aName, sal_Int16 _nFlags, backenduno::TemplateIdentifier const * _pTemplate = NULL);
+ bool finishNode();
+
+ bool removeNode(rtl::OUString const & _aName);
+
+ bool modifyProperty(rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, uno::Type const & _aType);
+ bool setPropertyValue(uno::Any const & _aValue);
+ bool setPropertyValueForLocale(uno::Any const & _aValue, rtl::OUString const & _aLocale);
+ bool resetPropertyValue();
+ bool resetPropertyValueForLocale(rtl::OUString const & _aLocale);
+ bool finishProperty();
+
+ bool addNullProperty(rtl::OUString const & _aName, sal_Int16 _nFlags, uno::Type const & _aType);
+ bool addProperty(rtl::OUString const & _aName, sal_Int16 _nFlags, uno::Any const & _aValue);
+ bool resetProperty(rtl::OUString const & _aName);
+
+ bool finish();
+ void clear();
+
+ bool isEmpty() const;
+ bool isActive() const;
+#if OSL_DEBUG_LEVEL > 0
+ bool isComplete() const;
+#endif
+ bool isPropertyActive() const;
+
+ LayerUpdate const & result() const;
+ private:
+ LayerUpdate & data();
+ };
+// -----------------------------------------------------------------------------
+
+ } // namespace backend
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/layerupdatehandler.cxx b/configmgr/source/backend/layerupdatehandler.cxx
new file mode 100644
index 000000000000..51ca33db97f8
--- /dev/null
+++ b/configmgr/source/backend/layerupdatehandler.cxx
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerupdatehandler.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "layerupdatehandler.hxx"
+#include "layerupdatemerger.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+#include <com/sun/star/beans/PropertyExistException.hpp>
+
+// -----------------------------------------------------------------------------
+#define OUSTR( str ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( str ) )
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > SAL_CALL instantiateUpdateMerger
+( uno::Reference< uno::XComponentContext > const& xContext )
+{
+ return * new LayerUpdateHandler( xContext );
+}
+
+// -----------------------------------------------------------------------------
+
+LayerUpdateHandler::LayerUpdateHandler(uno::Reference< uno::XComponentContext > const & _xContext)
+: UpdateService(_xContext)
+, m_aBuilder()
+{
+}
+// -----------------------------------------------------------------------------
+
+LayerUpdateHandler::~LayerUpdateHandler()
+{
+}
+// -----------------------------------------------------------------------------
+inline
+void LayerUpdateHandler::checkBuilder(bool _bForProperty)
+{
+ if ( m_aBuilder.isEmpty() )
+ raiseMalformedDataException("LayerUpdateHandler: Illegal operation - no update is in progress");
+
+ if ( !m_aBuilder.isActive() )
+ raiseMalformedDataException("LayerUpdateHandler: Illegal operation - no context for update available");
+
+ if ( m_aBuilder.isPropertyActive() != _bForProperty )
+ raiseMalformedDataException("LayerUpdateHandler: Illegal operation - a property is in progress");
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdateHandler::raiseMalformedDataException(sal_Char const * pMsg)
+{
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+ throw backenduno::MalformedDataException(sMsg,*this,uno::Any());
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdateHandler::raiseNodeChangedBeforeException(sal_Char const * pMsg)
+{
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+ throw backenduno::MalformedDataException(sMsg,*this,uno::Any());
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdateHandler::raisePropChangedBeforeException(sal_Char const * pMsg)
+{
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+ throw backenduno::MalformedDataException(sMsg,*this,uno::Any());
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdateHandler::raisePropExistsException(sal_Char const * pMsg)
+{
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+ com::sun::star::beans::PropertyExistException e(sMsg,*this);
+
+ throw backenduno::MalformedDataException(sMsg,*this, uno::makeAny(e));
+}
+// -----------------------------------------------------------------------------
+
+// XUpdateHandler
+void SAL_CALL
+ LayerUpdateHandler::startUpdate( )
+ throw ( backenduno::MalformedDataException, lang::IllegalAccessException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ this->checkSourceLayer();
+ if (!m_aBuilder.init())
+ raiseMalformedDataException("LayerUpdateHandler: Cannot start update - update is already in progress");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::endUpdate( )
+ throw ( backenduno::MalformedDataException, lang::IllegalAccessException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder();
+
+ if (!m_aBuilder.finish())
+ raiseMalformedDataException("LayerUpdateHandler: Cannot finish update - a node is still open.");
+
+ uno::Reference< backenduno::XLayer > xMergedLayer( LayerUpdateMerger::getMergedLayer(this->getSourceLayer(), m_aBuilder.result()) );
+
+ m_aBuilder.clear();
+
+ this->writeUpdatedLayer(xMergedLayer);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::modifyNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Int16 aAttributeMask, sal_Bool bReset )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder();
+
+ if (!m_aBuilder.modifyNode(aName,aAttributes,aAttributeMask,bReset))
+ raiseNodeChangedBeforeException("LayerUpdateHandler: Cannot start node modification - node has already been changed.");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder();
+
+ if (!m_aBuilder.replaceNode(aName,aAttributes,NULL))
+ raiseNodeChangedBeforeException("LayerUpdateHandler: Cannot start added/replaced node - node has already been changed.");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, sal_Int16 aAttributes, const backenduno::TemplateIdentifier& aTemplate )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder();
+
+ if (!m_aBuilder.replaceNode(aName,aAttributes,&aTemplate))
+ raiseNodeChangedBeforeException("LayerUpdateHandler: Cannot start added/replaced node - node has already been changed.");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder();
+
+ if (!m_aBuilder.finishNode())
+ {
+ OSL_ENSURE(m_aBuilder.isPropertyActive() || !m_aBuilder.isActive(), "LayerUpdateHandler: Unexpected failure mode for finishNode");
+ if (m_aBuilder.isPropertyActive())
+ raiseMalformedDataException("LayerUpdateHandler: Cannot finish node update - open property has not been ended.");
+ else
+ raiseMalformedDataException("LayerUpdateHandler: Cannot finish node update - no node has been started.");
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::removeNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder();
+
+ if (!m_aBuilder.removeNode(aName))
+ raiseNodeChangedBeforeException("LayerUpdateHandler: Cannot remove node - node has already been changed.");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler:: modifyProperty( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Int16 aAttributeMask, const uno::Type & aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder(false);
+
+ if (!m_aBuilder.modifyProperty(aName,aAttributes,aAttributeMask, aType))
+ raisePropChangedBeforeException("LayerUpdateHandler: Cannot start property modification - property has already been changed.");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler:: setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder(true); // already checks for open property
+
+ OSL_VERIFY( m_aBuilder.setPropertyValue(aValue) );
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler:: setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder(true); // already checks for open property
+
+ OSL_VERIFY( m_aBuilder.setPropertyValueForLocale(aValue,aLocale) );
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::resetPropertyValue( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder(true); // already checks for open property
+
+ OSL_VERIFY( m_aBuilder.resetPropertyValue() );
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::resetPropertyValueForLocale( const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder(true); // already checks for open property
+
+ OSL_VERIFY( m_aBuilder.resetPropertyValueForLocale(aLocale) );
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ checkBuilder(true); // already checks for open property
+
+ OSL_VERIFY ( m_aBuilder.finishProperty() );
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::resetProperty( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!m_aBuilder.resetProperty(aName))
+ raisePropChangedBeforeException("LayerUpdateHandler: Cannot reset property - property has already been changed.");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::addOrReplaceProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!m_aBuilder.addNullProperty(aName,aAttributes,aType))
+ raisePropExistsException("LayerUpdateHandler: Cannot add property - property exists (and has already been changed).");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::addOrReplacePropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!m_aBuilder.addProperty(aName,aAttributes,aValue))
+ raisePropExistsException("LayerUpdateHandler: Cannot add property - property exists (and has already been changed).");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL
+ LayerUpdateHandler::removeProperty( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ // treat 'remove' as 'reset'. (Note: does not verify that this actually amounts to dropping the property)
+ if (!m_aBuilder.resetProperty(aName))
+ raisePropChangedBeforeException("LayerUpdateHandler: Cannot remove property - property has already been changed.");
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/layerupdatehandler.hxx b/configmgr/source/backend/layerupdatehandler.hxx
new file mode 100644
index 000000000000..015eade9b278
--- /dev/null
+++ b/configmgr/source/backend/layerupdatehandler.hxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerupdatehandler.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_LAYERUPDATEHANDLER_HXX
+#define CONFIGMGR_BACKEND_LAYERUPDATEHANDLER_HXX
+
+#include "sal/config.h"
+
+#include "boost/utility.hpp"
+
+#include "updatesvc.hxx"
+#include "layerupdatebuilder.hxx"
+#include "utility.hxx"
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+ class LayerUpdateBuilder;
+
+ class LayerUpdateHandler: private boost::noncopyable, public UpdateService
+ {
+ public:
+ explicit
+ LayerUpdateHandler(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ ~LayerUpdateHandler();
+
+ // XUpdateHandler
+ virtual void SAL_CALL
+ startUpdate( )
+ throw ( backenduno::MalformedDataException, lang::IllegalAccessException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endUpdate( )
+ throw ( backenduno::MalformedDataException, lang::IllegalAccessException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ modifyNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Int16 aAttributeMask, sal_Bool bReset )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNodeFromTemplate( const rtl::OUString& aName, sal_Int16 aAttributes, const backenduno::TemplateIdentifier& aTemplate )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ modifyProperty( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Int16 aAttributeMask, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ resetPropertyValue( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ resetPropertyValueForLocale( const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ resetProperty( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplacePropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ removeProperty( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ private:
+ LayerUpdateBuilder & getUpdateBuilder();
+
+ void checkBuilder(bool _bForProperty = false);
+
+ void raiseMalformedDataException(sal_Char const * pMsg);
+ void raiseNodeChangedBeforeException(sal_Char const * pMsg);
+ void raisePropChangedBeforeException(sal_Char const * pMsg);
+ void raisePropExistsException(sal_Char const * pMsg);
+
+ private:
+ LayerUpdateBuilder m_aBuilder;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/layerupdatemerger.cxx b/configmgr/source/backend/layerupdatemerger.cxx
new file mode 100644
index 000000000000..469349920ca3
--- /dev/null
+++ b/configmgr/source/backend/layerupdatemerger.cxx
@@ -0,0 +1,515 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerupdatemerger.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "layerupdatemerger.hxx"
+#include "layerupdatebuilder.hxx"
+#include "updatedata.hxx"
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+LayerUpdateMerger::LayerUpdateMerger(uno::Reference< backenduno::XLayer > const & _xSourceLayer, LayerUpdate const & _aLayerUpdate)
+: BasicUpdateMerger(_xSourceLayer)
+, m_aLayerUpdate(_aLayerUpdate)
+, m_xCurrentNode()
+{
+}
+// -----------------------------------------------------------------------------
+
+LayerUpdateMerger::~LayerUpdateMerger()
+{
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdateMerger::flushUpdate()
+{
+ OSL_ENSURE(!BasicUpdateMerger::isHandling(), "LayerUpdateMerger: Unexpected: flushing data, while base implementation is active");
+ OSL_ENSURE(m_xCurrentNode.is(),"LayerUpdateMerger: No data for flushing.");
+
+ if (m_xCurrentNode.is())
+ {
+ m_xCurrentNode->writeChildrenToLayer(getResultWriter().get());
+ m_xCurrentNode.clear();
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ BasicUpdateMerger::startLayer();
+
+ m_xCurrentNode = m_aLayerUpdate.getContextNode();
+
+ BasicUpdateMerger::findContext(m_aLayerUpdate.getContextPath());
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ BasicUpdateMerger::endLayer();
+
+ OSL_ENSURE(!m_xCurrentNode.is(), "Path being updated not found in data - update not written");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::overrideNode(aName, aAttributes, bClear);
+ return;
+ }
+
+ OSL_ASSERT(m_xCurrentNode.is());
+
+ rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getNodeByName(aName);
+ if (!xUpdate.is())
+ {
+ BasicUpdateMerger::overrideNode(aName, aAttributes, bClear);
+ OSL_ASSERT(BasicUpdateMerger::isHandling());
+ return;
+ }
+ m_xCurrentNode->removeNodeByName(aName);
+
+ if (NodeUpdate * pNodeUpdate = xUpdate->asNodeUpdate(true))
+ {
+ getResultWriter()->overrideNode(aName, pNodeUpdate->updateFlags(aAttributes), bClear);
+ m_xCurrentNode.set(pNodeUpdate);
+ }
+ else
+ {
+ xUpdate->writeToLayer(getResultWriter().get());
+ BasicUpdateMerger::startSkipping();
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::addOrReplaceNode(aName, aAttributes);
+ return;
+ }
+
+ OSL_ASSERT(m_xCurrentNode.is());
+
+ rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getNodeByName(aName);
+ if (!xUpdate.is())
+ {
+ BasicUpdateMerger::addOrReplaceNode(aName, aAttributes);
+ OSL_ASSERT(BasicUpdateMerger::isHandling());
+ return;
+ }
+ m_xCurrentNode->removeNodeByName(aName);
+
+ if (NodeUpdate * pNodeUpdate = xUpdate->asNodeUpdate(true))
+ {
+ getResultWriter()->addOrReplaceNode(aName, pNodeUpdate->updateFlags(aAttributes));
+ m_xCurrentNode.set(pNodeUpdate);
+ }
+ else
+ {
+ xUpdate->writeToLayer(getResultWriter().get());
+ BasicUpdateMerger::startSkipping();
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::addOrReplaceNodeFromTemplate(aName, aTemplate, aAttributes);
+ return;
+ }
+
+ OSL_ASSERT(m_xCurrentNode.is());
+
+ rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getNodeByName(aName);
+ if (!xUpdate.is())
+ {
+ BasicUpdateMerger::addOrReplaceNodeFromTemplate(aName, aTemplate, aAttributes);
+ OSL_ASSERT(BasicUpdateMerger::isHandling());
+ return;
+ }
+ m_xCurrentNode->removeNodeByName(aName);
+
+ if (NodeUpdate * pNodeUpdate = xUpdate->asNodeUpdate(true))
+ {
+ getResultWriter()->addOrReplaceNodeFromTemplate(aName, aTemplate, pNodeUpdate->updateFlags(aAttributes));
+ m_xCurrentNode.set(pNodeUpdate);
+ }
+ else
+ {
+ xUpdate->writeToLayer(getResultWriter().get());
+ BasicUpdateMerger::startSkipping();
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::endNode();
+ return;
+ }
+
+ OSL_ASSERT(m_xCurrentNode.is());
+
+ // write unhandled so far changes
+ m_xCurrentNode->writeChildrenToLayer( getResultWriter().get() );
+
+ rtl::Reference<NodeUpdate> xParent( m_xCurrentNode->getParent() );
+
+ if (xParent.is())
+ getResultWriter()->endNode();
+
+ else
+ BasicUpdateMerger::leaveContext();
+
+ m_xCurrentNode = xParent;
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::dropNode(aName);
+ return;
+ }
+
+ OSL_ASSERT(m_xCurrentNode.is());
+
+ rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getNodeByName(aName);
+ if (xUpdate.is())
+ {
+ m_xCurrentNode->removeNodeByName(aName);
+
+ if (NodeUpdate * pNodeUpdate = xUpdate->asNodeUpdate())
+ {
+ if (pNodeUpdate-> getOperation() == NodeUpdate::replace)
+ {
+ xUpdate->writeToLayer( getResultWriter().get() );
+ return;
+ }
+ else
+ {
+ malformedUpdate("LayerUpdateMerger: Applying modification to dropped node");
+ }
+ }
+ }
+
+ getResultWriter()->dropNode(aName);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::overrideProperty(aName, aAttributes, aType, bClear);
+ return;
+ }
+
+ OSL_ASSERT( m_xCurrentNode.is());
+
+ rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getPropertyByName(aName);
+ if (!xUpdate.is())
+ {
+ BasicUpdateMerger::overrideProperty(aName, aAttributes, aType, bClear);
+ OSL_ASSERT(BasicUpdateMerger::isHandling());
+ return;
+ }
+
+ m_xCurrentNode->removePropertyByName(aName);
+
+ if (PropertyUpdate * pPropUpdate = xUpdate->asPropertyUpdate())
+ {
+ OSL_ENSURE( aType == pPropUpdate->getValueType() ||
+ aType == uno::Type() ||
+ pPropUpdate->getValueType() == uno::Type(),
+ "Error in update merger: type mismatch overriding property ...");
+
+ getResultWriter()->overrideProperty(aName, pPropUpdate->updateFlags(aAttributes), aType, bClear);
+ m_xCurrentProp.set(pPropUpdate);
+ }
+ else
+ {
+ xUpdate->writeToLayer(getResultWriter().get());
+ BasicUpdateMerger::startSkipping();
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::endProperty();
+ return;
+ }
+
+ OSL_ASSERT(m_xCurrentNode.is());
+
+ if (!m_xCurrentProp.is())
+ {
+ rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("LayerUpdateMerger: Invalid data: Ending property that wasn't started.") );
+ throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
+ }
+
+ // write unhandled so far values
+ m_xCurrentProp->writeValuesToLayer( getResultWriter().get() );
+
+ getResultWriter()->endProperty();
+
+ m_xCurrentProp.clear();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::setPropertyValue(aValue);
+ return;
+ }
+
+ OSL_ASSERT(m_xCurrentNode.is());
+
+ if (!m_xCurrentProp.is())
+ {
+ rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("LayerUpdateMerger: Invalid data: setting value, but no property is started.") );
+ throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
+ }
+
+ if (!m_xCurrentProp->hasChange())
+ {
+ BasicUpdateMerger::setPropertyValue(aValue);
+ return;
+ }
+
+#ifndef CFG_UPDATEMERGER_BATCHWRITE_PROPERTIES
+ if (m_xCurrentProp->hasValue())
+ {
+ getResultWriter()->setPropertyValue(m_xCurrentProp->getValue());
+ }
+ else
+ {
+ OSL_ENSURE(m_xCurrentProp->hasReset(),"LayerUpdateMerger: ERROR: Unknown change type in PropertyUpdate");
+ // write nothing to result
+ }
+
+ // mark handled
+ m_xCurrentProp->removeValue();
+#endif
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::setPropertyValueForLocale(aValue, aLocale);
+ return;
+ }
+
+ OSL_ASSERT(m_xCurrentNode.is());
+
+ if (!m_xCurrentProp.is())
+ {
+ rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("LayerUpdateMerger: Invalid data: setting value, but no property is started.") );
+ throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
+ }
+
+ if (!m_xCurrentProp->hasChangeFor(aLocale))
+ {
+ BasicUpdateMerger::setPropertyValueForLocale(aValue, aLocale);
+ return;
+ }
+
+#ifndef CFG_UPDATEMERGER_BATCHWRITE_PROPERTIES
+ if (m_xCurrentProp->hasValueFor(aLocale))
+ {
+ getResultWriter()->setPropertyValueForLocale(m_xCurrentProp->getValueFor(aLocale),aLocale);
+ }
+ else
+ {
+ OSL_ENSURE(m_xCurrentProp->hasResetFor(aLocale),"LayerUpdateMerger: ERROR: Unknown change type in PropertyUpdate");
+ // write nothing to result
+ }
+
+ // mark handled
+ m_xCurrentProp->removeValueFor(aLocale);
+#endif
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::addProperty(aName, aAttributes, aType);
+ return;
+ }
+ OSL_ASSERT( m_xCurrentNode.is());
+
+ rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getPropertyByName(aName);
+ if (!xUpdate.is())
+ {
+ BasicUpdateMerger::addProperty(aName, aAttributes, aType);
+ return;
+ }
+
+ m_xCurrentNode->removePropertyByName(aName);
+
+ if (PropertyUpdate * pPropUpdate = xUpdate->asPropertyUpdate())
+ {
+ if (pPropUpdate->hasValue() && pPropUpdate->getValue().hasValue())
+ {
+ // TODO: validate value-type
+ uno::Any aNewValue = pPropUpdate->getValue();
+ OSL_ASSERT( aNewValue.hasValue() );
+
+ if (aNewValue.getValueType() != aType)
+ malformedUpdate("LayerUpdateMerger: cannot do type conversion while writing updates");
+
+ getResultWriter()->addPropertyWithValue(aName, pPropUpdate->updateFlags(aAttributes), aNewValue);
+ }
+ else
+ {
+ // TODO: validate type
+ if (pPropUpdate->getValueType() != aType && pPropUpdate->getValueType() != uno::Type())
+ malformedUpdate("LayerUpdateMerger: types for property update do not match");
+
+ OSL_ENSURE(!pPropUpdate->hasReset(),"Warning: resetting the value of an added property is undefined - reverting to NULL");
+ getResultWriter()->addProperty(aName, pPropUpdate->updateFlags(aAttributes), aType);
+ }
+ }
+ else
+ {
+ xUpdate->writeToLayer(getResultWriter().get());
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerUpdateMerger::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (BasicUpdateMerger::isHandling())
+ {
+ BasicUpdateMerger::addPropertyWithValue(aName, aAttributes, aValue);
+ return;
+ }
+ OSL_ASSERT( m_xCurrentNode.is());
+
+ rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getPropertyByName(aName);
+ if (!xUpdate.is())
+ {
+ BasicUpdateMerger::addPropertyWithValue(aName, aAttributes, aValue);
+ return;
+ }
+
+ m_xCurrentNode->removePropertyByName(aName);
+
+ if (PropertyUpdate * pPropUpdate = xUpdate->asPropertyUpdate())
+ {
+ if (!pPropUpdate->hasChange()) // attribute change only
+ {
+ getResultWriter()->addPropertyWithValue(aName, pPropUpdate->updateFlags(aAttributes), aValue);
+ }
+ else if (pPropUpdate->hasReset())
+ {
+ // write nothing
+ }
+ else if (pPropUpdate->getValue().hasValue()) // setting to non-NULL value
+ {
+ OSL_ASSERT(pPropUpdate->hasValue());
+
+ // TODO: validate value-type
+ uno::Any aNewValue = pPropUpdate->getValue();
+
+ if (aNewValue.getValueType() != aValue.getValueType())
+ malformedUpdate("LayerUpdateMerger: cannot do type conversion while writing updates");
+
+ getResultWriter()->addPropertyWithValue(aName, pPropUpdate->updateFlags(aAttributes), aNewValue);
+ }
+ else // setting to null value
+ {
+ OSL_ASSERT(pPropUpdate->hasValue());
+
+ // TODO: validate type
+ if (pPropUpdate->getValueType() != aValue.getValueType() && pPropUpdate->getValueType() != uno::Type())
+ malformedUpdate("LayerUpdateMerger: types for property update do not match");
+
+ getResultWriter()->addProperty(aName, pPropUpdate->updateFlags(aAttributes), aValue.getValueType());
+ }
+ }
+ else
+ {
+ xUpdate->writeToLayer(getResultWriter().get());
+ }
+}
+// -----------------------------------------------------------------------------
+
+void LayerUpdateMerger::malformedUpdate(sal_Char const * pMsg)
+{
+ { (void)pMsg; }
+ OSL_ENSURE(false,pMsg);
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/layerupdatemerger.hxx b/configmgr/source/backend/layerupdatemerger.hxx
new file mode 100644
index 000000000000..5e421182d3c7
--- /dev/null
+++ b/configmgr/source/backend/layerupdatemerger.hxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerupdatemerger.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_LAYERUPDATEMERGER_HXX
+#define CONFIGMGR_BACKEND_LAYERUPDATEMERGER_HXX
+
+#include "basicupdatemerger.hxx"
+#include "layerupdate.hxx"
+#include <rtl/ref.hxx>
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ class NodeUpdate;
+ class PropertyUpdate;
+
+ class LayerUpdateMerger : protected BasicUpdateMerger
+ {
+ public:
+ static uno::Reference< backenduno::XLayer > getMergedLayer(uno::Reference< backenduno::XLayer > const & _xSourceLayer, LayerUpdate const & _aLayerUpdate)
+ { return new LayerUpdateMerger(_xSourceLayer, _aLayerUpdate); }
+
+ public:
+ explicit
+ LayerUpdateMerger( uno::Reference< backenduno::XLayer > const & _xSourceLayer, LayerUpdate const & _aLayerUpdate);
+
+ ~LayerUpdateMerger();
+
+
+ // XLayerHandler overrides
+ protected:
+ virtual void SAL_CALL
+ startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ // BasicUpdateMerger
+ virtual void flushUpdate();
+ private:
+ void malformedUpdate(sal_Char const * pMsg);
+ private:
+ LayerUpdate m_aLayerUpdate;
+ rtl::Reference<NodeUpdate> m_xCurrentNode;
+ rtl::Reference<PropertyUpdate> m_xCurrentProp;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/makefile.mk b/configmgr/source/backend/makefile.mk
new file mode 100644
index 000000000000..97e372929fb7
--- /dev/null
+++ b/configmgr/source/backend/makefile.mk
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.16 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJINC=$(PRJ)$/source
+PRJNAME=configmgr
+TARGET=backend
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+# --- Files ---
+
+
+SLOFILES=\
+ $(SLO)$/mergedcomponentdata.obj \
+ $(SLO)$/componentdatahelper.obj \
+ $(SLO)$/schemabuilder.obj \
+ $(SLO)$/layermerge.obj \
+ $(SLO)$/updatesvc.obj \
+ $(SLO)$/layerupdatehandler.obj \
+ $(SLO)$/basicupdatemerger.obj \
+ $(SLO)$/layerupdatemerger.obj \
+ $(SLO)$/layerupdatebuilder.obj \
+ $(SLO)$/layerupdate.obj \
+ $(SLO)$/updatedata.obj \
+ $(SLO)$/updatedispatch.obj \
+ $(SLO)$/singlebackendadapter.obj \
+ $(SLO)$/backendaccess.obj \
+ $(SLO)$/backendfactory.obj \
+ $(SLO)$/importsvc.obj \
+ $(SLO)$/basicimporthandler.obj \
+ $(SLO)$/importmergehandler.obj \
+ $(SLO)$/layerdefaultremover.obj \
+ $(SLO)$/emptylayer.obj \
+ $(SLO)$/binarywriter.obj \
+ $(SLO)$/binaryreader.obj \
+ $(SLO)$/binarywritehandler.obj \
+ $(SLO)$/binaryreadhandler.obj \
+ $(SLO)$/binarycache.obj \
+ $(SLO)$/backendnotifier.obj \
+ $(SLO)$/backendstratalistener.obj \
+ $(SLO)$/multistratumbackend.obj \
+
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/backend/mergedcomponentdata.cxx b/configmgr/source/backend/mergedcomponentdata.cxx
new file mode 100644
index 000000000000..92d9971a32ed
--- /dev/null
+++ b/configmgr/source/backend/mergedcomponentdata.cxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mergedcomponentdata.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "mergedcomponentdata.hxx"
+#include "treenodefactory.hxx"
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+MergedComponentData::MergedComponentData( )
+: m_pSchemaTree()
+, m_pTemplatesTree()
+{
+
+}
+// -----------------------------------------------------------------------------
+
+MergedComponentData::~MergedComponentData( )
+{
+
+}
+// -----------------------------------------------------------------------------
+
+void MergedComponentData::clear( )
+{
+ m_pTemplatesTree.reset();
+ m_pSchemaTree.reset();
+}
+// -----------------------------------------------------------------------------
+
+bool MergedComponentData::hasSchema()const
+{
+ return m_pSchemaTree.get() != NULL;
+}
+// -----------------------------------------------------------------------------
+
+
+bool MergedComponentData::hasTemplates() const
+{
+ return m_pTemplatesTree.get() != NULL;
+}
+// -----------------------------------------------------------------------------
+
+rtl::OUString MergedComponentData::getTemplateAccessor (backenduno::TemplateIdentifier const & _aTemplateName) const
+{
+ return _aTemplateName.Name;
+}
+// -----------------------------------------------------------------------------
+
+bool MergedComponentData::hasTemplate(rtl::OUString const & _aTemplateName) const
+{
+ return m_pTemplatesTree.get() != NULL &&
+ m_pTemplatesTree->getChild( _aTemplateName ) != NULL;
+}
+// -----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> MergedComponentData::extractSchemaTree()
+{
+ return m_pSchemaTree;
+}
+// -----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> MergedComponentData::extractTemplatesTree()
+{
+ return m_pTemplatesTree;
+}
+// -----------------------------------------------------------------------------
+
+std::auto_ptr<INode> MergedComponentData::extractTemplateNode(rtl::OUString const & _aTemplateName)
+{
+ if (m_pTemplatesTree.get() == NULL)
+ return std::auto_ptr<INode>();
+
+ return m_pTemplatesTree->removeChild(_aTemplateName);
+}
+// -----------------------------------------------------------------------------
+
+ISubtree const * MergedComponentData::findTemplate(rtl::OUString const & _aTemplateName) const
+{
+ INode const * pTemplateNode = m_pTemplatesTree->getChild(_aTemplateName);
+
+ ISubtree const * pTemplateTree = pTemplateNode ? pTemplateNode->asISubtree() : NULL;
+
+ OSL_ENSURE(pTemplateTree || !pTemplateNode, "ERROR: Template is not a subtree");
+
+ return pTemplateTree;
+}
+// -----------------------------------------------------------------------------
+
+std::auto_ptr<INode> MergedComponentData::instantiateTemplate(rtl::OUString const & _aName, rtl::OUString const & _aTemplateName) const
+{
+ if (INode const * pTemplateNode = m_pTemplatesTree->getChild(_aTemplateName))
+ {
+ std::auto_ptr<INode> aResult = pTemplateNode->clone();
+ aResult->setName(_aName);
+ return aResult;
+ }
+ else
+ {
+ return std::auto_ptr<INode>();
+ }
+}
+// -----------------------------------------------------------------------------
+
+ISubtree * MergedComponentData::setSchemaRoot(std::auto_ptr<ISubtree> _aSchemaRoot)
+{
+ OSL_PRECOND(_aSchemaRoot.get(),"ERROR: Setting a NULL schema root.");
+ OSL_PRECOND(!hasSchema(),"ERROR: Schema root already set");
+
+ m_pSchemaTree = _aSchemaRoot;
+
+ return m_pSchemaTree.get();
+}
+// -----------------------------------------------------------------------------
+void MergedComponentData::setTemplatesTree(std::auto_ptr<ISubtree> _aTemplateTree)
+{
+ OSL_PRECOND(!hasTemplates(),"ERROR: Template Tree already set");
+ m_pTemplatesTree = _aTemplateTree;
+}
+// -----------------------------------------------------------------------------
+ISubtree * MergedComponentData::addTemplate(std::auto_ptr<ISubtree> _aNode, backenduno::TemplateIdentifier const & aTemplate)
+{
+ OSL_PRECOND(_aNode.get(), "ERROR: Adding a NULL template");
+
+ if (!m_pTemplatesTree.get())
+ {
+ m_pTemplatesTree = getDefaultTreeNodeFactory().createGroupNode( aTemplate.Component, node::Attributes() );
+ }
+ else
+ {
+ OSL_ENSURE(m_pTemplatesTree->getName().equals(aTemplate.Component),
+ "Template Component names do not match");
+ }
+
+ return m_pTemplatesTree->addChild( base_ptr(_aNode) )->asISubtree();
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/mergedcomponentdata.hxx b/configmgr/source/backend/mergedcomponentdata.hxx
new file mode 100644
index 000000000000..dfc7153a3e75
--- /dev/null
+++ b/configmgr/source/backend/mergedcomponentdata.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mergedcomponentdata.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */
+
+#ifndef CONFIGMGR_BACKEND_MERGEDCOMPONENTDATA_HXX
+#define CONFIGMGR_BACKEND_MERGEDCOMPONENTDATA_HXX
+
+#include "valuenode.hxx"
+
+#include <com/sun/star/configuration/backend/TemplateIdentifier.hpp>
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ class OTreeNodeFactory;
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace backenduno = ::com::sun::star::configuration::backend;
+
+// -----------------------------------------------------------------------------
+
+ class MergedComponentData
+ {
+ public:
+ MergedComponentData();
+ ~MergedComponentData();
+
+ bool hasSchema() const;
+ bool hasTemplates() const;
+ bool hasTemplate(rtl::OUString const & _aTemplateName) const;
+
+ rtl::OUString getTemplateAccessor (backenduno::TemplateIdentifier const & _aTemplateName) const;
+
+ ISubtree const * getSchemaTree() const { return m_pSchemaTree.get(); }
+ ISubtree const * getTemplatesTree() const { return m_pTemplatesTree.get(); }
+ ISubtree const * findTemplate(rtl::OUString const & _aTemplateName) const;
+
+ ISubtree * getSchemaTree() { return m_pSchemaTree.get(); }
+ ISubtree * getTemplatesTree() { return m_pTemplatesTree.get(); }
+
+ std::auto_ptr<INode> instantiateTemplate(rtl::OUString const & _aName, rtl::OUString const & _aTemplateName) const;
+
+ void clear();
+
+ ISubtree * setSchemaRoot(std::auto_ptr<ISubtree> _aSchemaRoot);
+ ISubtree * addTemplate(std::auto_ptr<ISubtree> _aNode, backenduno::TemplateIdentifier const & aTemplate);
+ void setTemplatesTree(std::auto_ptr<ISubtree> _aTemplateTree);
+
+ std::auto_ptr<ISubtree> extractSchemaTree();
+ std::auto_ptr<ISubtree> extractTemplatesTree();
+ std::auto_ptr<INode> extractTemplateNode(rtl::OUString const & _aTemplateName);
+ private:
+ std::auto_ptr<ISubtree> m_pSchemaTree;
+ std::auto_ptr<ISubtree> m_pTemplatesTree;
+
+ };
+// -----------------------------------------------------------------------------
+
+ } // namespace backend
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/multistratumbackend.cxx b/configmgr/source/backend/multistratumbackend.cxx
new file mode 100644
index 000000000000..c46610f29030
--- /dev/null
+++ b/configmgr/source/backend/multistratumbackend.cxx
@@ -0,0 +1,934 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: multistratumbackend.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "multistratumbackend.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif // CONFIGMGR_API_FACTORY_HXX_
+#include "serviceinfohelper.hxx"
+#include "backendstratalistener.hxx"
+
+#ifndef _CONFIGMGR_BOOTSTRAP_HXX
+#include "bootstrap.hxx"
+#endif
+#include "simpleinteractionrequest.hxx"
+#include "configinteractionhandler.hxx"
+#include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
+#include <com/sun/star/configuration/backend/XSingleLayerStratum.hpp>
+#include <com/sun/star/configuration/backend/StratumCreationException.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <rtl/ustrbuf.hxx>
+
+#include <cppuhelper/exc_hlp.hxx>
+
+#include <stdio.h>
+
+//==============================================================================
+#define OU2A(rtlOUString) (::rtl::OUStringToOString((rtlOUString), RTL_TEXTENCODING_ASCII_US).getStr())
+//==============================================================================
+
+namespace {
+
+namespace css = com::sun::star;
+
+}
+
+namespace configmgr { namespace backend {
+
+//==============================================================================
+static const rtl::OUString kSchemaServiceParam(
+ RTL_CONSTASCII_USTRINGPARAM( CONTEXT_ITEM_PREFIX_ "SchemaSupplier"));
+
+static const rtl::OUString kStrataServiceParam(
+ RTL_CONSTASCII_USTRINGPARAM( CONTEXT_ITEM_PREFIX_ "Strata"));
+
+static const rtl::OUString kEntity(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"EntityLayer")) ;
+
+static const rtl::OUString kAdminModeFlag(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_ADMINFLAG)) ;
+
+static const rtl::OUString kThisOwnerEntity(
+ RTL_CONSTASCII_USTRINGPARAM("<ThisOwnerEntity>")) ;
+
+//------------------------------------------------------------------------------
+bool checkOptionalArg(rtl::OUString& aArg)
+ {
+ if (aArg.getLength() && aArg[0] == sal_Unicode('?'))
+ {
+ aArg = aArg.copy(1);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+//------------------------------------------------------------------------------
+void parseStrataInfo(const rtl::OUString aServiceList,
+ std::vector< std::pair<rtl::OUString, rtl::OUString> >& aServiceInfoList,
+ const uno::Reference<uno::XInterface>& pContext)
+{
+ sal_Int32 nNextToken =0;
+ sal_Int32 nLength = aServiceList.getLength();
+
+ do
+ {
+ rtl::OUString aServiceName =aServiceList.getToken(0, ':',nNextToken);
+ if((nNextToken ==-1)||(aServiceName.getLength()==0))
+ {
+ throw backenduno::BackendSetupException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Malformed Strata Service specified")),
+ pContext, uno::Any()) ;
+ }
+ rtl::OUString aServiceData = aServiceList.getToken(0, ';',nNextToken);
+
+ std::pair<rtl::OUString, rtl::OUString> aServiceInfo(aServiceName,aServiceData);
+ aServiceInfoList.push_back(aServiceInfo);
+ }
+ while (nNextToken >= 0 && nNextToken < nLength ) ;
+}
+//------------------------------------------------------------------------------
+MultiStratumBackend::MultiStratumBackend(
+ const uno::Reference<uno::XComponentContext>& xContext)
+ : cppu::WeakComponentImplHelper7< backenduno::XBackend, backenduno::XBackendEntities, backenduno::XVersionedSchemaSupplier, backenduno::XBackendChangesNotifier, backenduno::XBackendChangesListener, lang::XInitialization, lang::XServiceInfo >(mMutex), mFactory(xContext->getServiceManager(),uno::UNO_QUERY_THROW)
+ ,mListenerList()
+{
+
+}
+//------------------------------------------------------------------------------
+
+MultiStratumBackend::~MultiStratumBackend()
+{
+}
+//------------------------------------------------------------------------------
+bool MultiStratumBackend::checkOkState()
+{
+ if (!mSchemaSupplier.is())
+ {
+ if(rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MultiStratumBackend: Backends already disposed")),*this);
+ }
+ else
+ {
+ throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MultiStratumBackend: Object was never Initialised")),*this);
+ }
+ }
+ return true;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL MultiStratumBackend::initialize(
+ const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ css::configuration::InvalidBootstrapFileException,
+ backenduno::BackendSetupException) {
+
+ if (aParameters.getLength() == 0) {
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "No parameters provided to MultiStratumBackend")),
+ *this, 0) ;
+ }
+
+ uno::Reference<uno::XComponentContext> context ;
+
+ for (sal_Int32 i = 0 ; i < aParameters.getLength() ; ++ i) {
+ if (aParameters [i] >>= context) { break ; }
+ }
+
+
+ try
+ {
+ //Initialize Backends
+ initializeSchemaSupplier (context);
+ initializeBackendStrata(context);
+
+ sal_Bool bAdminMode = false;
+ context->getValueByName(kAdminModeFlag) >>= bAdminMode;
+
+ if (bAdminMode)
+ {
+ // find given entity
+ rtl::OUString sDefaultEntity;
+ if ( (context->getValueByName(kEntity) >>= sDefaultEntity) && sDefaultEntity.getLength() )
+ {
+ for (sal_uInt32 i = 0; i < mBackendStrata.size(); i++)
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( mBackendStrata[i], uno::UNO_QUERY );
+ if (xEntities.is()&& xEntities->supportsEntity(sDefaultEntity))
+ {
+ mBackendStrata.resize(i+1);
+ mOwnerEntity = sDefaultEntity;
+ break;
+ }
+ }
+ }
+ else
+ {
+ mBackendStrata.resize(1);
+ }
+ }
+
+ if(mOwnerEntity.getLength()==0)
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities(
+ mBackendStrata[mBackendStrata.size()-1], uno::UNO_QUERY );
+ if (xEntities.is())
+ {
+ mOwnerEntity = xEntities->getOwnerEntity();
+ }
+ else
+ {
+ mOwnerEntity = kThisOwnerEntity;
+ }
+ }
+ mStrataListener = new BackendStrataListener(*this);
+
+ }
+ catch(uno::Exception& )
+ {
+ mSchemaSupplier.clear();
+ mBackendStrata.clear() ;
+
+ throw;
+ }
+
+}
+//------------------------------------------------------------------------------
+void MultiStratumBackend::initializeSchemaSupplier(const uno::Reference<uno::XComponentContext>& aContext)
+{
+
+ rtl::OUString aServiceName;
+
+ aContext->getValueByName(kSchemaServiceParam) >>= aServiceName;
+ uno::Sequence< uno::Any > aInitArgs( 1 );
+ aInitArgs[0] <<= aContext;
+ mSchemaSupplier = uno::Reference<backenduno::XSchemaSupplier>::query(mFactory->createInstanceWithArguments(aServiceName,aInitArgs)) ;
+ if (!mSchemaSupplier.is())
+ {
+ throw backenduno::BackendSetupException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MultiStratumBackend: Could not create Schema Supplier service")),
+ *this, uno::Any()) ;
+
+ }
+}
+//------------------------------------------------------------------------------
+static
+bool approveRecovery(const backenduno::StratumCreationException & aError)
+{
+ sal_uInt32 const k_supported_choices = apihelper::CONTINUATION_APPROVE ; //| apihelper::CONTINUATION_DISAPPROVE;
+
+ sal_uInt32 chosen = apihelper::CONTINUATION_UNKNOWN;
+
+ apihelper::ConfigurationInteractionHandler handler;
+ try {
+ uno::Reference< css::task::XInteractionHandler > h(handler.get());
+ if (h.is()) {
+ rtl::Reference< apihelper::SimpleInteractionRequest > req(
+ new apihelper::SimpleInteractionRequest(
+ uno::makeAny(aError), k_supported_choices));
+ h->handle(req.get());
+ chosen = req->getResponse();
+ }
+ } catch (uno::Exception & e) {
+ OSL_TRACE("Warning - Configuration: Interaction handler failed: [%s]\n", OU2A(e.Message));
+ }
+
+ switch (chosen)
+ {
+ case apihelper::CONTINUATION_APPROVE: return true;
+ case apihelper::CONTINUATION_DISAPPROVE: return false;
+ case apihelper::CONTINUATION_UNKNOWN: break;
+
+ default: OSL_ENSURE(false,"Unsolicited continuation chosen"); break;
+ }
+ // no choice available - default: disapprove
+ return false;
+}
+//------------------------------------------------------------------------------
+void MultiStratumBackend::initializeBackendStrata(const uno::Reference<uno::XComponentContext>& aContext)
+{
+
+ rtl::OUString sStrata;
+ //Get Strata
+ aContext->getValueByName(kStrataServiceParam) >>= sStrata;
+ if(sStrata.getLength()==0)
+ {
+ throw backenduno::BackendSetupException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MultiStratumBackend: No Strata Services Specified")),
+ *this, uno::Any()) ;
+
+ }
+
+ //need to parse the Strata to extract service names and data location
+ std::vector< std::pair<rtl::OUString, rtl::OUString> > aServiceInfoList;
+ parseStrataInfo(sStrata,aServiceInfoList,*this);
+
+ for (std::vector< std::pair<rtl::OUString, rtl::OUString> >::const_iterator it = aServiceInfoList.begin(); it != aServiceInfoList.end(); ++it)
+ {
+ uno::Sequence< uno::Any > aInitArgs( 1 );
+ rtl::OUString sServiceName = it->first;
+ const rtl::OUString& sServiceData = it->second;
+ aInitArgs[0] <<= sServiceData;
+ uno::Reference <uno::XInterface> xBackend;
+ bool bOptional = checkOptionalArg(sServiceName);
+
+ try
+ {
+ xBackend= mFactory->createInstanceWithArguments(sServiceName,aInitArgs);
+ }
+ catch (uno::Exception& exception)
+ {
+ if(!bOptional)
+ {
+ static const sal_Char sErrContext[] = "MultiStratumBackend: Could not create Backend Stratum Service: ";
+ rtl::OUString const sContext(RTL_CONSTASCII_USTRINGPARAM(sErrContext));
+ rtl::OUString const sMessage = sContext.concat(exception.Message);
+
+ backenduno::StratumCreationException error(sMessage,*this,
+ ::cppu::getCaughtException(),
+ sServiceName,sServiceData);
+ if (!approveRecovery(error))
+ throw error;
+ }
+
+ }
+ if (xBackend.is())
+ {
+ mBackendStrata.push_back(xBackend) ;
+ }
+ }
+}
+//---------------------------------------------------------------------------------------------
+// XBackendEntities
+rtl::OUString SAL_CALL
+ MultiStratumBackend::getOwnerEntity( )
+ throw (uno::RuntimeException)
+{
+
+ if (checkOkState())
+ {
+ return mOwnerEntity;
+ }
+ return rtl::OUString();
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL
+ MultiStratumBackend::getAdminEntity()
+ throw (uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+ if (checkOkState())
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( mBackendStrata[0], uno::UNO_QUERY );
+ if(xEntities.is())
+ {
+ return xEntities->getAdminEntity();
+ }
+ else
+ {
+ return rtl::OUString();
+ }
+ }
+ return rtl::OUString();
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL
+ MultiStratumBackend::supportsEntity( const rtl::OUString& aEntity )
+ throw (backenduno::BackendAccessException, uno::RuntimeException)
+{
+
+ osl::MutexGuard aGuard(mMutex);
+ if (checkOkState())
+ {
+ for (std::vector< uno::Reference <uno::XInterface> >::const_iterator it = mBackendStrata.begin(); it != mBackendStrata.end(); ++it)
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( *it, uno::UNO_QUERY );
+ if (xEntities.is())
+ {
+ if( xEntities->supportsEntity(aEntity))
+ return true;
+ }
+ }
+ return false;
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL
+ MultiStratumBackend::isEqualEntity( const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity )
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+ if (aEntity.getLength() == 0)
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Invalid empty entity."));
+
+ throw lang::IllegalArgumentException(sMsg, *this, 1);
+ }
+ if (aOtherEntity.getLength() == 0)
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Invalid empty entity."));
+
+ throw lang::IllegalArgumentException(sMsg, *this, 2);
+ }
+
+
+ if (aEntity.equals(aOtherEntity))
+ {
+ return true;
+ }
+
+ if (checkOkState())
+ {
+ for (std::vector< uno::Reference <uno::XInterface> >::const_iterator it = mBackendStrata.begin(); it != mBackendStrata.end(); ++it)
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( *it, uno::UNO_QUERY );
+ if (xEntities.is())
+ {
+ if( xEntities->supportsEntity(aEntity))
+ return xEntities->isEqualEntity(aEntity,aOtherEntity);
+ }
+ }
+ return false;
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL
+ MultiStratumBackend::getSchemaVersion(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+
+ if (checkOkState())
+ {
+ uno::Reference<backenduno::XVersionedSchemaSupplier> xVersionSupplier(mSchemaSupplier,uno::UNO_QUERY);
+ if (xVersionSupplier.is())
+ return xVersionSupplier->getSchemaVersion(aComponent) ;
+ }
+ return rtl::OUString();
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backenduno::XSchema> SAL_CALL
+ MultiStratumBackend::getComponentSchema(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+
+ if (checkOkState())
+ {
+ return mSchemaSupplier->getComponentSchema(aComponent) ;
+ }
+ return NULL;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ MultiStratumBackend::listOwnLayers(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ return listLayers(aComponent, mOwnerEntity ) ;
+ }
+ return uno::Sequence<uno::Reference<backenduno::XLayer> >() ;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ MultiStratumBackend::getOwnUpdateHandler(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::NoSupportException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ return getUpdateHandler(aComponent, mOwnerEntity) ;
+ }
+ return NULL;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ MultiStratumBackend::listLayers(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+
+ osl::MutexGuard aGuard(mMutex);
+ if (checkOkState())
+ {
+ sal_Int32 nNumSupportedLayers = mBackendStrata.size();
+ if(aEntity != mOwnerEntity)
+ {
+ nNumSupportedLayers = findSupportingStratum(aEntity);
+ }
+ return searchSupportingStrata(nNumSupportedLayers,aEntity,aComponent);
+ }
+ return uno::Sequence<uno::Reference<backenduno::XLayer> >();
+}
+//------------------------------------------------------------------------------
+sal_Int32 MultiStratumBackend::findSupportingStratum(const rtl::OUString& aEntity)
+{
+ sal_Int32 nNumLayers = mBackendStrata.size();
+ for (std::vector< uno::Reference <uno::XInterface> >::reverse_iterator it = mBackendStrata.rbegin(); it != mBackendStrata.rend(); ++it)
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( *it, uno::UNO_QUERY );
+ if (xEntities.is())
+ {
+ if( xEntities->supportsEntity(aEntity))
+ {
+ return nNumLayers;
+ }
+ }
+ nNumLayers--;
+ }
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("\n MultiStratumBackend: No Backend supports Entity: \"");
+ sMsg.append(aEntity);
+ throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),
+ *this, 0) ;
+}
+//------------------------------------------------------------------------------
+uno::Sequence<uno::Reference<backenduno::XLayer> >
+ MultiStratumBackend::searchSupportingStrata(sal_Int32 nNumLayers,
+ rtl::OUString aEntity,
+ const rtl::OUString& aComponent)
+{
+ uno::Sequence<uno::Reference<backenduno::XLayer> > aLayers;
+ std::vector<uno::Reference<backenduno::XLayer> > aBackendLayers;
+ for (sal_Int32 i = 0 ; i < nNumLayers ; ++ i)
+ {
+ uno::Sequence<uno::Reference<backenduno::XLayer> > aMultiLayers;
+ uno::Reference< backenduno::XBackendEntities > xEntities(mBackendStrata[i], uno::UNO_QUERY );
+
+ uno::Reference<backenduno::XBackend> xBackend(mBackendStrata[i], uno::UNO_QUERY) ;
+ if (xBackend.is())
+ {
+ if (xEntities.is())
+ {
+ if( !xEntities->supportsEntity(aEntity))
+ {
+ aEntity = xEntities->getOwnerEntity();
+ }
+ aMultiLayers = xBackend->listLayers(aComponent, aEntity) ;
+ }
+ else
+ {
+ aMultiLayers = xBackend->listOwnLayers(aComponent);
+ }
+ }
+ else
+ {
+ uno::Reference<backenduno::XMultiLayerStratum> xMultiLayerStratum(
+ mBackendStrata[i], uno::UNO_QUERY) ;
+
+ if (xMultiLayerStratum.is())
+ {
+ if (xEntities.is())
+ {
+ if( !xEntities->supportsEntity(aEntity))
+ {
+ aEntity = xEntities->getOwnerEntity();
+ }
+ aMultiLayers = xMultiLayerStratum->getLayers(
+ xMultiLayerStratum->listLayerIds(aComponent, aEntity),
+ rtl::OUString()) ;
+
+ }
+ else
+ {
+ throw backenduno::BackendSetupException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MultiStratumBackend: XMultiLayerStratum must support XBackendEntities")),
+ *this, uno::Any()) ;
+ }
+
+ }
+ else
+ {
+ uno::Reference<backenduno::XSingleLayerStratum> xSingleLayerStratum(
+ mBackendStrata[i], uno::UNO_REF_QUERY_THROW) ;
+ if (xSingleLayerStratum.is())
+ {
+ uno::Reference<backenduno::XLayer> xLayer = xSingleLayerStratum->getLayer( aComponent, rtl::OUString());
+ //Could be an empty layer
+ if (xLayer.is())
+ {
+ aBackendLayers.push_back(xLayer);
+ }
+ }
+ }
+ }
+ // There might be non-existent layers in the list if there's no
+ // actual data associated to a given layer id. Hence we have to
+ // compress the list.
+ for (sal_Int32 j = 0 ; j < aMultiLayers.getLength() ; ++j)
+ {
+ if (aMultiLayers [j].is())
+ {
+ aBackendLayers.push_back( aMultiLayers[j]);
+ }
+ }
+ }
+ aLayers.realloc(aBackendLayers.size());
+ for (sal_uInt32 k =0; k < aBackendLayers.size();k++)
+ {
+ aLayers[k] = aBackendLayers[k];
+ }
+ return aLayers;
+}
+//------------------------------------------------------------------------------
+uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ MultiStratumBackend::getUpdateHandler(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::NoSupportException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+
+ if (checkOkState())
+ {
+
+ sal_Int32 nNumSupportedLayers = mBackendStrata.size();
+ rtl::OUString aUsedEntity;
+
+ if(aEntity != mOwnerEntity)
+ {
+ nNumSupportedLayers = findSupportingStratum(aEntity);
+ aUsedEntity = aEntity;
+ }
+ else
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( mBackendStrata[mBackendStrata.size()-1], uno::UNO_QUERY );
+ if (xEntities.is())
+ {
+ aUsedEntity = xEntities->getOwnerEntity();
+ }
+ }
+ sal_Int32 nStrataIndex = nNumSupportedLayers -1;
+
+ uno::Reference<backenduno::XBackend> xBackend(
+ mBackendStrata[nStrataIndex], uno::UNO_QUERY) ;
+ uno::Reference< uno::XInterface > xHandler;
+ if(xBackend.is())
+ {
+ if (aUsedEntity.getLength()==0)
+ {
+ xHandler = xBackend->getOwnUpdateHandler(aComponent) ;
+ return uno::Reference<backenduno::XUpdateHandler>(xHandler,uno::UNO_REF_QUERY_THROW);
+ }
+ else
+ {
+ xHandler = xBackend->getUpdateHandler(aComponent, aUsedEntity) ;
+ return uno::Reference<backenduno::XUpdateHandler>(xHandler,uno::UNO_REF_QUERY_THROW);
+ }
+ }
+ else
+ {
+
+ uno::Sequence<uno::Any> arguments(1) ;
+
+ uno::Reference< backenduno::XMultiLayerStratum > xMultiLayerStratum
+ (mBackendStrata[nStrataIndex], uno::UNO_QUERY );
+ if(xMultiLayerStratum.is())
+ {
+ arguments [0] <<= xMultiLayerStratum->getUpdatableLayer(
+ xMultiLayerStratum->getUpdateLayerId(aComponent,aUsedEntity));
+ }
+ else
+ {
+ uno::Reference< backenduno::XSingleLayerStratum > xSingleLayerStratum(
+ mBackendStrata[nStrataIndex], uno::UNO_REF_QUERY_THROW );
+
+ arguments [0] <<= xSingleLayerStratum->getUpdatableLayer(aComponent);
+
+ }
+
+ if(!xHandler.is())
+ {
+ try
+ {
+ const rtl::OUString kUpdateMerger(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.backend.LayerUpdateMerger")) ;
+
+
+ if(!mFactory.is())
+ {
+ throw lang::DisposedException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "MultiStratumBackend: Service Factory already dispoed")),*this);
+ }
+
+ xHandler = mFactory->createInstanceWithArguments(kUpdateMerger, arguments);
+ }
+ catch (uno::RuntimeException & )
+ {throw;}
+ catch (uno::Exception & e)
+ {
+ const rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM(
+ "Configuration MultiStratumBackend: Cannot create UpdateMerger - error message: ")) ;
+ throw uno::RuntimeException(sMessage.concat(e.Message),*this);
+ }
+ }
+ return uno::Reference<backenduno::XUpdateHandler>(xHandler, uno::UNO_REF_QUERY_THROW) ;
+ }
+ }
+ return NULL;
+}
+// ---------------------------------------------------------------------------
+// ComponentHelper
+void SAL_CALL MultiStratumBackend::disposing()
+{
+ osl::MutexGuard aGuard(mMutex);
+ if (mFactory.is())
+ {
+ mFactory.clear();
+ }
+ if (mSchemaSupplier.is())
+ {
+ uno::Reference< lang::XComponent> xComp( mSchemaSupplier, uno::UNO_QUERY);
+ if (xComp.is())
+ {
+ xComp->dispose();
+ }
+ if (mSchemaSupplier.is())
+ {
+ mSchemaSupplier.clear();
+ }
+ }
+ if (!mBackendStrata.empty())
+ {
+ for (std::vector< uno::Reference <uno::XInterface> >::const_iterator it = mBackendStrata.begin(); it != mBackendStrata.end(); ++it)
+ {
+ uno::Reference< lang::XComponent> xComp( *it, uno::UNO_QUERY );
+ if (xComp.is())
+ {
+ try
+ {
+ xComp->dispose();
+ }
+ catch(uno::Exception &){}
+ }
+ }
+ mBackendStrata.clear();
+
+ }
+
+ }
+//------------------------------------------------------------------------------
+
+static const sal_Char * const kBackendService = "com.sun.star.configuration.backend.Backend" ;
+
+static const sal_Char * const kImplementation =
+ "com.sun.star.comp.configuration.backend.MultiStratumBackend" ;
+
+static sal_Char const * const kServiceNames [] =
+{
+ kBackendService,
+ 0
+} ;
+static const ServiceImplementationInfo kServiceInfo =
+{
+ kImplementation,
+ kServiceNames,
+ 0
+} ;
+
+const ServiceRegistrationInfo *getMultiStratumBackendServiceInfo()
+{
+ return getRegistrationInfo(&kServiceInfo) ;
+}
+
+uno::Reference<uno::XInterface> SAL_CALL
+ instantiateMultiStratumBackend(const uno::Reference< uno::XComponentContext >& xContext)
+{
+ return *new MultiStratumBackend(xContext) ;
+}
+//------------------------------------------------------------------------------
+
+static const rtl::OUString kImplementationName(
+ RTL_CONSTASCII_USTRINGPARAM(kImplementation)) ;
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL
+ MultiStratumBackend::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).getImplementationName() ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL
+ MultiStratumBackend::supportsService(const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).supportsService(aServiceName) ;
+}
+//------------------------------------------------------------------------------
+uno::Sequence<rtl::OUString> SAL_CALL
+ MultiStratumBackend::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ;
+}
+//------------------------------------------------------------------------------
+void SAL_CALL MultiStratumBackend::addChangesListener( const uno::Reference<backenduno::XBackendChangesListener>& xListener,
+ const rtl::OUString& aComponent)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+ if(checkOkState())
+ {
+
+ mListenerList.insert( ListenerList::value_type(aComponent, xListener));
+ //Now register with lower layers
+ for (sal_uInt32 i = 0 ; i < mBackendStrata.size() ; ++ i)
+ {
+ uno::Reference<backenduno::XBackendChangesNotifier> xBackend(mBackendStrata[i], uno::UNO_QUERY) ;
+ if (xBackend.is())
+ {
+ xBackend->addChangesListener(mStrataListener, aComponent);
+ }
+ }
+ }
+}
+//------------------------------------------------------------------------------
+void SAL_CALL MultiStratumBackend::removeChangesListener( const uno::Reference<backenduno::XBackendChangesListener>& /*xListner*/,
+ const rtl::OUString& aComponent)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+ if(checkOkState())
+ {
+ sal_Int32 nCount = mListenerList.count(aComponent);
+ if (nCount == 0)
+ {
+ OSL_TRACE("MultiStratumBackend: removeListener: no listener registered for component %s"
+ , aComponent.getStr());
+ }
+ else
+ {
+ ListenerList::iterator aIter;
+ aIter = mListenerList.find(aComponent);
+ mListenerList.erase(aIter);
+ if (nCount == 1)
+ {
+ //Deregister Listener from strata backend if they support notification
+ for (sal_uInt32 i = 0 ; i < mBackendStrata.size(); ++ i)
+ {
+ uno::Reference<backenduno::XBackendChangesNotifier> xBackend(mBackendStrata[i], uno::UNO_QUERY) ;
+ if (xBackend.is())
+ {
+ xBackend->removeChangesListener(mStrataListener, aComponent);
+ }
+ }
+ }
+ }
+ }
+}
+//------------------------------------------------------------------------------
+void MultiStratumBackend::componentDataChanged(const backenduno::ComponentChangeEvent& aEvent)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ try
+ {
+ notifyListeners( aEvent);
+
+ }
+ catch (uno::RuntimeException& ) { throw; }
+ catch (uno::Exception& e)
+ {
+ throw lang::WrappedTargetRuntimeException(e.Message, *this, uno::makeAny(e));
+ }
+}
+//------------------------------------------------------------------------------
+void MultiStratumBackend::disposing( lang::EventObject const & /*rSource*/ )
+ throw (::com::sun::star::uno::RuntimeException)
+{}
+//------------------------------------------------------------------------------
+void MultiStratumBackend::notifyListeners(const backenduno::ComponentChangeEvent& aEvent)const
+{
+ //fire off notification to all registered listeners for specific Component
+ ListenerList::const_iterator aIter;
+ rtl::OUString aComponentName = aEvent.Component;
+ if (mListenerList.empty())
+ {
+ OSL_TRACE("MultiStratumBackend: notifyListeners: no listeners registered for component %s",
+ aComponentName.getStr());
+ }
+ else
+ {
+ aIter = mListenerList.begin();
+ do{
+ if (aIter->first == aComponentName)
+ {
+ aIter->second->componentDataChanged(aEvent);
+ }
+ aIter++;
+ }while (aIter != mListenerList.end());
+ }
+ }
+//------------------------------------------------------------------------------
+} } // configmgr.backend
+
diff --git a/configmgr/source/backend/multistratumbackend.hxx b/configmgr/source/backend/multistratumbackend.hxx
new file mode 100644
index 000000000000..22fe463ff0d9
--- /dev/null
+++ b/configmgr/source/backend/multistratumbackend.hxx
@@ -0,0 +1,222 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: multistratumbackend.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_MULTISTRATUMBACKEND_HXX_
+#define CONFIGMGR_BACKEND_MULTISTRATUMBACKEND_HXX_
+
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+#include <com/sun/star/configuration/backend/XBackendEntities.hpp>
+#include <com/sun/star/configuration/backend/XVersionedSchemaSupplier.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/XBackendChangesNotifier.hpp>
+#include <com/sun/star/configuration/backend/XBackendChangesListener.hpp>
+#include <cppuhelper/compbase7.hxx>
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+namespace configmgr { namespace backend {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backenduno = css::configuration::backend ;
+
+/**
+ Class implementing the Backend service for multibackend access.
+ It creates the required backends and coordinates access to them.
+ */
+class MultiStratumBackend : public cppu::WeakComponentImplHelper7< backenduno::XBackend, backenduno::XBackendEntities, backenduno::XVersionedSchemaSupplier, backenduno::XBackendChangesNotifier, backenduno::XBackendChangesListener, lang::XInitialization, lang::XServiceInfo > {
+ public :
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ explicit
+ MultiStratumBackend(
+ const uno::Reference<uno::XComponentContext>& xContext) ;
+ /** Destructor */
+ ~MultiStratumBackend() ;
+
+ // XInitialize
+ virtual void SAL_CALL initialize(
+ const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ css::configuration::InvalidBootstrapFileException,
+ backenduno::BackendSetupException) ;
+
+ // XVersionedSchemaSupplier
+ virtual rtl::OUString
+ SAL_CALL getSchemaVersion(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ // XSchemaSupplier
+ virtual uno::Reference<backenduno::XSchema>
+ SAL_CALL getComponentSchema(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ // XBackend
+ virtual uno::Sequence<uno::Reference<backenduno::XLayer> >
+ SAL_CALL listOwnLayers(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Reference<backenduno::XUpdateHandler>
+ SAL_CALL getOwnUpdateHandler(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+ virtual uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ listLayers(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+ virtual uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ getUpdateHandler(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+
+ // XBackendEntities
+ virtual rtl::OUString SAL_CALL
+ getOwnerEntity( )
+ throw (uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ getAdminEntity( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsEntity( const rtl::OUString& aEntity )
+ throw (backenduno::BackendAccessException, uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isEqualEntity( const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity )
+ throw ( backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (uno::RuntimeException) ;
+ virtual sal_Bool SAL_CALL supportsService(
+ const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException) ;
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void) throw (uno::RuntimeException) ;
+
+ // XBackendChangesNotifier
+ virtual void SAL_CALL addChangesListener( const uno::Reference<backenduno::XBackendChangesListener>& xListner,
+ const rtl::OUString& aComponent)
+ throw (::com::sun::star::uno::RuntimeException);
+
+
+ virtual void SAL_CALL removeChangesListener( const uno::Reference<backenduno::XBackendChangesListener>& xListner,
+ const rtl::OUString& aComponent)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XBackendChangesListener
+ virtual void SAL_CALL componentDataChanged(const backenduno::ComponentChangeEvent& aEvent)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL disposing( lang::EventObject const & rSource )
+ throw (uno::RuntimeException);
+
+ void notifyListeners(const backenduno::ComponentChangeEvent& aEvent) const;
+ protected:
+ // ComponentHelper
+ virtual void SAL_CALL disposing();
+ private :
+ /** Initialize the schema supplier backend
+
+ */
+ void initializeSchemaSupplier(const uno::Reference<uno::XComponentContext>& aContext);
+
+ /** Initialize strata(SingleLayer or MultiLayer) backend
+ */
+ void initializeBackendStrata(const uno::Reference<uno::XComponentContext>& aContext);
+
+ /** Get Layers from Backend Strata
+ */
+ uno::Sequence<uno::Reference<backenduno::XLayer> >
+ searchSupportingStrata(sal_Int32 nNumLayer,
+ rtl::OUString aEntity,
+ const rtl::OUString& aComponent) ;
+
+
+ /** Find the Stratum that supports the specified Entity
+ * @return Number of Supported Strata
+ */
+ sal_Int32 findSupportingStratum(const rtl::OUString& aEntity) ;
+
+
+ /**
+ Check state of MultiStratumBackend -
+ @return true if not disposed/uninitialized
+ */
+ bool checkOkState();
+ /** Service factory */
+ uno::Reference<lang::XMultiServiceFactory> mFactory ;
+ /** Mutex for resource protection */
+ osl::Mutex mMutex ;
+
+ uno::Reference<backenduno::XSchemaSupplier> mSchemaSupplier ;
+ /** list of all backends */
+ std::vector< uno::Reference <uno::XInterface> > mBackendStrata;
+
+ rtl::OUString mOwnerEntity;
+
+ /** Helper object that listens to the Strata Backends */
+ uno::Reference<backenduno::XBackendChangesListener> mStrataListener;
+ /** List of higher level listeners */
+ typedef std::multimap< rtl::OUString, uno::Reference<backenduno::XBackendChangesListener> > ListenerList;
+ ListenerList mListenerList;
+} ;
+
+} } // configmgr.backend
+
+#endif // CONFIGMGR_BACKEND_MULTISTRATUMBACKEND_HXX_
diff --git a/configmgr/source/backend/schemabuilder.cxx b/configmgr/source/backend/schemabuilder.cxx
new file mode 100644
index 000000000000..ec41b5489e2a
--- /dev/null
+++ b/configmgr/source/backend/schemabuilder.cxx
@@ -0,0 +1,539 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: schemabuilder.cxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "schemabuilder.hxx"
+#include "treenodefactory.hxx"
+#include "matchlocale.hxx"
+#include <com/sun/star/configuration/backend/SchemaAttribute.hpp>
+#include <rtl/ustrbuf.hxx>
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+ namespace SchemaAttribute = backenduno::SchemaAttribute;
+// -----------------------------------------------------------------------------
+//#if OSL_DEBUG_LEVEL > 0
+// currently not used in debug builds
+#if 0
+ static void check_if_complete(MergedComponentData & md, uno::Reference< uno::XComponentContext > const & xContext)
+ {
+ uno::Reference< backenduno::XSchemaHandler >
+ test(new SchemaBuilder(xContext, rtl::OUString(),md,NULL));
+ }
+#endif
+// -----------------------------------------------------------------------------
+
+SchemaBuilder::SchemaBuilder(uno::Reference< uno::XComponentContext > const & xContext, const rtl::OUString& aExpectedComponentName, MergedComponentData & rData, ITemplateDataProvider* aTemplateProvider )
+: m_aData(rData)
+, m_aContext(xContext)
+//, m_aContext(xContext,static_cast<backenduno::XSchemaHandler*>(this), aExpectedComponentName, aTemplateProvider )
+, m_aFactory()
+{
+ m_aContext = DataBuilderContext(xContext,static_cast<backenduno::XSchemaHandler*>(this), aExpectedComponentName, aTemplateProvider );
+}
+// -----------------------------------------------------------------------------
+
+SchemaBuilder::~SchemaBuilder( )
+{
+
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// XSchemaHandler
+
+void SAL_CALL SchemaBuilder::startSchema( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!this->isDone())
+ m_aContext.raiseMalformedDataException("Schema builder: Unexpected Restart of Schema");
+
+ m_aData.clear();
+
+ OSL_ASSERT(!m_aContext.hasActiveComponent());
+ OSL_ASSERT( m_aContext.isDone());
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::endSchema( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!this->isDone())
+ m_aContext.raiseMalformedDataException("Schema builder: Unexpected End of Schema");
+
+ substituteInstances();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::importComponent( const rtl::OUString& /*aName*/ )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ //OSL_TRACE("WARNING: Configuration schema parser: Cross-component references are not yet supported\n");
+}
+// -----------------------------------------------------------------------------
+
+
+void SAL_CALL SchemaBuilder::startComponent( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (m_aData.hasSchema())
+ m_aContext.raiseElementExistException("Schema builder: The component schema is already loaded", rtl::OUString());
+
+ m_aContext.startActiveComponent(aName);
+
+ std::auto_ptr<ISubtree> apSchema =
+ m_aFactory.createGroup(aName,0,getComponentRootAttributes());
+
+ ISubtree * pSchema = m_aData.setSchemaRoot(apSchema);
+
+ m_aContext.pushNode(pSchema);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::endComponent( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ m_aContext.popNode();
+
+ m_aContext.endActiveComponent();
+}
+// -----------------------------------------------------------------------------
+
+bool SchemaBuilder::isExtensible(sal_Int16 aSchemaAttributes)
+{
+ sal_Int16 const aValidAttributes = aSchemaAttributes & SchemaAttribute::EXTENSIBLE;
+
+ if (aValidAttributes != aSchemaAttributes)
+ m_aContext.raiseIllegalArgumentException("Schema builder: Illegal attribute specified for node.",2);
+
+ return (aValidAttributes != 0);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::startGroupTemplate( const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (aTemplate.Component.getLength() == 0)
+ m_aContext.raiseIllegalArgumentException("Schema builder: Starting template without owning component",1);
+
+ m_aContext.startActiveComponent(aTemplate.Component);
+
+ if (m_aData.hasTemplate(aTemplate.Name))
+ m_aContext.raiseElementExistException("Schema builder: Template already exists",aTemplate.Name);
+
+ rtl::OUString aName = m_aData.getTemplateAccessor(aTemplate);
+ bool bExtensible = isExtensible(aAttributes);
+
+ std::auto_ptr<ISubtree> aTemplateTree =
+ m_aFactory.createGroup(aName,bExtensible,getTemplateBaseAttributes());
+
+ ISubtree * pTree = m_aData.addTemplate(aTemplateTree,aTemplate);
+
+ m_aContext.pushNode(pTree);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::startSetTemplate( const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes, const backenduno::TemplateIdentifier& aItemType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (aTemplate.Component.getLength() == 0)
+ m_aContext.raiseIllegalArgumentException("Schema builder: Starting template without owning component",1);
+
+ m_aContext.startActiveComponent(aTemplate.Component);
+
+ if (m_aData.hasTemplate(aTemplate.Name))
+ m_aContext.raiseElementExistException("Schema builder: Template already exists",aTemplate.Name);
+
+ rtl::OUString aName = m_aData.getTemplateAccessor(aTemplate);
+ backenduno::TemplateIdentifier aFullType = m_aContext.completeComponent(aItemType);
+ bool bExtensible = isExtensible(aAttributes);
+
+ std::auto_ptr<ISubtree> aTemplateTree =
+ m_aFactory.createSet( aName,aFullType,bExtensible,getTemplateBaseAttributes());
+
+ ISubtree * pTree = m_aData.addTemplate(aTemplateTree,aTemplate);
+
+ m_aContext.pushNode(pTree);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::endTemplate( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ m_aContext.popNode();
+
+ m_aContext.endActiveComponent();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::startGroup( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ bool bExtensible = isExtensible(aAttributes);
+
+ std::auto_ptr<ISubtree> aTree = m_aFactory.createGroup(aName,bExtensible,getNodeAttributes());
+
+ ISubtree * pTree = m_aContext.addNodeToCurrent(aTree);
+
+ m_aContext.pushNode(pTree);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::startSet( const rtl::OUString& aName, sal_Int16 aAttributes, const backenduno::TemplateIdentifier& aItemType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ backenduno::TemplateIdentifier aFullType = m_aContext.completeComponent(aItemType);
+ bool bExtensible = isExtensible(aAttributes);
+
+ std::auto_ptr<ISubtree> aTree = m_aFactory.createSet(aName,aFullType,bExtensible,getNodeAttributes());
+
+ ISubtree * pTree = m_aContext.addNodeToCurrent(aTree);
+
+ m_aContext.pushNode(pTree);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ m_aContext.popNode();
+
+ if (m_aContext.isDone())
+ m_aContext.raiseMalformedDataException("Schema builder: Incorrect Termination");
+}
+// -----------------------------------------------------------------------------
+
+node::Attributes SchemaBuilder::makePropertyAttributes(sal_Int16 aSchemaAttributes) const
+{
+ const sal_uInt16 c_AllPropertyAttributes =
+ SchemaAttribute::REQUIRED | SchemaAttribute::LOCALIZED;
+
+ if ((aSchemaAttributes & c_AllPropertyAttributes) != aSchemaAttributes)
+ m_aContext.raiseIllegalArgumentException("SchemaBuilder: Unreckognized Attribute for Property",2);
+
+ node::Attributes aAttributes = getNodeAttributes();
+
+ if (aSchemaAttributes & SchemaAttribute::REQUIRED)
+ aAttributes.setNullable (false);
+
+ return aAttributes;
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ // TODO: add type validation
+ node::Attributes aValueAttributes = makePropertyAttributes(aAttributes);
+
+ if (aAttributes & SchemaAttribute::LOCALIZED)
+ {
+ std::auto_ptr<ISubtree> aLocalizedProp =
+ m_aFactory.createLocalizedContainer(aName,aType,aValueAttributes);
+
+ m_aContext.addLocalizedToCurrent(aLocalizedProp);
+ }
+ else
+ {
+ std::auto_ptr<ValueNode> aPropertyValue =
+ m_aFactory.getNodeFactory().createNullValueNode(aName,aType,aValueAttributes);
+
+ m_aContext.addPropertyToCurrent(aPropertyValue);
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::addPropertyWithDefault( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aDefaultValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ // TODO: add parameter validation
+ node::Attributes aValueAttributes = makePropertyAttributes(aAttributes);
+
+ if (aAttributes & SchemaAttribute::LOCALIZED)
+ {
+ std::auto_ptr<ISubtree> aLocalizedProp =
+ m_aFactory.createLocalizedContainer(aName,aDefaultValue.getValueType(),aValueAttributes);
+
+ std::auto_ptr<ValueNode> aPropertyValue =
+ m_aFactory.getNodeFactory().createValueNode(localehelper::getDefaultLanguage(),aDefaultValue,aValueAttributes);
+
+ aLocalizedProp->addChild( base_ptr(aPropertyValue) );
+
+ m_aContext.addLocalizedToCurrent(aLocalizedProp);
+ }
+ else
+ {
+ std::auto_ptr<ValueNode> aPropertyValue =
+ m_aFactory.getNodeFactory().createValueNode(aName,aDefaultValue,aValueAttributes);
+
+
+ m_aContext.addPropertyToCurrent( aPropertyValue);
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::addInstance( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ backenduno::TemplateIdentifier aFullType = m_aContext.completeComponent(aTemplate);
+
+ std::auto_ptr<ISubtree> aPlaceHolder =
+ m_aFactory.createPlaceHolder(aName,aFullType);
+
+ m_aContext.addNodeToCurrent(aPlaceHolder);
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaBuilder::addItemType( const backenduno::TemplateIdentifier& aItemType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ if ( m_aContext.getCurrentParent().getElementTemplateName() != aItemType.Name ||
+ m_aContext.getCurrentParent().getElementTemplateModule() != m_aContext.getTemplateComponent(aItemType) )
+ {
+ OSL_ENSURE(false, "SchemaBuilder: Multiple ItemTypes for Sets are currently not supported");
+ m_aContext.raiseMalformedDataException("SchemaBuilder: Unsupported Feature: Multiple ItemTypes for Sets");
+ }
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+node::Attributes SchemaBuilder::getNodeAttributes() const
+{
+ node::Attributes aResult = m_aContext.getCurrentAttributes();
+ aResult.setState( node::isDefault );
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+
+node::Attributes SchemaBuilder::getComponentRootAttributes()
+{
+ node::Attributes aResult;
+ aResult.setState( node::isDefault );
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+
+node::Attributes SchemaBuilder::getTemplateBaseAttributes()
+{
+ node::Attributes aResult;
+ aResult.setState( node::isReplaced );
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+namespace
+{
+ class SubstitutionHelper : NodeModification
+ {
+ MergedComponentData & m_rData;
+ DataBuilderContext m_aContext;
+ ComponentDataFactory m_aFactory;
+
+ std::vector< rtl::OUString > m_aReplacementList;
+ std::vector< ISubtree const * > m_aTemplateStack;
+ public:
+ SubstitutionHelper(DataBuilderContext const & aBaseContext, MergedComponentData & _rData, uno::XInterface * _pContext)
+ : m_rData(_rData)
+ , m_aContext(aBaseContext,_pContext)
+ , m_aReplacementList()
+ , m_aTemplateStack()
+ {}
+
+ void substituteInData();
+ private:
+ void substituteInComponent(ISubtree * _pComponent);
+ void substituteInNode(ISubtree & _rNode);
+ void substituteInList();
+
+ void substitute(rtl::OUString const & _aName);
+
+ virtual void handle(ValueNode&);
+ virtual void handle(ISubtree&);
+ };
+}
+// -----------------------------------------------------------------------------
+
+void SchemaBuilder::substituteInstances()
+{
+ SubstitutionHelper helper(m_aContext, m_aData, static_cast<backenduno::XSchemaHandler*>(this));
+
+ helper.substituteInData();
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+namespace
+{
+// -----------------------------------------------------------------------------
+ void SubstitutionHelper::substituteInData()
+ {
+ if (m_rData.hasTemplates())
+ substituteInComponent(m_rData.getTemplatesTree());
+
+ if (m_rData.hasSchema())
+ substituteInComponent(m_rData.getSchemaTree());
+ }
+ // -----------------------------------------------------------------------------
+
+ void SubstitutionHelper::substituteInComponent(ISubtree * _pComponent)
+ {
+ OSL_ENSURE(_pComponent,"ERROR: Trying to substitute in NULL component");
+
+ if (_pComponent)
+ {
+ m_aContext.startActiveComponent(_pComponent->getName());
+ this->substituteInNode(*_pComponent);
+ m_aContext.endActiveComponent();
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SubstitutionHelper::substituteInNode(ISubtree & _rNode)
+ {
+ std::vector< rtl::OUString > aSaveInstances;
+ aSaveInstances.swap(m_aReplacementList);
+
+ // todo: own stack to check against infinite recursion
+ m_aContext.pushNode(&_rNode);
+
+ this->applyToChildren(_rNode); // fill the list
+
+ this->substituteInList();
+
+ m_aContext.popNode();
+
+ aSaveInstances.swap(m_aReplacementList);
+ }
+ // -----------------------------------------------------------------------------
+
+ void SubstitutionHelper::substituteInList()
+ {
+ for(std::vector< rtl::OUString >::iterator it = m_aReplacementList.begin();
+ it != m_aReplacementList.end(); ++it)
+ {
+ this->substitute(*it);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SubstitutionHelper::substitute(rtl::OUString const & _aName)
+ {
+
+ ISubtree & rParent = m_aContext.getCurrentParent();
+
+ std::auto_ptr<INode> pReplacedNode = rParent.removeChild(_aName);
+ OSL_ASSERT( pReplacedNode.get() != NULL );
+
+ ISubtree * pReplacedInstance = pReplacedNode->asISubtree();
+ OSL_ASSERT( pReplacedInstance != NULL );
+
+ backenduno::TemplateIdentifier aTemplateName = m_aFactory.getInstanceType(*pReplacedInstance);
+ if (aTemplateName.Component == m_aContext.getActiveComponent())
+ {
+ if (ISubtree const * pTemplate = m_rData.findTemplate(aTemplateName.Name))
+ {
+ std::vector< ISubtree const * >::iterator beg = m_aTemplateStack.begin(), end = m_aTemplateStack.end();
+ if (std::find(beg,end,pTemplate) != end)
+ m_aContext.raiseMalformedDataException("SchemaBuilder: Could not expand instances: Template is recursive");
+
+ m_aTemplateStack.push_back(pTemplate);
+
+ std::auto_ptr< INode > pTemplateInstance = pTemplate->clone();
+
+ pTemplateInstance->setName(_aName);
+ // TODO: adjust state/attributes here (?)
+
+ ISubtree * pAddedTree = rParent.addChild(pTemplateInstance)->asISubtree();
+
+ OSL_ENSURE(pAddedTree, "Could not obtain added template instance");
+
+ this->substituteInNode(*pAddedTree);
+
+ m_aTemplateStack.pop_back();
+ }
+ else
+ {
+ m_aContext.raiseMalformedDataException("SchemaBuilder: Could not expand instances: Template not found");
+ }
+ }
+ //Import Template from different component
+ else
+ {
+ TemplateRequest aTemplateRequest(aTemplateName.Name,
+ aTemplateName.Component );
+ ResultHolder< TemplateInstance > aResult = m_aContext.getTemplateData( aTemplateRequest );
+
+ std::auto_ptr<INode> pTemplateInstance = aResult.extractDataAndClear();
+ pTemplateInstance->setName(_aName);
+
+ // Add template instance - must be a tree as any template
+ OSL_VERIFY(
+ rParent.addChild(pTemplateInstance)->asISubtree() );
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SubstitutionHelper::handle(ValueNode&)
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ void SubstitutionHelper::handle(ISubtree& _rTree)
+ {
+ if (m_aFactory.isInstancePlaceHolder(_rTree))
+ m_aReplacementList.push_back(_rTree.getName());
+
+ else
+ substituteInNode(_rTree);
+ }
+// -----------------------------------------------------------------------------
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/schemabuilder.hxx b/configmgr/source/backend/schemabuilder.hxx
new file mode 100644
index 000000000000..97fdbad3bb15
--- /dev/null
+++ b/configmgr/source/backend/schemabuilder.hxx
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: schemabuilder.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_SCHEMABUILDER_HXX
+#define CONFIGMGR_BACKEND_SCHEMABUILDER_HXX
+
+#include "mergedcomponentdata.hxx"
+#include "componentdatahelper.hxx"
+#include "mergeddataprovider.hxx"
+#include <com/sun/star/configuration/backend/XSchemaHandler.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ class OTreeNodeFactory;
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+ class SchemaBuilder
+ : public cppu::WeakImplHelper1<backenduno::XSchemaHandler>
+ {
+ public:
+ SchemaBuilder(uno::Reference< uno::XComponentContext > const & xContext, const rtl::OUString& aExpectedComponentName, MergedComponentData & rData, ITemplateDataProvider* aTemplateProvider = NULL );
+ virtual ~SchemaBuilder();
+
+ // checking the result
+ bool isDone() const { return m_aContext.isDone(); }
+
+ MergedComponentData & result();
+ MergedComponentData const & result() const;
+
+ // XSchemaHandler
+ public:
+ virtual void SAL_CALL
+ startSchema( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endSchema( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ importComponent( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ startComponent( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endComponent( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ startGroupTemplate( const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ startSetTemplate( const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes, const backenduno::TemplateIdentifier& aItemType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endTemplate( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ startGroup( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ startSet( const rtl::OUString& aName, sal_Int16 aAttributes, const backenduno::TemplateIdentifier& aItemType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyWithDefault( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aDefaultValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addInstance( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addItemType( const backenduno::TemplateIdentifier& aItemType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ private:
+ static node::Attributes getComponentRootAttributes();
+ static node::Attributes getTemplateBaseAttributes();
+ node::Attributes getNodeAttributes() const;
+ node::Attributes makePropertyAttributes(sal_Int16 aSchemaAttributes) const;
+
+ bool isExtensible(sal_Int16 aSchemaAttributes);
+
+ void substituteInstances();
+ private:
+ MergedComponentData & m_aData;
+ DataBuilderContext m_aContext;
+ ComponentDataFactory m_aFactory;
+ };
+// -----------------------------------------------------------------------------
+
+ } // namespace backend
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/singlebackendadapter.cxx b/configmgr/source/backend/singlebackendadapter.cxx
new file mode 100644
index 000000000000..400874a291fe
--- /dev/null
+++ b/configmgr/source/backend/singlebackendadapter.cxx
@@ -0,0 +1,339 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: singlebackendadapter.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "singlebackendadapter.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif // CONFIGMGR_API_FACTORY_HXX_
+#include "serviceinfohelper.hxx"
+#include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
+#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+namespace configmgr { namespace backend {
+
+//==============================================================================
+
+SingleBackendAdapter::SingleBackendAdapter(
+ const uno::Reference<uno::XComponentContext>& xContext)
+ : cppu::WeakComponentImplHelper5< backenduno::XBackend, backenduno::XBackendEntities, backenduno::XSchemaSupplier, lang::XInitialization, lang::XServiceInfo >(mMutex), mFactory(xContext->getServiceManager(),uno::UNO_QUERY) {
+}
+//------------------------------------------------------------------------------
+
+SingleBackendAdapter::~SingleBackendAdapter(void) {}
+//------------------------------------------------------------------------------
+
+void SAL_CALL SingleBackendAdapter::initialize(
+ const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception) {
+
+ uno::Any const * const pParams = aParameters.getConstArray();
+ sal_Int32 nCount = aParameters.getLength();
+
+ for (sal_Int32 ix = 0; ix < nCount; ++ix)
+ {
+ if (pParams[ix] >>= mBackend) break;
+ }
+
+ if (!mBackend.is())
+ {
+ throw com::sun::star::configuration::CannotLoadConfigurationException(
+ rtl::OUString::createFromAscii("Online SingleBackend Adapter: Cannot operate without real (Single)Backend"),
+ *this);
+ }
+}
+//------------------------------------------------------------------------------
+static inline rtl::OUString getSingleLayerDummyEntity()
+{ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")); }
+//------------------------------------------------------------------------------
+bool SingleBackendAdapter::checkOkState()
+{
+ if (!mBackend.is())
+ {
+ if(rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SingleBackendAdapter: Backend already disposed")),*this);
+ }
+ else
+ {
+ throw backenduno::BackendAccessException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SingleBackendAdapter: Object was never Initialised")),*this,uno::Any() );
+ }
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------------
+
+// XBackendEntities
+rtl::OUString SAL_CALL
+ SingleBackendAdapter::getOwnerEntity( )
+ throw (uno::RuntimeException)
+{
+ if (mBackend.is())
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
+
+ return xEntities->getOwnerEntity();
+ }
+ else
+ {
+ throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SingleBackendAdapter: Object was never Initialised")),*this);
+ }
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL
+ SingleBackendAdapter::getAdminEntity( )
+ throw (uno::RuntimeException)
+{
+ if (mBackend.is())
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
+ return xEntities->getAdminEntity();
+ }
+ else
+ {
+ throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SingleBackendAdapter: Object was never Initialised")),*this);
+ }
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL
+ SingleBackendAdapter::supportsEntity( const rtl::OUString& aEntity )
+ throw (backenduno::BackendAccessException, uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
+ return xEntities->supportsEntity(aEntity);
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL
+ SingleBackendAdapter::isEqualEntity( const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity )
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
+ return xEntities->isEqualEntity(aEntity,aOtherEntity);
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backenduno::XSchema> SAL_CALL
+ SingleBackendAdapter::getComponentSchema(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ return mBackend->getComponentSchema(aComponent) ;
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ SingleBackendAdapter::listOwnLayers(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ return listLayers(aComponent, this->getOwnerEntity()) ;
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ SingleBackendAdapter::getOwnUpdateHandler(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::NoSupportException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ return getUpdateHandler(aComponent, this->getOwnerEntity()) ;
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ SingleBackendAdapter::listLayers(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ uno::Reference< backenduno::XMultiLayerStratum > xBackend( mBackend, uno::UNO_REF_QUERY_THROW );
+
+ uno::Sequence<uno::Reference<backenduno::XLayer> > retCode =
+ xBackend->getLayers(xBackend->listLayerIds(aComponent, aEntity),
+ rtl::OUString()) ;
+
+ // There might be non-existent layers in the list if there's no
+ // actual data associated to a given layer id. Hence we have to
+ // compress the list.
+ sal_Int32 maxLayer = 0 ;
+
+ for (sal_Int32 i = 0 ; i < retCode.getLength() ; ++ i)
+ {
+ if (retCode [i].is())
+ {
+ if (i != maxLayer) { retCode [maxLayer] = retCode [i] ; }
+ ++ maxLayer ;
+ }
+ }
+ retCode.realloc(maxLayer) ;
+ return retCode ;
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ SingleBackendAdapter::getUpdateHandler(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::NoSupportException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (checkOkState())
+ {
+ uno::Reference< backenduno::XMultiLayerStratum > xBackend( mBackend, uno::UNO_REF_QUERY_THROW );
+
+ uno::Sequence<uno::Any> arguments(1) ;
+
+ arguments [0] <<= xBackend->getUpdatableLayer(
+ xBackend->getUpdateLayerId(aComponent,
+ aEntity)) ;
+ uno::Reference< uno::XInterface > xHandler;
+ try
+ {
+ const rtl::OUString kUpdateMerger(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.backend.LayerUpdateMerger")) ;
+
+ xHandler = mFactory->createInstanceWithArguments(kUpdateMerger, arguments);
+ }
+ catch (uno::RuntimeException & )
+ {throw;}
+ catch (uno::Exception & e)
+ {
+ const rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM(
+ "Configuration SingleBackendAdapter: Cannot create UpdateMerger - error message: ")) ;
+ throw uno::RuntimeException(sMessage.concat(e.Message),*this);
+ }
+
+ return uno::Reference<backenduno::XUpdateHandler>(xHandler, uno::UNO_REF_QUERY_THROW) ;
+ }
+ return false;
+}
+//------------------------------------------------------------------------------
+
+static const sal_Char * const kBackendService = "com.sun.star.configuration.backend.Backend" ;
+static const sal_Char * const kAdapterService = "com.sun.star.configuration.backend.BackendAdapter" ;
+static const sal_Char * const kOnlineService = "com.sun.star.configuration.backend.OnlineBackend" ;
+
+static const sal_Char * const kImplementation =
+ "com.sun.star.comp.configuration.backend.SingleBackendAdapter" ;
+
+static sal_Char const * const kServiceNames [] =
+{
+ kOnlineService,
+ kAdapterService,
+ 0,
+ kBackendService,
+ 0
+} ;
+static const ServiceImplementationInfo kServiceInfo =
+{
+ kImplementation,
+ kServiceNames,
+ kServiceNames + 3
+} ;
+
+const ServiceRegistrationInfo *getSingleBackendAdapterServiceInfo()
+{
+ return getRegistrationInfo(&kServiceInfo) ;
+}
+
+uno::Reference<uno::XInterface> SAL_CALL
+ instantiateSingleBackendAdapter(const uno::Reference< uno::XComponentContext >& xContext)
+{
+ return *new SingleBackendAdapter(xContext) ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL
+ SingleBackendAdapter::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).getImplementationName() ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL
+ SingleBackendAdapter::supportsService(const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).supportsService(aServiceName) ;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString> SAL_CALL
+ SingleBackendAdapter::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ;
+}
+//------------------------------------------------------------------------------
+
+} } // configmgr.backend
+
diff --git a/configmgr/source/backend/singlebackendadapter.hxx b/configmgr/source/backend/singlebackendadapter.hxx
new file mode 100644
index 000000000000..871705356c29
--- /dev/null
+++ b/configmgr/source/backend/singlebackendadapter.hxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: singlebackendadapter.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_SINGLEBACKENDADAPTER_HXX_
+#define CONFIGMGR_BACKEND_SINGLEBACKENDADAPTER_HXX_
+
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+#include <com/sun/star/configuration/backend/XBackendEntities.hpp>
+#include <com/sun/star/configuration/backend/XSchemaSupplier.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/compbase5.hxx>
+
+namespace configmgr { namespace backend {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backenduno = css::configuration::backend ;
+
+/**
+ Class implementing the Backend service for remote access.
+ It just transfers calls to a SingleBackend implementation.
+ */
+class SingleBackendAdapter : public cppu::WeakComponentImplHelper5< backenduno::XBackend, backenduno::XBackendEntities, backenduno::XSchemaSupplier, lang::XInitialization, lang::XServiceInfo > {
+ public :
+ /**
+ Service constructor from a service factory.
+
+ @param aFactory service factory
+ */
+ SingleBackendAdapter(
+ const uno::Reference<uno::XComponentContext>& xContext) ;
+ /** Destructor */
+ ~SingleBackendAdapter(void) ;
+
+ // XInitialize
+ virtual void SAL_CALL initialize(
+ const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception) ;
+
+ // XSchemaSupplier
+ virtual uno::Reference<backenduno::XSchema>
+ SAL_CALL getComponentSchema(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ // XBackend
+ virtual uno::Sequence<uno::Reference<backenduno::XLayer> >
+ SAL_CALL listOwnLayers(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Reference<backenduno::XUpdateHandler>
+ SAL_CALL getOwnUpdateHandler(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+ virtual uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ listLayers(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+ virtual uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ getUpdateHandler(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+
+ // XBackendEntities
+ virtual rtl::OUString SAL_CALL
+ getOwnerEntity( )
+ throw (uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ getAdminEntity( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsEntity( const rtl::OUString& aEntity )
+ throw (backenduno::BackendAccessException, uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isEqualEntity( const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity )
+ throw ( backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName(void)
+ throw (uno::RuntimeException) ;
+ virtual sal_Bool SAL_CALL supportsService(
+ const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException) ;
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void) throw (uno::RuntimeException) ;
+ protected :
+ private :
+ /** Service factory */
+ uno::Reference<lang::XMultiServiceFactory> mFactory ;
+ /** Mutex for resource protection */
+ osl::Mutex mMutex ;
+ /** Remote backend that the offline cache is handling */
+ uno::Reference<backenduno::XSchemaSupplier> mBackend ;
+ /* checks if object is in initialized and undisposed state */
+ bool checkOkState();
+} ;
+
+} } // configmgr.backend
+
+#endif // CONFIGMGR_BACKEND_SINGLEBACKENDADAPTER_HXX_
diff --git a/configmgr/source/backend/updatedata.cxx b/configmgr/source/backend/updatedata.cxx
new file mode 100644
index 000000000000..7a70210f3aa0
--- /dev/null
+++ b/configmgr/source/backend/updatedata.cxx
@@ -0,0 +1,458 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updatedata.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "updatedata.hxx"
+
+#include <com/sun/star/configuration/backend/NodeAttribute.hpp>
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+
+#include <iterator>
+#include <algorithm>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+ElementUpdate::ElementUpdate(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask)
+: NamedUpdate(_aName)
+, m_pParent(_pParent)
+, m_nFlags(_nFlags)
+, m_nFlagsMask(_nFlagsMask)
+{
+}
+// -----------------------------------------------------------------------------
+
+sal_Int16 ElementUpdate::updateFlags(sal_Int16 _nFlags) const
+{
+ return (_nFlags & ~m_nFlagsMask) | (m_nFlags & m_nFlagsMask);
+}
+// -----------------------------------------------------------------------------
+
+NodeUpdate * ElementUpdate::asNodeUpdate(bool )
+{
+ return NULL;
+}
+// -----------------------------------------------------------------------------
+
+PropertyUpdate * ElementUpdate::asPropertyUpdate()
+{
+ return NULL;
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+NodeUpdate::NodeUpdate(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, Op _op)
+: ElementUpdate(_pParent,_aName,_nFlags, _nFlagsMask)
+, m_aNodes()
+, m_aProperties()
+, m_aRemovedElements()
+, m_op(_op)
+{
+}
+// -----------------------------------------------------------------------------
+
+NodeUpdate * NodeUpdate::asNodeUpdate(bool _bMerged)
+{
+ return (!_bMerged || m_op == modify
+ || (updateFlags() & backenduno::NodeAttribute::FUSE) != 0)
+ ? this : NULL;
+}
+// -----------------------------------------------------------------------------
+
+bool NodeUpdate::addNodeUpdate(rtl::Reference<ElementUpdate> const & _aNode)
+{
+ OSL_PRECOND( _aNode.is(), "ERROR: NodeUpdate: Trying to add NULL node.");
+ OSL_PRECOND( _aNode->getParent() == this, "ERROR: NodeUpdate: Node being added has wrong parent.");
+ OSL_ENSURE(m_aNodes.find(_aNode->getName()) == m_aNodes.end(),
+ "NodeUpdate: Child node being added already exists in this node.");
+
+ return m_aNodes.insert( ElementList::value_type(_aNode->getName(),_aNode) ).second;
+}
+// -----------------------------------------------------------------------------
+
+bool NodeUpdate::addPropertyUpdate(rtl::Reference<ElementUpdate> const & _aProp)
+{
+ OSL_PRECOND( _aProp.is(), "ERROR: NodeUpdate: Trying to add NULL property.");
+ OSL_PRECOND( _aProp->getParent() == this, "ERROR: NodeUpdate: Property being added has wrong parent.");
+ OSL_ENSURE(m_aProperties.find(_aProp->getName()) == m_aProperties.end(),
+ "NodeUpdate: Property being added already exists in this node.");
+
+ return m_aProperties.insert( ElementList::value_type(_aProp->getName(),_aProp) ).second;
+}
+// -----------------------------------------------------------------------------
+
+void NodeUpdate::removeNodeByName(rtl::OUString const & _aName)
+{
+ ElementList::iterator it = m_aNodes.find(_aName);
+ OSL_ENSURE(it != m_aNodes.end(),
+ "NodeUpdate: Child node being removed is not in this node.");
+
+ if (it != m_aNodes.end())
+ {
+ m_aRemovedElements.insert(*it);
+ m_aNodes.erase(it);
+ }
+}
+// -----------------------------------------------------------------------------
+
+void NodeUpdate::removePropertyByName (rtl::OUString const & _aName)
+{
+ ElementList::iterator it = m_aProperties.find(_aName);
+ OSL_ENSURE(it != m_aProperties.end(),
+ "NodeUpdate: Property being removed is not in this node.");
+
+ if (it != m_aProperties.end())
+ {
+ m_aRemovedElements.insert(*it);
+ m_aProperties.erase(it);
+ }
+}
+// -----------------------------------------------------------------------------
+
+rtl::Reference<ElementUpdate> NodeUpdate::getNodeByName(rtl::OUString const & _aName) const
+{
+ ElementList::const_iterator it = m_aNodes.find(_aName);
+
+ return it != m_aNodes.end() ? it->second : rtl::Reference<ElementUpdate>();
+}
+// -----------------------------------------------------------------------------
+
+rtl::Reference<ElementUpdate> NodeUpdate::getPropertyByName (rtl::OUString const & _aName) const
+{
+ ElementList::const_iterator it = m_aProperties.find(_aName);
+
+ return it != m_aProperties.end() ? it->second : rtl::Reference<ElementUpdate>();
+}
+// -----------------------------------------------------------------------------
+
+void NodeUpdate::writeChildrenToLayer(backenduno::XLayerHandler * _pLayer)
+{
+ OSL_ASSERT(_pLayer);
+ for (ElementList::const_iterator itP = beginProperties(); itP != endProperties(); ++itP)
+ itP->second->writeToLayer(_pLayer);
+
+ for (ElementList::const_iterator itN = beginNodes(); itN != endNodes(); ++itN)
+ itN->second->writeToLayer(_pLayer);
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+NodeModification::NodeModification(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, sal_Bool _bReset)
+: NodeUpdate(_pParent,_aName,_nFlags, _nFlagsMask, _bReset ? reset : modify)
+{
+}
+// -----------------------------------------------------------------------------
+
+void NodeModification::writeToLayer(backenduno::XLayerHandler * _pLayer)
+{
+ OSL_ASSERT(_pLayer);
+
+ if ( this->getOperation() == reset && // if we have an empty
+ !this->changedFlags() && // 'reset' node, that means
+ !this->hasChildren() ) // we need to write
+ return; // nothing
+
+ _pLayer->overrideNode( this->getName(), this->updateFlags(), false );
+ this->writeChildrenToLayer(_pLayer);
+ _pLayer->endNode();
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+NodeReplace::NodeReplace(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags)
+: NodeUpdate(_pParent,_aName,_nFlags, _nFlags, replace)
+, m_aTemplateName()
+, m_aTemplateComponent()
+{
+}
+// -----------------------------------------------------------------------------
+
+NodeReplace::NodeReplace(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, rtl::OUString const & _aTemplateName, rtl::OUString const & _aTemplateComponent)
+: NodeUpdate(_pParent,_aName,_nFlags, _nFlags, replace)
+, m_aTemplateName(_aTemplateName)
+, m_aTemplateComponent(_aTemplateComponent)
+{
+}
+// -----------------------------------------------------------------------------
+
+bool NodeReplace::hasTemplate() const
+{
+ return m_aTemplateName.getLength() != 0;
+}
+// -----------------------------------------------------------------------------
+
+void NodeReplace::writeToLayer(backenduno::XLayerHandler * _pLayer)
+{
+ OSL_ASSERT(_pLayer);
+
+ if (this->hasTemplate())
+ {
+ backenduno::TemplateIdentifier aTemplate( m_aTemplateName, m_aTemplateComponent );
+ _pLayer->addOrReplaceNodeFromTemplate( this->getName(), aTemplate, this->updateFlags() );
+ }
+ else
+ _pLayer->addOrReplaceNode( this->getName(), this->updateFlags() );
+
+ this->writeChildrenToLayer(_pLayer);
+ _pLayer->endNode();
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+NodeDrop::NodeDrop(NodeUpdate * _pParent, rtl::OUString const & _aName)
+: ElementUpdate(_pParent,_aName,0,0)
+{
+}
+// -----------------------------------------------------------------------------
+
+void NodeDrop::writeToLayer(backenduno::XLayerHandler * _pLayer)
+{
+ OSL_ASSERT(_pLayer);
+ _pLayer->dropNode(this->getName());
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+PropertyUpdate::PropertyUpdate(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, uno::Type const & _aType)
+: ElementUpdate(_pParent,_aName,_nFlags,_nFlagsMask)
+, m_aValues()
+, m_aType(_aType)
+{}
+// -----------------------------------------------------------------------------
+
+PropertyUpdate * PropertyUpdate::asPropertyUpdate()
+{
+ return this;
+}
+// -----------------------------------------------------------------------------
+
+static uno::Any makeResetMarker()
+{
+ uno::Reference< backenduno::XLayerHandler > xNull;
+ return uno::makeAny(xNull);
+}
+// -----------------------------------------------------------------------------
+
+inline bool PropertyUpdate::isResetMarker(uno::Any const & _aValue)
+{
+ OSL_ENSURE( _aValue.getValueTypeClass() != uno::TypeClass_INTERFACE ||
+ _aValue == makeResetMarker() && _aValue.getValueType() == makeResetMarker().getValueType(),
+ "Unexpected any: Interface reference will be taken as reset marker");
+
+ return _aValue.getValueTypeClass() == uno::TypeClass_INTERFACE;
+}
+// -----------------------------------------------------------------------------
+
+uno::Any const & PropertyUpdate::getResetMarker()
+{
+ static uno::Any const aMarker = makeResetMarker();
+
+ OSL_ASSERT( isResetMarker(aMarker) );
+
+ return aMarker;
+}
+// -----------------------------------------------------------------------------
+
+bool PropertyUpdate::setValueFor(rtl::OUString const & _aLocale, uno::Any const & _aValueUpdate)
+{
+ OSL_PRECOND( !isResetMarker(_aValueUpdate), "PropertyUpdate: ERROR: Trying to set a reset marker as regular value" );
+
+ OSL_ENSURE(m_aValues.find(_aLocale) == m_aValues.end(),
+ "PropertyUpdate: Locale being added already has a value in this property.");
+
+ if (_aValueUpdate.hasValue())
+ {
+ if (m_aType.getTypeClass() == uno::TypeClass_ANY)
+ m_aType = _aValueUpdate.getValueType();
+
+ else
+ OSL_ENSURE( m_aType == _aValueUpdate.getValueType() ||
+ m_aType == uno::Type(),
+ "ValueType mismatch in PropertyUpdate");
+ }
+ return m_aValues.insert( ValueList::value_type(_aLocale,_aValueUpdate) ).second;
+}
+// -----------------------------------------------------------------------------
+
+bool PropertyUpdate::resetValueFor(rtl::OUString const & _aLocale)
+{
+ OSL_ENSURE(m_aValues.find(_aLocale) == m_aValues.end(),
+ "PropertyUpdate: Locale being reset already has a value in this property.");
+
+ return m_aValues.insert( ValueList::value_type(_aLocale,getResetMarker()) ).second;
+}
+// -----------------------------------------------------------------------------
+
+void PropertyUpdate::removeValueFor(rtl::OUString const & _aLocale)
+{
+ OSL_ENSURE(m_aValues.find(_aLocale) != m_aValues.end(),
+ "PropertyUpdate: Locale being removed is not in this node.");
+
+ m_aValues.erase(_aLocale);
+}
+// -----------------------------------------------------------------------------
+
+void PropertyUpdate::finishValue()
+{
+ if (m_aType.getTypeClass() == uno::TypeClass_ANY)
+ m_aType = uno::Type();
+}
+// -----------------------------------------------------------------------------
+
+bool PropertyUpdate::hasValueFor(rtl::OUString const & _aLocale) const
+{
+ ValueList::const_iterator it = m_aValues.find(_aLocale);
+
+ return it != m_aValues.end() && ! isResetMarker(it->second);
+}
+// -----------------------------------------------------------------------------
+
+bool PropertyUpdate::hasResetFor(rtl::OUString const & _aLocale) const
+{
+ ValueList::const_iterator it = m_aValues.find(_aLocale);
+
+ return it != m_aValues.end() && isResetMarker(it->second);
+}
+// -----------------------------------------------------------------------------
+
+bool PropertyUpdate::hasChangeFor(rtl::OUString const & _aLocale) const
+{
+ ValueList::const_iterator it = m_aValues.find(_aLocale);
+
+ return it != m_aValues.end();
+}
+// -----------------------------------------------------------------------------
+
+uno::Any PropertyUpdate::getValueFor(rtl::OUString const & _aLocale) const
+{
+ ValueList::const_iterator it = m_aValues.find(_aLocale);
+
+ OSL_ENSURE(it != m_aValues.end() && !isResetMarker(it->second),
+ "PropertyUpdate: Should not call getValue() unless hasValue() returns true" );
+
+ return it != m_aValues.end() && !isResetMarker(it->second) ? it->second : uno::Any();
+}
+// -----------------------------------------------------------------------------
+
+void PropertyUpdate::writeValueToLayer(backenduno::XLayerHandler * _pLayer, uno::Any const & _aValue)
+{
+ OSL_ASSERT(_pLayer);
+ if ( !isResetMarker(_aValue) )
+ _pLayer->setPropertyValue(_aValue);
+
+ // else - to reset - do nothing
+}
+// -----------------------------------------------------------------------------
+
+void PropertyUpdate::writeValueToLayerFor(backenduno::XLayerHandler * _pLayer, uno::Any const & _aValue, rtl::OUString const & _aLocale)
+{
+ OSL_ASSERT(_pLayer);
+ if (_aLocale == this->primarySlot())
+ this->writeValueToLayer(_pLayer,_aValue);
+
+ else if ( !isResetMarker(_aValue) )
+ _pLayer->setPropertyValueForLocale(_aValue,_aLocale);
+
+ // else - to reset - do nothing
+}
+// -----------------------------------------------------------------------------
+
+void PropertyUpdate::writeValuesToLayer(backenduno::XLayerHandler * _pLayer)
+{
+ OSL_ASSERT(_pLayer);
+ for (ValueList::const_iterator itV = beginValues(); itV != endValues(); ++itV)
+ this->writeValueToLayerFor(_pLayer, itV->second, itV->first);
+}
+// -----------------------------------------------------------------------------
+
+void PropertyUpdate::writeToLayer(backenduno::XLayerHandler * _pLayer)
+{
+ OSL_ASSERT(_pLayer);
+
+ _pLayer->overrideProperty( this->getName(), this->updateFlags(), this->m_aType, false );
+ this->writeValuesToLayer(_pLayer);
+ _pLayer->endProperty();
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+
+PropertyAdd::PropertyAdd(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, uno::Type const & _aType)
+: ElementUpdate(_pParent,_aName,_nFlags,_nFlags)
+, m_aValueType(_aType)
+, m_aValue()
+{
+
+}
+// -----------------------------------------------------------------------------
+
+PropertyAdd::PropertyAdd(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, uno::Any const & _aValue)
+: ElementUpdate(_pParent,_aName,_nFlags,_nFlags)
+, m_aValueType(_aValue.getValueType())
+, m_aValue(_aValue)
+{
+}
+// -----------------------------------------------------------------------------
+
+void PropertyAdd::writeToLayer(backenduno::XLayerHandler * _pLayer)
+{
+ OSL_ASSERT(_pLayer);
+ if (this->hasValue())
+ _pLayer->addPropertyWithValue(this->getName(),this->updateFlags(),this->getValue());
+ else
+ _pLayer->addProperty(this->getName(),this->updateFlags(),this->getValueType());
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+PropertyReset::PropertyReset(NodeUpdate * _pParent, rtl::OUString const & _aName)
+: ElementUpdate(_pParent,_aName,0,0)
+{
+}
+// -----------------------------------------------------------------------------
+
+void PropertyReset::writeToLayer(backenduno::XLayerHandler * _pLayer)
+{
+ (void) _pLayer; // avoid warning about unused parameter
+ OSL_ASSERT(_pLayer);
+ // skip - nothing to write
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/updatedata.hxx b/configmgr/source/backend/updatedata.hxx
new file mode 100644
index 000000000000..01a155aedaf9
--- /dev/null
+++ b/configmgr/source/backend/updatedata.hxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updatedata.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_UPDATEDATA_HXX
+#define CONFIGMGR_BACKEND_UPDATEDATA_HXX
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/ustring.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include "utility.hxx"
+
+#ifndef INCLUDED_SET
+#include <set>
+#define INCLUDED_SET
+#endif
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+namespace com { namespace sun { namespace star { namespace configuration { namespace backend {
+ class XLayerHandler;
+} } } } }
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+ class ElementUpdate;
+ class NodeUpdate;
+ class NodeModification;
+ class NodeReplace;
+ class NodeDrop;
+ class PropertyUpdate;
+ class PropertyAdd;
+ class PropertyReset;
+
+// -----------------------------------------------------------------------------
+
+ class NamedUpdate : public salhelper::SimpleReferenceObject
+ {
+ rtl::OUString const m_aName;
+
+ protected:
+ explicit
+ NamedUpdate(rtl::OUString const & _aName)
+ : m_aName(_aName)
+ {}
+
+ ~NamedUpdate() {};
+
+ public:
+ rtl::OUString const & getName() const { return m_aName; }
+ };
+// -----------------------------------------------------------------------------
+ class ElementUpdate : public NamedUpdate
+ {
+ NodeUpdate * m_pParent;
+ sal_Int16 m_nFlags;
+ sal_Int16 m_nFlagsMask;
+ protected:
+ ElementUpdate(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask);
+
+ public:
+ virtual NodeUpdate * asNodeUpdate(bool _bMerged = false);
+ virtual PropertyUpdate * asPropertyUpdate();
+
+ virtual void writeToLayer(backenduno::XLayerHandler * _pLayer) = 0;
+
+ public:
+ NodeUpdate * getParent() const { return m_pParent; }
+
+ sal_Int16 changedFlags() const { return m_nFlagsMask; }
+ sal_Int16 updateFlags(sal_Int16 _nFlags = 0) const;
+
+ };
+// -----------------------------------------------------------------------------
+
+ class NodeUpdate : public ElementUpdate
+ {
+ typedef std::map< rtl::OUString, rtl::Reference<ElementUpdate> > ElementList;
+ public:
+ enum Op { modify, reset, replace };
+
+ protected:
+ NodeUpdate(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, Op _op);
+
+ virtual NodeUpdate * asNodeUpdate(bool _bMerged);
+
+ public:
+ bool addNodeUpdate (rtl::Reference<ElementUpdate> const & _aNode);
+ bool addPropertyUpdate (rtl::Reference<ElementUpdate> const & _aProp);
+ void removeNodeByName (rtl::OUString const & _aName);
+ void removePropertyByName (rtl::OUString const & _aName);
+
+ Op getOperation() const { return m_op; }
+
+ rtl::Reference<ElementUpdate> getNodeByName (rtl::OUString const & _aName) const;
+ rtl::Reference<ElementUpdate> getPropertyByName (rtl::OUString const & _aName) const;
+
+ ElementList::const_iterator beginNodes() const { return m_aNodes.begin(); }
+ ElementList::const_iterator endNodes() const { return m_aNodes.end(); };
+ ElementList::const_iterator beginProperties() const { return m_aProperties.begin(); };
+ ElementList::const_iterator endProperties() const { return m_aProperties.end(); };
+
+ bool hasChildren() const { return !m_aNodes.empty() || !m_aProperties.empty(); }
+
+ void writeChildrenToLayer(backenduno::XLayerHandler * _pLayer);
+ private:
+ ElementList m_aNodes;
+ ElementList m_aProperties;
+ ElementList m_aRemovedElements;
+ Op m_op;
+ };
+// -----------------------------------------------------------------------------
+
+ class NodeModification : public NodeUpdate
+ {
+ public:
+ NodeModification(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, sal_Bool _bReset);
+ virtual void writeToLayer(backenduno::XLayerHandler * _pLayer);
+ };
+// -----------------------------------------------------------------------------
+
+ class NodeReplace : public NodeUpdate
+ {
+ public:
+ NodeReplace(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags);
+ NodeReplace(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, rtl::OUString const & _aTemplateName, rtl::OUString const & _aTemplateComponent);
+
+ bool hasTemplate() const;
+ rtl::OUString getTemplateName() const { return m_aTemplateName; }
+ rtl::OUString getTemplateComponent() const { return m_aTemplateComponent; }
+
+ virtual void writeToLayer(backenduno::XLayerHandler * _pLayer);
+ private:
+ rtl::OUString m_aTemplateName;
+ rtl::OUString m_aTemplateComponent;
+ };
+// -----------------------------------------------------------------------------
+
+ class NodeDrop : public ElementUpdate
+ {
+ public:
+ NodeDrop(NodeUpdate * _pParent, rtl::OUString const & _aName);
+
+ virtual void writeToLayer(backenduno::XLayerHandler * _pLayer);
+ };
+// -----------------------------------------------------------------------------
+
+ class PropertyUpdate : public ElementUpdate
+ {
+ typedef std::map< rtl::OUString, uno::Any > ValueList;
+
+ ValueList m_aValues;
+ uno::Type m_aType;
+ public:
+ PropertyUpdate(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, sal_Int16 _nFlagsMask, uno::Type const & _aType);
+
+ bool setValueFor(rtl::OUString const & _aLocale, uno::Any const & _aValueUpdate);
+ bool resetValueFor(rtl::OUString const & _aLocale);
+ void removeValueFor(rtl::OUString const & _aLocale);
+
+ bool setValue(uno::Any const & _aValueUpdate) { return setValueFor(primarySlot(), _aValueUpdate); }
+ bool resetValue() { return resetValueFor(primarySlot()); }
+ void removeValue() { removeValueFor(primarySlot()); }
+
+ void finishValue();
+
+ uno::Type const & getValueType() const { return m_aType; }
+
+ bool hasValueFor(rtl::OUString const & _aLocale) const;
+ bool hasValue() const { return hasValueFor(primarySlot()); }
+
+ bool hasResetFor(rtl::OUString const & _aLocale) const;
+ bool hasReset() const { return hasResetFor(primarySlot()); }
+
+ bool hasChangeFor(rtl::OUString const & _aLocale) const;
+ bool hasChange() const { return hasChangeFor(primarySlot()); }
+
+ uno::Any getValueFor(rtl::OUString const & _aLocale) const;
+ uno::Any getValue() const { return getValueFor(primarySlot()); }
+
+ ValueList::const_iterator beginValues() const { return m_aValues.begin(); }
+ ValueList::const_iterator endValues() const { return m_aValues.end(); }
+
+ void writeValueToLayerFor(backenduno::XLayerHandler * _pLayer, uno::Any const & _aValue, rtl::OUString const & _aLocale);
+ void writeValueToLayer(backenduno::XLayerHandler * _pLayer, uno::Any const & _aValue);
+ void writeValuesToLayer(backenduno::XLayerHandler * _pLayer);
+ virtual void writeToLayer(backenduno::XLayerHandler * _pLayer);
+ private:
+ rtl::OUString primarySlot() const { return rtl::OUString(); }
+
+ static uno::Any const & getResetMarker();
+ static inline bool isResetMarker(uno::Any const & _aValue);
+
+ virtual PropertyUpdate * asPropertyUpdate();
+ };
+// -----------------------------------------------------------------------------
+
+ class PropertyAdd : public ElementUpdate
+ {
+ uno::Type m_aValueType;
+ uno::Any m_aValue;
+ public:
+ PropertyAdd(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, uno::Type const & _aType);
+ PropertyAdd(NodeUpdate * _pParent, rtl::OUString const & _aName, sal_Int16 _nFlags, uno::Any const & _aValue);
+
+ bool hasValue() const { return !! m_aValue.hasValue(); }
+ uno::Any const & getValue() const { return m_aValue; }
+ uno::Type const & getValueType() const { return m_aValueType; }
+
+ virtual void writeToLayer(backenduno::XLayerHandler * _pLayer);
+ };
+// -----------------------------------------------------------------------------
+
+ class PropertyReset : public ElementUpdate
+ {
+ public:
+ PropertyReset(NodeUpdate * _pParent, rtl::OUString const & _aName);
+
+ virtual void writeToLayer(backenduno::XLayerHandler * _pLayer);
+ };
+// -----------------------------------------------------------------------------
+
+ } // namespace backend
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/updatedispatch.cxx b/configmgr/source/backend/updatedispatch.cxx
new file mode 100644
index 000000000000..6e805308c7a9
--- /dev/null
+++ b/configmgr/source/backend/updatedispatch.cxx
@@ -0,0 +1,499 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updatedispatch.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "treefragment.hxx"
+#include "updatedispatch.hxx"
+#include "configpath.hxx"
+#include "node.hxx"
+#include "matchlocale.hxx"
+
+#include <com/sun/star/configuration/backend/XUpdateHandler.hpp>
+#include <com/sun/star/configuration/backend/NodeAttribute.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+
+UpdateDispatcher::UpdateDispatcher(uno::Reference< backenduno::XUpdateHandler > const & _xUpdateHandler, rtl::OUString const & _aLocale)
+: m_pContextPath(NULL)
+, m_xUpdateHandler(_xUpdateHandler)
+, m_aLocale(_aLocale)
+, m_aElementName()
+, m_bInValueSet(false)
+, m_bInLocalizedValues(false)
+{
+}
+// -----------------------------------------------------------------------------
+
+UpdateDispatcher::~UpdateDispatcher()
+{
+}
+// -----------------------------------------------------------------------------
+
+void UpdateDispatcher::dispatchUpdate(configuration::AbsolutePath const & _aRootPath, SubtreeChange const& _anUpdate)
+{
+ if (!m_xUpdateHandler.is())
+ {
+ rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("ERROR: Cannot dispatch update - no handler found") );
+ throw uno::RuntimeException(sMsg,NULL);
+ }
+
+ OSL_PRECOND( !_aRootPath.isRoot(), "Cannot apply update, where root is outside a component" );
+
+ OSL_PRECOND( m_pContextPath == NULL, "Update Dispatcher already has a context path" );
+ if (!_aRootPath.getParentPath().isRoot())
+ {
+ OSL_ENSURE(false,"Obsolete functionality used: starting update with non-empty context");
+ m_pContextPath = &_aRootPath;
+ }
+
+ this->startUpdate();
+ this->applyToChange(_anUpdate);
+ this->endUpdate();
+
+ m_pContextPath = NULL;
+}
+// -----------------------------------------------------------------------------
+
+void UpdateDispatcher::startUpdate()
+{
+ m_xUpdateHandler->startUpdate();
+ m_bInValueSet = false;
+ m_bInLocalizedValues = false;
+ m_aElementName = rtl::OUString();
+
+ if (m_pContextPath)
+ {
+ std::vector<configuration::Path::Component>::const_reverse_iterator it = m_pContextPath->begin();
+ std::vector<configuration::Path::Component>::const_reverse_iterator stop = m_pContextPath->end();
+
+ OSL_ASSERT(it != stop);
+ --stop;
+
+ for ( ; it != stop; ++it)
+ {
+ m_xUpdateHandler->modifyNode(it->getName(),0,0,false);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+void UpdateDispatcher::endUpdate()
+{
+ if (m_pContextPath)
+ {
+ std::vector<configuration::Path::Component>::const_reverse_iterator it = m_pContextPath->begin();
+ std::vector<configuration::Path::Component>::const_reverse_iterator stop = m_pContextPath->end();
+
+ OSL_ASSERT(it != stop);
+ --stop;
+
+ for ( ; it != stop; ++it)
+ {
+ m_xUpdateHandler->endNode();
+ }
+ }
+ m_xUpdateHandler->endUpdate();
+}
+// -----------------------------------------------------------------------------
+
+void UpdateDispatcher::handle(ValueChange const& aValueNode)
+{
+ // special case: doing members of a localized property (as set)
+ if (m_bInLocalizedValues)
+ {
+ rtl::OUString aLocale = aValueNode.getNodeName();
+
+ if (aLocale.getLength())
+ {
+ if ( aValueNode.isToDefault() )
+ m_xUpdateHandler->resetPropertyValueForLocale( aLocale );
+ else
+ m_xUpdateHandler->setPropertyValueForLocale( aValueNode.getNewValue(), aLocale );
+ }
+ else
+ {
+ if ( aValueNode.isToDefault() )
+ m_xUpdateHandler->resetPropertyValue( );
+ else
+ m_xUpdateHandler->setPropertyValue( aValueNode.getNewValue() );
+ }
+ return;
+ }
+
+ // normal case: updating a single property
+ switch (aValueNode.getMode())
+ {
+ case ValueChange::wasDefault:
+ if (aValueNode.isReplacedValue())
+ {
+
+ OSL_ENSURE(m_bInValueSet, "UpdateDispatcher: Cannot add/replace a value in a nonextensible node");
+ OSL_ENSURE(!aValueNode.isLocalizedValue(), "UpdateDispatcher: Cannot add a localized value in a layer");
+
+ sal_Int16 nAttr = getUpdateAttributes(aValueNode.getAttributes(),true);
+
+ if (aValueNode.getNewValue().hasValue())
+ {
+ m_xUpdateHandler->addOrReplacePropertyWithValue( aValueNode.getNodeName(),
+ nAttr,
+ aValueNode.getNewValue());
+ }
+ else
+ {
+ m_xUpdateHandler->addOrReplaceProperty( aValueNode.getNodeName(),
+ nAttr,
+ aValueNode.getValueType());
+ }
+
+ break;
+ }
+ // else fall thru to changeValue case
+
+ case ValueChange::changeValue:
+ {
+ sal_Int16 nAttr = getUpdateAttributes(aValueNode.getAttributes(),false);
+ sal_Int16 nAttrMask = getUpdateAttributeMask(aValueNode.getAttributes());
+
+ m_xUpdateHandler->modifyProperty( aValueNode.getNodeName(),
+ nAttr, nAttrMask,
+ aValueNode.getValueType() );
+
+ if (aValueNode.isLocalizedValue() && m_aLocale.getLength())
+ {
+ m_xUpdateHandler->setPropertyValueForLocale( aValueNode.getNewValue(), m_aLocale );
+ }
+ else
+ {
+ m_xUpdateHandler->setPropertyValue( aValueNode.getNewValue() );
+ }
+
+ m_xUpdateHandler->endProperty();
+ }
+ break;
+
+ case ValueChange::setToDefault:
+ m_xUpdateHandler->resetProperty( aValueNode.getNodeName() );
+ break;
+
+ case ValueChange::changeDefault:
+ OSL_ENSURE(false, "Illegal mode in ValueChange");
+ break;
+
+ default:
+ OSL_ENSURE(false, "Illegal mode in ValueChange");
+ break;
+ };
+}
+// -----------------------------------------------------------------------------
+
+void UpdateDispatcher::handle(AddNode const& aAddNode)
+{
+ rtl::Reference< data::TreeSegment > aAddedTree = aAddNode.getNewTree();
+
+ OSL_ENSURE(aAddedTree.is(), "AddNode has no new data -> cannot add anything");
+
+ OSL_ENSURE( ((m_bInValueSet||m_bInLocalizedValues) == aAddedTree->fragment->nodes[0].isValue()),
+ "Found added subtree in value set (extensible group)\n" );
+
+ this->visitTree(aAddedTree->fragment);
+}
+// -----------------------------------------------------------------------------
+
+void UpdateDispatcher::handle(RemoveNode const& aRemoveNode)
+{
+ OSL_ENSURE( !m_bInLocalizedValues, "UpdateDispatcher: Removing values for a specific locale is currently not supported");
+
+ rtl::Reference< data::TreeSegment > aRemovedTree = aRemoveNode.getRemovedTree();
+
+ OSL_ENSURE( !aRemovedTree.is() ||
+ ((m_bInValueSet||m_bInLocalizedValues) == aRemovedTree->fragment->nodes[0].isValue()),
+ "Found removed subtree in value set (extensible group)\n" );
+
+ if (m_bInLocalizedValues)
+ OSL_TRACE("configmgr: UpdateDispatcher - Removing value for locale ignored");
+
+ else if (m_bInValueSet)
+ m_xUpdateHandler->removeProperty( aRemoveNode.getNodeName() );
+
+ else
+ m_xUpdateHandler->removeNode( aRemoveNode.getNodeName() );
+}
+// -----------------------------------------------------------------------------
+
+void UpdateDispatcher::handle(SubtreeChange const& aSubtree)
+{
+ OSL_ENSURE( !m_bInLocalizedValues, "UpdateDispatcher: A localized value cannot be a complete subtree");
+ OSL_ENSURE( !m_bInValueSet, "UpdateDispatcher: A dynamic property cannot be a complete subtree");
+
+ sal_Int16 nAttr = getUpdateAttributes(aSubtree.getAttributes(),false);
+ sal_Int16 nAttrMask = getUpdateAttributeMask(aSubtree.getAttributes());
+
+ if (isLocalizedValueSet(aSubtree))
+ {
+ m_xUpdateHandler->modifyProperty( aSubtree.getNodeName(),
+ nAttr, nAttrMask,
+ uno::Type() );
+
+ m_bInLocalizedValues = true;
+ this->applyToChildren(aSubtree);
+ m_bInLocalizedValues = false;
+
+ m_xUpdateHandler->endProperty();
+ }
+
+ else
+ {
+ m_xUpdateHandler->modifyNode( aSubtree.getNodeName(),
+ nAttr, nAttrMask,
+ aSubtree.isToDefault() );
+
+ m_bInValueSet = isValueSet(aSubtree);
+ this->applyToChildren(aSubtree);
+ m_bInValueSet = false;
+
+ m_xUpdateHandler->endNode();
+ }
+}
+// -----------------------------------------------------------------------------
+
+bool UpdateDispatcher::handle(sharable::ValueNode * node)
+{
+ rtl::OUString aName;
+
+ // special case: doing members of a localized property (as set)
+ if (m_bInLocalizedValues)
+ {
+ // the node name is the locale
+ rtl::OUString aLocale;
+ OSL_VERIFY(testReplacedAndGetName(sharable::node(node), aLocale)); // "Adding a localized subvalue but not as root of element tree"
+
+ if (aLocale.getLength() && ! localehelper::isDefaultLanguage(aLocale))
+ {
+ m_xUpdateHandler->setPropertyValueForLocale(node->getValue(), aLocale);
+ }
+ else
+ {
+ m_xUpdateHandler->setPropertyValue(node->getValue());
+ }
+ }
+ else if (testReplacedAndGetName(sharable::node(node), aName) && sharable::node(node)->getAttributes().isRemovable()) // we must be inside a set of values
+ {
+
+ OSL_ENSURE(!node->info.isLocalized(), "UpdateDispatcher: Cannot add a localized value in a layer .");
+
+ sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),true);
+
+ if (!node->isNull())
+ {
+ m_xUpdateHandler->addOrReplacePropertyWithValue( aName,
+ nAttr,
+ node->getValue());
+ }
+ else
+ {
+ m_xUpdateHandler->addOrReplaceProperty( aName,
+ nAttr,
+ node->getValueType());
+ }
+ }
+ else // normal case: updating a single property //Inserting set
+ {
+ sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),false);
+ sal_Int16 nAttrMask = getUpdateAttributeMask(sharable::node(node)->getAttributes());
+
+ m_xUpdateHandler->modifyProperty( aName, nAttr, nAttrMask, node->getValueType() );
+
+ if (node->info.isLocalized() && m_aLocale.getLength())
+ {
+ m_xUpdateHandler->setPropertyValueForLocale(node->getValue(), m_aLocale);
+ }
+ else
+ {
+ m_xUpdateHandler->setPropertyValue(node->getValue());
+ }
+
+ m_xUpdateHandler->endProperty();
+ }
+ return false;
+}
+// -----------------------------------------------------------------------------
+
+bool UpdateDispatcher::handle(sharable::GroupNode * node)
+{
+ OSL_ENSURE( !m_bInLocalizedValues, "UpdateDispatcher: A localized value cannot be a complete group");
+
+ rtl::OUString aName;
+
+ if ( testReplacedAndGetName(sharable::node(node), aName) )
+ {
+ sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),true);
+
+ m_xUpdateHandler->addOrReplaceNode( aName, nAttr );
+
+ this->visitChildren(node);
+
+ m_xUpdateHandler->endNode();
+ }
+ else
+ {
+ sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),false);
+ sal_Int16 nAttrMask = getUpdateAttributeMask(sharable::node(node)->getAttributes());
+
+ m_xUpdateHandler->modifyNode( aName, nAttr, nAttrMask, false );
+
+ this->visitChildren(node);
+
+ m_xUpdateHandler->endNode();
+ }
+ return false;
+}
+// -----------------------------------------------------------------------------
+
+bool UpdateDispatcher::handle(sharable::SetNode * node)
+{
+ OSL_ENSURE( !m_bInLocalizedValues, "UpdateDispatcher: A localized value cannot be a complete set");
+
+ rtl::OUString aName;
+
+ if ( testReplacedAndGetName(sharable::node(node), aName) )
+ {
+ OSL_ENSURE( !node->info.isLocalized(), "UpdateDispatcher: Cannot add a localized value in a layer." );
+
+ sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),true);
+
+ m_xUpdateHandler->addOrReplaceNode( aName, nAttr );
+
+ this->visitElements(node);
+
+ m_xUpdateHandler->endNode();
+ }
+ else
+ {
+ sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),false);
+ sal_Int16 nAttrMask = getUpdateAttributeMask(sharable::node(node)->getAttributes());
+
+ if (node->info.isLocalized())
+ {
+ m_xUpdateHandler->modifyProperty( aName, nAttr, nAttrMask, uno::Type() );
+
+ m_bInLocalizedValues = true;
+ this->visitElements(node);
+ m_bInLocalizedValues = false;
+
+ m_xUpdateHandler->endProperty();
+ }
+
+ else
+ {
+ m_xUpdateHandler->modifyNode( aName, nAttr, nAttrMask, false );
+
+ this->visitElements(node);
+
+ m_xUpdateHandler->endNode();
+ }
+ }
+ return false;
+}
+// -----------------------------------------------------------------------------
+
+bool UpdateDispatcher::testReplacedAndGetName(sharable::Node * node, rtl::OUString & _aName)
+{
+ if (m_aElementName.getLength())
+ {
+ OSL_ENSURE( node->isFragmentRoot(), "ERROR - UpdateDispatcher: Found orphaned 'element' name for inner node");
+ _aName = m_aElementName;
+ m_aElementName = rtl::OUString();
+ return true;
+ }
+ else
+ {
+ OSL_ENSURE(!node->isFragmentRoot(), "ERROR - UpdateDispatcher: Found no 'element' name for fragment root node");
+ _aName = node->getName();
+ return false;
+ }
+}
+// -----------------------------------------------------------------------------
+
+bool UpdateDispatcher::handle(sharable::TreeFragment * tree)
+{
+ m_aElementName = tree->getName();
+ bool done = SetVisitor::handle(tree); // dispatch to root node
+ m_aElementName = rtl::OUString(); // clear - just to be safe
+ return done;
+}
+// -----------------------------------------------------------------------------
+
+sal_Int16 UpdateDispatcher::getUpdateAttributes(node::Attributes const & _aAttributes, bool bAdded)
+{
+ namespace NodeAttribute = backenduno::NodeAttribute;
+
+ // no support for post-creation attribute changes yet
+ if (!bAdded)
+ {
+ OSL_ENSURE( getUpdateAttributeMask(_aAttributes) == 0,
+ "Incomplete support for attribute changes" );
+ return 0;
+ }
+
+ sal_Int16 nResult = 0;
+
+ if (_aAttributes.isReadonly())
+ nResult = NodeAttribute::READONLY;
+
+ if (_aAttributes.isFinalized())
+ nResult |= NodeAttribute::FINALIZED;
+
+ if (!_aAttributes.isNullable())
+ nResult |= NodeAttribute::MANDATORY;
+
+ return nResult;
+}
+// -----------------------------------------------------------------------------
+
+sal_Int16 UpdateDispatcher::getUpdateAttributeMask(node::Attributes const & /*_aAttributes*/)
+{
+ // no support for post-creation attribute changes yet
+ return 0;
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/backend/updatedispatch.hxx b/configmgr/source/backend/updatedispatch.hxx
new file mode 100644
index 000000000000..e950557b251e
--- /dev/null
+++ b/configmgr/source/backend/updatedispatch.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updatedispatch.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_UPDATEDISPATCH_HXX
+#define CONFIGMGR_BACKEND_UPDATEDISPATCH_HXX
+
+#include "change.hxx"
+#include "nodevisitor.hxx"
+#include "utility.hxx"
+#include <boost/utility.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+namespace com { namespace sun { namespace star { namespace configuration { namespace backend {
+ class XUpdateHandler;
+} } } } }
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace configuration
+ {
+ class AbsolutePath;
+ }
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+
+// -----------------------------------------------------------------------------
+
+ class UpdateDispatcher: private boost::noncopyable, private ChangeTreeAction, private data::SetVisitor
+ {
+ public:
+ UpdateDispatcher(uno::Reference< backenduno::XUpdateHandler > const & _xUpdateHandler, rtl::OUString const & _aLocale);
+ ~UpdateDispatcher();
+
+ void dispatchUpdate(configuration::AbsolutePath const & _aRootPath, SubtreeChange const& _anUpdate);
+
+ protected:
+ using data::NodeVisitor::handle;
+
+ private:
+ void startUpdate();
+ void endUpdate();
+
+ virtual void handle(ValueChange const& aValueNode);
+ virtual void handle(AddNode const& aAddNode);
+ virtual void handle(RemoveNode const& aRemoveNode);
+ virtual void handle(SubtreeChange const& aSubtree) ;
+
+ virtual bool handle(sharable::ValueNode * node);
+ virtual bool handle(sharable::GroupNode * node);
+ virtual bool handle(sharable::SetNode * node);
+ virtual bool handle(sharable::TreeFragment * tree);
+ private:
+ sal_Int16 getUpdateAttributes(node::Attributes const & _aAttributes, bool bAdded);
+ sal_Int16 getUpdateAttributeMask(node::Attributes const & _aAttributes);
+
+ bool testReplacedAndGetName(sharable::Node * node, rtl::OUString & _aName);
+ private:
+ configuration::AbsolutePath const * m_pContextPath;
+ uno::Reference< backenduno::XUpdateHandler > m_xUpdateHandler;
+ rtl::OUString m_aLocale;
+ rtl::OUString m_aElementName;
+ bool m_bInValueSet;
+ bool m_bInLocalizedValues;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace backend
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backend/updatesvc.cxx b/configmgr/source/backend/updatesvc.cxx
new file mode 100644
index 000000000000..0b23621baf32
--- /dev/null
+++ b/configmgr/source/backend/updatesvc.cxx
@@ -0,0 +1,281 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updatesvc.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "updatesvc.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include "emptylayer.hxx"
+#include <com/sun/star/configuration/backend/XUpdatableLayer.hpp>
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace beans = ::com::sun::star::beans;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+sal_Char const * const aUpdateMergerServices[] =
+{
+ "com.sun.star.configuration.backend.LayerUpdateMerger",
+ 0
+};
+const ServiceImplementationInfo aUpdateMergerSI =
+{
+ "com.sun.star.comp.configuration.backend.LayerUpdateMerger",
+ aUpdateMergerServices,
+ 0
+};
+// -----------------------------------------------------------------------------
+
+const ServiceRegistrationInfo* getUpdateMergerServiceInfo()
+{ return getRegistrationInfo(& aUpdateMergerSI); }
+// -----------------------------------------------------------------------------
+
+inline
+ServiceInfoHelper UpdateService::getServiceInfo()
+{
+ return & aUpdateMergerSI;
+}
+// -----------------------------------------------------------------------------
+
+
+UpdateService::UpdateService(uno::Reference< uno::XComponentContext > const & _xContext)
+: m_xServiceFactory(_xContext->getServiceManager(),uno::UNO_QUERY)
+, m_aSourceMode(merge)
+{
+ if (!m_xServiceFactory.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration Update Merger: Context has no service manager (or missing interface)"));
+ throw uno::RuntimeException(sMessage,NULL);
+ }
+}
+// -----------------------------------------------------------------------------
+
+// XInitialization
+
+void SAL_CALL
+ UpdateService::initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException)
+{
+ sal_Int16 const nCount = static_cast<sal_Int16>(aArguments.getLength());
+
+ if (sal_Int32(nCount) != aArguments.getLength())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Too many arguments to initialize a Configuration Update Merger"));
+ throw lang::IllegalArgumentException(sMessage,*this,0);
+ }
+
+ for (sal_Int16 i = 0; i < nCount; ++i)
+ {
+ uno::Reference< backenduno::XUpdatableLayer > xUpdLayer;
+ if (aArguments[i] >>= xUpdLayer)
+ {
+ m_xSourceLayer = xUpdLayer.get();
+ m_xLayerWriter.clear();
+
+ OSL_ASSERT( uno::Reference< backenduno::XUpdatableLayer >::query(m_xSourceLayer).is() || !xUpdLayer.is() );
+
+ continue;
+ }
+
+ if (aArguments[i] >>= m_xSourceLayer)
+ continue;
+
+ if (aArguments[i] >>= m_xLayerWriter)
+ continue;
+
+ beans::NamedValue aExtraArg;
+ if (aArguments[i] >>= aExtraArg)
+ {
+ OSL_VERIFY( setImplementationProperty(aExtraArg.Name, aExtraArg.Value) );
+
+ continue;
+ }
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Cannot use argument to initialize a Configuration Update Merger"
+ "- XLayer, XLayerHandler or XUpdatableLayer expected"));
+ throw lang::IllegalArgumentException(sMessage,*this,i);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool UpdateService::setImplementationProperty(rtl::OUString const & aName, uno::Any const & aValue)
+{
+ if (aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Overwrite")))
+ {
+ sal_Bool bOverwrite = sal_False;
+ if (aValue >>= bOverwrite)
+ {
+ if (!bOverwrite)
+ m_aSourceMode = protect;
+
+ else if (protect == m_aSourceMode)
+ m_aSourceMode = merge;
+
+ return true;
+ }
+ }
+
+ else if (aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Truncate")))
+ {
+ sal_Bool bTruncate = sal_False;
+ if (aValue >>= bTruncate)
+ {
+ if (!bTruncate)
+ m_aSourceMode = merge;
+
+ else if (merge == m_aSourceMode)
+ m_aSourceMode = truncate;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+// -----------------------------------------------------------------------------
+
+bool UpdateService::validateSourceLayerAndCheckNotEmpty() SAL_THROW( (lang::IllegalAccessException) )
+{
+ switch (m_aSourceMode)
+ {
+ case merge: // TODO: check for readonly layer
+ return true;
+
+ case protect: if (!checkEmptyLayer(m_xSourceLayer))
+ raiseIllegalAccessException("UpdateService: Layer already exists");
+ // else fall through
+
+ case truncate: return false;
+
+ default: OSL_ASSERT(!"not reached");
+ return true;
+ }
+}
+// -----------------------------------------------------------------------------
+
+uno::Reference< backenduno::XLayer > UpdateService::getSourceLayer() SAL_THROW( (lang::IllegalAccessException) )
+{
+ if ( validateSourceLayerAndCheckNotEmpty() )
+ return m_xSourceLayer;
+ else
+ return createEmptyLayer();
+}
+// -----------------------------------------------------------------------------
+
+void UpdateService::raiseIllegalAccessException(sal_Char const * pMsg)
+ SAL_THROW( (lang::IllegalAccessException) )
+{
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+ throw lang::IllegalAccessException(sMsg,*this);
+}
+// -----------------------------------------------------------------------------
+
+void UpdateService::writeUpdatedLayer(uno::Reference< backenduno::XLayer > const & _xLayer)
+{
+ OSL_ENSURE( _xLayer.is(), "UpdateService: Trying to write NULL XLayer");
+
+ if (!_xLayer.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Update Merger - Internal error: trying to write a NULL Layer"));
+ throw uno::RuntimeException(sMessage,*this);
+ }
+
+ // use our layer writer, if we have one
+ if ( m_xLayerWriter.is() )
+ {
+ _xLayer->readData( m_xLayerWriter );
+ return;
+ }
+
+ // look for an updatable layer otherwise
+ uno::Reference< backenduno::XUpdatableLayer > xUpdLayer(m_xSourceLayer, uno::UNO_QUERY);
+ if (xUpdLayer.is())
+ {
+ xUpdLayer->replaceWith( _xLayer );
+ return;
+ }
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Update Merger: Cannot write merge results - no recipient available."));
+ throw uno::RuntimeException(sMessage,*this);
+}
+// -----------------------------------------------------------------------------
+
+// XServiceInfo
+
+::rtl::OUString SAL_CALL
+ UpdateService::getImplementationName( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getImplementationName( );
+}
+// -----------------------------------------------------------------------------
+
+
+sal_Bool SAL_CALL
+ UpdateService::supportsService( const ::rtl::OUString& ServiceName )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().supportsService( ServiceName );
+}
+// -----------------------------------------------------------------------------
+
+
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ UpdateService::getSupportedServiceNames( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getSupportedServiceNames( );
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/backend/updatesvc.hxx b/configmgr/source/backend/updatesvc.hxx
new file mode 100644
index 000000000000..4fcdc71dfd89
--- /dev/null
+++ b/configmgr/source/backend/updatesvc.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updatesvc.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_UPDATESVC_HXX
+#define CONFIGMGR_BACKEND_UPDATESVC_HXX
+
+#include "serviceinfohelper.hxx"
+#include <cppuhelper/implbase3.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/configuration/backend/XUpdateHandler.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace com { namespace sun { namespace star { namespace configuration { namespace backend {
+ class XLayerHandler;
+ class XLayer;
+} } } } }
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace backend
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+ class UpdateService : public ::cppu::WeakImplHelper3<
+ lang::XInitialization,
+ lang::XServiceInfo,
+ backenduno::XUpdateHandler
+ >
+ {
+ public:
+ explicit
+ UpdateService(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& ServiceName )
+ throw (uno::RuntimeException);
+
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException);
+
+ protected:
+ uno::Reference< lang::XMultiServiceFactory > getServiceFactory() const
+ { return m_xServiceFactory; }
+
+ void checkSourceLayer() SAL_THROW( (lang::IllegalAccessException) )
+ { validateSourceLayerAndCheckNotEmpty(); }
+
+ uno::Reference< backenduno::XLayer > getSourceLayer() SAL_THROW( (lang::IllegalAccessException) );
+
+ void writeUpdatedLayer(uno::Reference< backenduno::XLayer > const & _xLayer);
+
+ virtual sal_Bool setImplementationProperty(rtl::OUString const & aName, uno::Any const & aValue);
+
+ void raiseIllegalAccessException(sal_Char const * pMsg)
+ SAL_THROW( (lang::IllegalAccessException) );
+
+ private:
+ bool validateSourceLayerAndCheckNotEmpty() SAL_THROW( (lang::IllegalAccessException) );
+
+ private:
+ uno::Reference< lang::XMultiServiceFactory > m_xServiceFactory;
+ uno::Reference< backenduno::XLayer > m_xSourceLayer;
+ uno::Reference< backenduno::XLayerHandler > m_xLayerWriter;
+ enum { merge, truncate, protect } m_aSourceMode;
+
+ static ServiceInfoHelper getServiceInfo();
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/backendhelper/backendlayerhelper.cxx b/configmgr/source/backendhelper/backendlayerhelper.cxx
new file mode 100644
index 000000000000..b6a9fcda9869
--- /dev/null
+++ b/configmgr/source/backendhelper/backendlayerhelper.cxx
@@ -0,0 +1,364 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendlayerhelper.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+
+#include "backendlayerhelper.hxx"
+#include <com/sun/star/configuration/backend/PropertyInfo.hpp>
+
+namespace configmgr { namespace backendhelper {
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+uno::Type toType(const ::rtl::OUString& _rType)
+ {
+ uno::Type aRet;
+
+ if (_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("boolean")))
+ aRet = ::getBooleanCppuType();
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("short")))
+ aRet = ::getCppuType(static_cast<sal_Int16 const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("int")))
+ aRet = ::getCppuType(static_cast<sal_Int32 const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("integer")))
+ aRet = ::getCppuType(static_cast<sal_Int32 const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("long")))
+ aRet = ::getCppuType(static_cast<sal_Int64 const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("double")))
+ aRet = ::getCppuType(static_cast<double const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("string")))
+ aRet = ::getCppuType(static_cast<rtl::OUString const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("binary")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int8> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("any")))
+ aRet = ::getCppuType(static_cast<uno::Any const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("boolean-list")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Bool> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("short-list")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int16> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("int-list")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int32> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("integer-list")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int32> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("long-list")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int64> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("double-list")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<double> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("string-list")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<rtl::OUString> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("binary-list")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<uno::Sequence<sal_Int8> > const*>(0));
+
+ else
+ {
+ ::rtl::OString aStr("Unknown type! ");
+ aStr += rtl::OUStringToOString(_rType,RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(0,aStr.getStr());
+ }
+
+ return aRet;
+ }
+
+//------------------------------------------------------------------------------
+
+IOONode::IOONode(const rtl::OUString& sName):
+ mName(sName)
+{
+}
+
+//------------------------------------------------------------------------------
+OOProperty::OOProperty(
+ const rtl::OUString& sName,const rtl::OUString& sPropType,
+ const uno::Any& aPropValue,sal_Bool bProtected)
+ :IOONode(sName), mPropType(sPropType), mPropValue(aPropValue),
+ mbProtected(bProtected)
+{
+}
+//------------------------------------------------------------------------------
+OONode::OONode(const rtl::OUString& sName)
+ :IOONode(sName)
+{
+}
+
+OONode::OONode()
+ :IOONode(rtl::OUString())
+{
+}
+IOONode* OONode::addChild(IOONode* aChild)
+{
+ mChildList.push_back(aChild);
+ return aChild;
+}
+const std::vector<IOONode*>& OONode::getChildren()
+{
+ return mChildList;
+}
+
+IOONode* OONode::getChild(const rtl::OUString& aChildName)
+{
+ for (sal_uInt32 i=0; i< mChildList.size();++i)
+ {
+ if (mChildList[i]->getName() == aChildName)
+ return mChildList[i];
+ }
+ return NULL;
+}
+OONode::~OONode()
+{
+ for (sal_uInt32 i=0; i< mChildList.size();++i)
+ {
+ delete mChildList[i];
+ }
+ mChildList.clear();
+}
+//------------------------------------------------------------------------------
+ sal_Bool addChildrenToNodeTree(
+ OONode * aNode,
+ sal_Int32 nNextToken,
+ const backend::PropertyInfo& aPropInfo,
+ const uno::Reference<uno::XInterface>& xContext)
+{
+ do
+ {
+ rtl::OUString aName = aPropInfo.Name.getToken(0, '/',nNextToken);
+ if (aName.getLength() == 0)
+ {
+ throw backend::MalformedDataException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Malformed OpenOffice Key specified")),
+ xContext, uno::Any()) ;
+ }
+ //Check if Property -> nNextToken == -1
+ if(nNextToken != -1)
+ {
+ //check if child already exists
+ IOONode* aChildNode= aNode->getChild(aName);
+ if (aChildNode == NULL)
+ {
+ aChildNode = new OONode(aName);
+ if (aChildNode != 0)
+ {
+ aNode->addChild( aChildNode);
+ }
+ }
+
+ sal_Bool bFinished =addChildrenToNodeTree(
+ aChildNode->getComposite(),
+ nNextToken,
+ aPropInfo,
+ xContext);
+ //Check that if you have finished parsing string therefore no
+ //more children
+ if (bFinished)
+ break;
+ }
+ else
+ {
+ //Add Property
+ IOONode* aProperty = new OOProperty(aName,
+ aPropInfo.Type,
+ aPropInfo.Value,
+ aPropInfo.Protected);
+ if (aProperty != 0)
+ {
+ aNode->addChild( aProperty);
+ }
+ //Return finished is true when you are finished parsing the string
+ if( nNextToken == -1)
+ {
+ return sal_True;
+ }
+ }
+ }
+ while (nNextToken >= 0 ) ;
+ return sal_True;
+}
+//------------------------------------------------------------------------------
+void processChildren(
+ std::vector<IOONode*> aChildList,
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+{
+ for(sal_uInt32 i=0; i <aChildList.size(); ++i)
+ {
+ OONode * aTestOONode = aChildList[i]->getComposite();
+ if (aTestOONode)
+ {
+ xHandler->overrideNode(aTestOONode->getName(),0,false);
+ processChildren(aTestOONode->getChildren(),xHandler);
+ xHandler->endNode();
+ }
+ else
+ {
+ OOProperty* aProperty = aChildList[i]->asOOProperty();
+ sal_Int16 aAttributes = aProperty->isProtected() ? 256:0;
+ //Convert Type either simple or list
+ uno::Type aType = toType( aProperty->getType());
+
+ xHandler->overrideProperty(aProperty->getName(),
+ aAttributes,
+ aType,
+ false);
+
+ xHandler->setPropertyValue(aProperty->getValue());
+ xHandler->endProperty();
+ }
+
+ }
+}
+//------------------------------------------------------------------------------
+void buildNodeTree(
+ const uno::Sequence< backend::PropertyInfo >& aPropertyInfos,
+ const uno::Reference<uno::XInterface>& xContext,
+ OONode& aNodeTree)
+{
+ sal_Int32 nNextToken =0;
+ rtl::OUString aName = aPropertyInfos[0].Name.getToken(0, '/',nNextToken);
+ if((nNextToken ==-1)||(aName.getLength()==0))
+ {
+ throw backend::MalformedDataException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Malformed OpenOffice Key specified")),
+ xContext, uno::Any()) ;
+
+ }
+ aNodeTree.setName(aName);
+ sal_Int32 size = aPropertyInfos.getLength();
+ for (sal_Int32 i =0; i < size; ++i)
+ {
+ addChildrenToNodeTree(&aNodeTree, nNextToken,aPropertyInfos[i],xContext);
+ }
+
+}
+//------------------------------------------------------------------------------
+BackendLayerHelper::BackendLayerHelper(
+ const uno::Reference<uno::XComponentContext>& /*xContext*/)
+ :cppu::WeakComponentImplHelper2<backend::XLayerContentDescriber, lang::XServiceInfo>(mMutex)
+{
+}
+//------------------------------------------------------------------------------
+
+BackendLayerHelper::~BackendLayerHelper(void) {}
+
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BackendLayerHelper::
+ getBackendLayerHelperName(void)
+{
+ static const rtl::OUString kImplementationName(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.configuration.backend.LayerDescriber")) ;
+
+ return kImplementationName ;
+}
+//------------------------------------------------------------------------------
+void SAL_CALL BackendLayerHelper::describeLayer(
+ const uno::Reference< backend::XLayerHandler >& xHandler,
+ const uno::Sequence< backend::PropertyInfo >& aPropertyInfos )
+ throw (lang::NullPointerException,
+ backend::MalformedDataException,
+ uno::RuntimeException)
+
+
+
+{
+ OONode aNodeTree;
+ buildNodeTree(aPropertyInfos, *this, aNodeTree);
+
+ //Descirbe the Layer to the XHandler Object
+ xHandler->startLayer();
+ xHandler->overrideNode(aNodeTree.getName(),0,false);
+ std::vector<IOONode*> aChildList = aNodeTree.getChildren();
+ processChildren(aChildList,xHandler);
+ xHandler->endNode();
+ xHandler->endLayer();
+
+
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL BackendLayerHelper::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return getBackendLayerHelperName() ;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString> SAL_CALL BackendLayerHelper::
+ getBackendLayerHelperServiceNames(void)
+{
+ uno::Sequence<rtl::OUString> aServices(1) ;
+ aServices[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.LayerDescriber")) ;
+ return aServices ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL BackendLayerHelper::supportsService(
+ const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< rtl::OUString > const svc = getBackendLayerHelperServiceNames();
+
+ for(sal_Int32 i = 0; i < svc.getLength(); ++i )
+ if(svc[i] == aServiceName)
+ return true;
+ return false;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString>
+SAL_CALL BackendLayerHelper::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ return getBackendLayerHelperServiceNames() ;
+}
+//------------------------------------------------------------------------------
+
+} // backendhelper
+} // configmgr
diff --git a/configmgr/source/backendhelper/backendlayerhelper.hxx b/configmgr/source/backendhelper/backendlayerhelper.hxx
new file mode 100644
index 000000000000..2a6dee1ecae0
--- /dev/null
+++ b/configmgr/source/backendhelper/backendlayerhelper.hxx
@@ -0,0 +1,168 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendlayerhelper.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_
+#define CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_
+
+#include <com/sun/star/configuration/backend/XLayerContentDescriber.hpp>
+
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/compbase2.hxx>
+
+namespace configmgr { namespace backendhelper {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backend = css::configuration::backend ;
+//------------------------------------------------------------------------------
+
+/**
+ * Implements the LayerContentDescriber service.
+ * Describes a set of configuration data to an XLayerHandler
+ * Object
+ */
+class BackendLayerHelper : public cppu::WeakComponentImplHelper2<backend::XLayerContentDescriber, lang::XServiceInfo> {
+public :
+ /**
+ Service constructor from a service factory.
+ @param xContext component context
+ */
+ BackendLayerHelper(const uno::Reference<uno::XComponentContext>& xContext) ;
+
+ /** Destructor */
+ ~BackendLayerHelper(void) ;
+
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException) ;
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& aServiceName )
+ throw (uno::RuntimeException) ;
+
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException) ;
+
+
+ //XLayerContentDescriber
+ virtual void SAL_CALL
+ describeLayer( const uno::Reference< backend::XLayerHandler >& xHandler,
+ const uno::Sequence< backend::PropertyInfo >& aPropertyInfos )
+ throw (lang::NullPointerException,
+ backend::MalformedDataException,
+ uno::RuntimeException);
+
+ /**
+ Provides the implementation name.
+
+ @return implementation name
+ */
+ static rtl::OUString SAL_CALL getBackendLayerHelperName(void) ;
+ /**
+ Provides the supported services names
+
+ @return service names
+ */
+ static uno::Sequence<rtl::OUString> SAL_CALL getBackendLayerHelperServiceNames(void) ;
+private:
+ osl::Mutex mMutex;
+
+} ;
+//------------------------------------------------------------------------------
+class OONode;
+class OOProperty;
+
+/**
+ Base class for representing OO properties and nodes
+*/
+class IOONode
+{
+public:
+ virtual OONode* getComposite(){return NULL;}
+ virtual ~IOONode(){};
+ virtual OOProperty* asOOProperty(){return NULL;}
+ rtl::OUString getName(){return mName;}
+ void setName(const rtl::OUString& sName){mName = sName;}
+protected:
+ IOONode(const rtl::OUString& sName);
+private:
+ rtl::OUString mName;
+};
+//------------------------------------------------------------------------------
+class OONode :public IOONode
+{
+public:
+
+ OONode(const rtl::OUString& sName);
+ OONode();
+ ~OONode();
+
+ IOONode* addChild(IOONode* aChild);
+ OONode* getComposite(){return this;}
+ const std::vector<IOONode*>& getChildren();
+ IOONode* getChild(const rtl::OUString& aChildName);
+
+private:
+ std::vector<IOONode*> mChildList;
+};
+//------------------------------------------------------------------------------
+class OOProperty :public IOONode
+{
+public:
+ OOProperty(const rtl::OUString& sName,
+ const rtl::OUString& sPropType,
+ const uno::Any& aPropValue,
+ sal_Bool bProtected);
+ ~OOProperty(){};
+
+ const rtl::OUString& getType(){return mPropType;}
+ uno::Any getValue(){return mPropValue;}
+ sal_Bool isProtected(){return mbProtected;}
+ OOProperty* asOOProperty(){return this;}
+
+private:
+ rtl::OUString mPropType;
+ uno::Any mPropValue;
+ sal_Bool mbProtected;
+};
+//------------------------------------------------------------------------------
+
+
+} } // configmgr.backendhelper
+
+#endif // CONFIGMGR_BACKENDHELPER_BACKENDLAYERHELPER_HXX_
+
+
diff --git a/configmgr/source/backendhelper/behelper.uno.xml b/configmgr/source/backendhelper/behelper.uno.xml
new file mode 100644
index 000000000000..a160360c5ec2
--- /dev/null
+++ b/configmgr/source/backendhelper/behelper.uno.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice/DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name>behelper.uno</module-name>
+ <component-description>
+ <author>Sarah Smith</author>
+ <name>com.sun.star.comp.configuration.backend.LayerDescriber</name>
+ <description>Describes the contents of a Layer to an XLayerHandler object. The contents of the layer
+is contained in a sequence of PropertyInfo structs</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>C++</language>
+ <status value="final"/>
+ <supported-services>com.sun.star.configuration.backend.LayerDescriber</supported-services>
+ <type>com.sun.star.configuration.backend.XLayerContentDescriber</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XSingleServiceFactory</type>
+ <type>com.sun.star.lang.XSingleComponentFactory</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.registry.XRegistryKey</type>
+ <type>com.sun.star.uno.Any</type>
+ <type>com.sun.star.uno.Sequence</type>
+ </component-description>
+ <project-build-dependency> comphelper </project-build-dependency>
+ <project-build-dependency> vos </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> salhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> comphelp2$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> vos2$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> salhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+</module-description>
diff --git a/configmgr/source/backendhelper/componentdf.cxx b/configmgr/source/backendhelper/componentdf.cxx
new file mode 100644
index 000000000000..ff36f410ceda
--- /dev/null
+++ b/configmgr/source/backendhelper/componentdf.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: componentdf.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "backendlayerhelper.hxx"
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif // _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+
+//==============================================================================
+
+static com::sun::star::uno::Reference<com::sun::star::uno::XInterface> SAL_CALL createBackendLayerHelper(
+ const com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext>& aContext) {
+ return * new configmgr::backendhelper::BackendLayerHelper(aContext) ;
+}
+//==============================================================================
+
+//------------------------------------------------------------------------------
+
+static const cppu::ImplementationEntry kImplementations_entries[] =
+{
+ {
+ createBackendLayerHelper,
+ configmgr::backendhelper::BackendLayerHelper::getBackendLayerHelperName,
+ configmgr::backendhelper::BackendLayerHelper::getBackendLayerHelperServiceNames,
+ cppu::createSingleComponentFactory,
+ NULL,
+ 0
+ },
+ { NULL, NULL, NULL, NULL, NULL, 0 }
+} ;
+//------------------------------------------------------------------------------
+
+extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL
+component_getImplementationEnvironment(
+ const sal_Char **ppEnvTypeName,
+ uno_Environment ** /* ppEnv */
+ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+//------------------------------------------------------------------------------
+
+extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(
+ void *aServiceManager, void *aRegistryKey)
+{
+ return cppu::component_writeInfoHelper(aServiceManager,
+ aRegistryKey,
+ kImplementations_entries) ;
+}
+//------------------------------------------------------------------------------
+
+extern "C" SAL_DLLPUBLIC_EXPORT void *component_getFactory(
+ const sal_Char *aImplementationName, void *aServiceManager,
+ void *aRegistryKey)
+{
+ return cppu::component_getFactoryHelper(aImplementationName,
+ aServiceManager,
+ aRegistryKey,
+ kImplementations_entries) ;
+}
+//------------------------------------------------------------------------------
diff --git a/configmgr/source/backendhelper/exports.dxp b/configmgr/source/backendhelper/exports.dxp
new file mode 100644
index 000000000000..9630d7e06768
--- /dev/null
+++ b/configmgr/source/backendhelper/exports.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
diff --git a/configmgr/source/backendhelper/makefile.mk b/configmgr/source/backendhelper/makefile.mk
new file mode 100644
index 000000000000..44b502b451b4
--- /dev/null
+++ b/configmgr/source/backendhelper/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJINC=$(PRJ)$/source
+PRJNAME=configmgr
+TARGET=behelper
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+DLLPRE =
+
+# --- Files ---
+
+
+SLOFILES=\
+ $(SLO)$/backendlayerhelper.obj \
+ $(SLO)$/componentdf.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+SHL1TARGET=$(TARGET).uno
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+SHL1IMPLIB=i$(SHL1TARGET)
+SHL1STDLIBS= \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+DEF1DES=Configuration: Backend Helper
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/data/anydata.cxx b/configmgr/source/data/anydata.cxx
new file mode 100644
index 000000000000..96bacf0e198e
--- /dev/null
+++ b/configmgr/source/data/anydata.cxx
@@ -0,0 +1,471 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: anydata.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "anydata.hxx"
+#include "sequence.hxx"
+#include "flags.hxx"
+#include "typeconverter.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace sharable
+ {
+//-----------------------------------------------------------------------------
+ namespace Type = data::Type;
+ namespace uno = ::com::sun::star::uno;
+//-----------------------------------------------------------------------------
+
+sal_uInt8 getTypeCode(uno::Type const & _aType)
+{
+ switch (_aType.getTypeClass())
+ {
+ case uno::TypeClass_ANY:
+ case uno::TypeClass_VOID:
+ return Type::value_any;
+
+ case uno::TypeClass_STRING:
+ return Type::value_string;
+
+ case uno::TypeClass_BOOLEAN:
+ return Type::value_boolean;
+
+ case uno::TypeClass_SHORT:
+ return Type::value_short;
+
+ case uno::TypeClass_LONG:
+ return Type::value_int;
+
+ case uno::TypeClass_HYPER:
+ return Type::value_long;
+
+ case uno::TypeClass_FLOAT:
+ case uno::TypeClass_DOUBLE:
+ return Type::value_double;
+
+ case uno::TypeClass_SEQUENCE:
+ {
+ uno::Type aElementType = getSequenceElementType(_aType);
+
+ if (aElementType.getTypeClass() == uno::TypeClass_BYTE)
+ return Type::value_binary;
+
+ OSL_ASSERT(aElementType != _aType); // would cause infinite recursion
+ sal_uInt8 aElementTC = getTypeCode(aElementType);
+
+ OSL_ASSERT(Type::value_invalid & Type::flag_sequence); // ensure check works for invalid types
+
+ if (aElementTC & Type::flag_sequence) // no sequence of sequence
+ return Type::value_invalid;
+
+ return sal_uInt8( aElementTC | Type::flag_sequence );
+ }
+ default:
+ return Type::value_invalid;
+ }
+}
+//-----------------------------------------------------------------------------
+
+static uno::Type getUnoSimpleType( sal_uInt8 _aSimpleType)
+{
+ OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
+
+ switch (_aSimpleType)
+ {
+ case Type::value_string:
+ return ::getCppuType(static_cast<rtl::OUString const *>(0));
+
+ case Type::value_boolean:
+ return ::getBooleanCppuType();
+
+ case Type::value_short:
+ return ::getCppuType(static_cast<sal_Int16 const *>(0));
+
+ case Type::value_int:
+ return ::getCppuType(static_cast<sal_Int32 const *>(0));
+
+ case Type::value_long:
+ return ::getCppuType(static_cast<sal_Int64 const *>(0));
+
+ case Type::value_double:
+ return ::getCppuType(static_cast<double const *>(0));
+
+ case Type::value_binary:
+ return ::getCppuType(static_cast<uno::Sequence<sal_Int8> const *>(0));
+
+ case Type::value_any:
+ //return ::getVoidCppuType();
+ return ::getCppuType(static_cast<uno::Any const *>(0));
+
+ default:
+ OSL_ENSURE( false, "Invalid type code" );
+ return ::getVoidCppuType();
+ }
+}
+//-----------------------------------------------------------------------------
+
+static uno::Type getUnoSequenceType( sal_uInt8 _aSimpleType)
+{
+ OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
+
+ switch (_aSimpleType)
+ {
+ case Type::value_string:
+ return ::getCppuType(static_cast<uno::Sequence<rtl::OUString> const *>(0));
+
+ case Type::value_boolean:
+ return ::getCppuType(static_cast<uno::Sequence<sal_Bool> const *>(0));
+
+ case Type::value_short:
+ return ::getCppuType(static_cast<uno::Sequence<sal_Int16> const *>(0));
+
+ case Type::value_int:
+ return ::getCppuType(static_cast<uno::Sequence<sal_Int32> const *>(0));
+
+ case Type::value_long:
+ return ::getCppuType(static_cast<uno::Sequence<sal_Int64> const *>(0));
+
+ case Type::value_double:
+ return ::getCppuType(static_cast<uno::Sequence<double> const *>(0));
+
+ case Type::value_binary:
+ return ::getCppuType(static_cast<uno::Sequence<uno::Sequence<sal_Int8> > const *>(0));
+
+ case Type::value_any: // results from value_invalid
+ default:
+ OSL_ENSURE( false, "Invalid type code" );
+ return ::getVoidCppuType();
+ }
+}
+//-----------------------------------------------------------------------------
+
+uno::Type getUnoType( sal_uInt8 _aType)
+{
+ OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" );
+
+ if (_aType & Type::flag_sequence)
+ return getUnoSequenceType( sal_uInt8(_aType & Type::mask_basetype));
+
+ else
+ return getUnoSimpleType(_aType);
+}
+//-----------------------------------------------------------------------------
+
+static
+AnyData allocSimpleData(sal_uInt8 _aSimpleType, uno::Any const & _aAny)
+{
+ OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
+
+ AnyData aResult;
+ aResult.data = 0;
+
+ switch (_aSimpleType)
+ {
+ case Type::value_string:
+ {
+ rtl::OUString sValue;
+ OSL_VERIFY(_aAny >>= sValue );
+ aResult.stringValue = acquireString(sValue);
+ }
+ break;
+
+ case Type::value_boolean:
+ OSL_VERIFY(_aAny >>= aResult.boolValue );
+ break;
+
+ case Type::value_short:
+ OSL_VERIFY(_aAny >>= aResult.shortValue);
+ break;
+
+ case Type::value_int:
+ OSL_VERIFY(_aAny >>= aResult.intValue);
+ break;
+
+ case Type::value_long:
+ {
+ sal_Int64 nValue = 0;
+ OSL_VERIFY(_aAny >>= nValue);
+
+ aResult.longValue = new sal_Int64( nValue );
+ }
+ break;
+
+ case Type::value_double:
+ {
+ double dValue = 0;
+ OSL_VERIFY(_aAny >>= dValue);
+
+ aResult.doubleValue = new double( dValue );
+ }
+ break;
+
+ case Type::value_binary:
+ {
+ uno::Sequence<sal_Int8> aValue;
+ OSL_VERIFY(_aAny >>= aValue);
+ aResult.binaryValue = allocBinary(aValue);
+ }
+ break;
+
+ case Type::value_any:
+ OSL_ENSURE( false, "Trying to allocate void value" );
+ break;
+
+ default:
+ OSL_ENSURE( false, "Invalid type code" );
+ break;
+ }
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+template <class E>
+inline
+sal_Sequence const * extractSequenceData(uno::Sequence< E > & _rSeq, uno::Any const & _aAny)
+{
+ if (_aAny >>= _rSeq)
+ {
+ return _rSeq.get();
+ }
+
+ else
+ {
+ OSL_ENSURE(false, "Could not extract sequence from Any");
+ return NULL;
+ }
+}
+//-----------------------------------------------------------------------------
+
+static
+AnyData allocSequenceData(sal_uInt8 _aSimpleType, uno::Any const & _aAny)
+{
+ OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
+
+ sal_uInt8 * aSequence = 0;
+
+ switch (_aSimpleType)
+ {
+ case Type::value_string:
+ {
+ uno::Sequence<rtl::OUString> aSeqValue;
+ if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
+ aSequence = allocSequence(_aSimpleType,pData);
+ }
+ break;
+
+ case Type::value_boolean:
+ {
+ uno::Sequence<sal_Bool> aSeqValue;
+ if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
+ aSequence = allocSequence(_aSimpleType,pData);
+ }
+ break;
+
+ case Type::value_short:
+ {
+ uno::Sequence<sal_Int16> aSeqValue;
+ if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
+ aSequence = allocSequence(_aSimpleType,pData);
+ }
+ break;
+
+ case Type::value_int:
+ {
+ uno::Sequence<sal_Int32> aSeqValue;
+ if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
+ aSequence = allocSequence(_aSimpleType,pData);
+ }
+ break;
+
+ case Type::value_long:
+ {
+ uno::Sequence<sal_Int64> aSeqValue;
+ if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
+ aSequence = allocSequence(_aSimpleType,pData);
+ }
+ break;
+
+ case Type::value_double:
+ {
+ uno::Sequence<double> aSeqValue;
+ if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
+ aSequence = allocSequence(_aSimpleType,pData);
+ }
+ break;
+
+ case Type::value_binary:
+ {
+ uno::Sequence<uno::Sequence<sal_Int8> > aSeqValue;
+ if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny))
+ aSequence = allocSequence(_aSimpleType,pData);
+ }
+ break;
+
+ case Type::value_any: // results from value_invalid
+ default:
+ OSL_ENSURE( false, "Invalid type code" );
+ break;
+ }
+
+ AnyData aResult;
+ aResult.sequenceValue = aSequence;
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+AnyData allocData(sal_uInt8 _aType, uno::Any const & _aAny)
+{
+ OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" );
+ OSL_ENSURE( _aType == getTypeCode(_aAny.getValueType()), "Type code does not match value" );
+
+ if (_aType & Type::flag_sequence)
+ return allocSequenceData(sal_uInt8( _aType & Type::mask_basetype),_aAny);
+ else
+ return allocSimpleData(_aType,_aAny);
+}
+//-----------------------------------------------------------------------------
+
+static
+void freeSimpleData(sal_uInt8 _aSimpleType, AnyData const & _aData)
+{
+ OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
+
+ switch (_aSimpleType)
+ {
+ case Type::value_string:
+ rtl_uString_release(_aData.stringValue);
+ break;
+
+ case Type::value_boolean:
+ case Type::value_short:
+ case Type::value_int:
+ // nothing to do
+ break;
+
+ // free memory for oversized values
+ case Type::value_long:
+ delete _aData.longValue;
+ break;
+
+ case Type::value_double:
+ delete _aData.doubleValue;
+ break;
+
+ case Type::value_binary:
+ freeBinary(_aData.binaryValue);
+ break;
+
+ case Type::value_any:
+ // nothing to do for void value
+ break;
+
+ default:
+ OSL_ENSURE( false, "Invalid type code" );
+ break;
+ }
+}
+//-----------------------------------------------------------------------------
+
+void freeData(sal_uInt8 _aType, AnyData _aData)
+{
+ OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" );
+
+ if (_aType & Type::flag_sequence)
+ freeSequence(sal_uInt8(_aType & Type::mask_basetype),_aData.sequenceValue);
+
+ else
+ freeSimpleData(_aType,_aData);
+}
+//-----------------------------------------------------------------------------
+
+static
+uno::Any readSimpleData(sal_uInt8 _aSimpleType, AnyData const & _aData)
+{
+ OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" );
+
+ switch (_aSimpleType)
+ {
+ case Type::value_string:
+ {
+ rtl::OUString sValue = rtl::OUString(_aData.stringValue);
+ return uno::makeAny(sValue);
+ }
+
+ case Type::value_boolean:
+ return uno::makeAny( _aData.boolValue );
+
+ case Type::value_short:
+ return uno::makeAny( _aData.shortValue );
+
+ case Type::value_int:
+ return uno::makeAny( _aData.intValue );
+
+ case Type::value_long:
+ return uno::makeAny( *_aData.longValue );
+
+ case Type::value_double:
+ return uno::makeAny( *_aData.doubleValue );
+
+ case Type::value_binary:
+ {
+ uno::Sequence<sal_Int8> aValue = readBinary( _aData.binaryValue );
+ return uno::makeAny( aValue );
+ }
+
+ case Type::value_any: // void value
+ return uno::Any();
+
+ default:
+ OSL_ENSURE( false, "Invalid type code" );
+ return uno::Any();
+ }
+}
+//-----------------------------------------------------------------------------
+
+uno::Any readData(sal_uInt8 _aType, AnyData _aData)
+{
+ OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" );
+
+ if (_aType & Type::flag_sequence)
+ return readAnySequence(sal_uInt8(_aType & Type::mask_basetype),_aData.sequenceValue);
+
+ else
+ return readSimpleData(_aType,_aData);
+}
+
+//-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/data/makefile.mk b/configmgr/source/data/makefile.mk
new file mode 100644
index 000000000000..5745979c1bed
--- /dev/null
+++ b/configmgr/source/data/makefile.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source$/inc
+PRJNAME=configmgr
+TARGET=data
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+.INCLUDE : $(PRJ)$/version.mk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/anydata.obj \
+ $(SLO)$/sequence.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/data/sequence.cxx b/configmgr/source/data/sequence.cxx
new file mode 100644
index 000000000000..b0721d646586
--- /dev/null
+++ b/configmgr/source/data/sequence.cxx
@@ -0,0 +1,493 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sequence.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "datalock.hxx"
+#include "sequence.hxx"
+#include "flags.hxx"
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+
+#ifndef INCLUDED_STRING_H
+#include <string.h>
+#define INCLUDED_STRING_H
+#endif
+
+#include "utility.hxx"
+
+#ifndef SIMPLE_REFERENCE_FAST
+# include <stdio.h>
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace sharable
+ {
+//-----------------------------------------------------------------------------
+ namespace Type = data::Type;
+ namespace uno = ::com::sun::star::uno;
+//-----------------------------------------------------------------------------
+static
+sal_uInt32 implGetElementSize(sal_uInt8 _aElementType)
+{
+ OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype));
+ switch (_aElementType)
+ {
+
+ case Type::value_boolean: return sizeof(sal_Bool);
+
+ case Type::value_short: return sizeof(sal_Int16);
+
+ case Type::value_int: return sizeof(sal_Int32);
+
+ case Type::value_long: return sizeof(sal_Int64);
+
+ case Type::value_double: return sizeof(double);
+
+ case Type::value_string: return sizeof(rtl_uString *);
+
+ case Type::value_binary: return sizeof(sal_uInt8 *);
+
+ case Type::value_any: // results from value_invalid
+ default:
+ OSL_ENSURE( false, "Invalid type code" );
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+static inline
+sal_uInt32 implGetHeaderSize(sal_uInt32 _nElemSize)
+{
+ // pad header to elem size, if larger (for safe alignment)
+ OSL_ASSERT(_nElemSize > sizeof(sal_Int32) || sizeof(sal_Int32) % _nElemSize== 0);
+ return _nElemSize > sizeof(sal_Int32) ? _nElemSize : sizeof(sal_Int32);
+}
+
+//-----------------------------------------------------------------------------
+static
+inline
+sal_Int32& implGetSize(sal_uInt8 * _aSeq)
+{
+ return * (sal_Int32 *) _aSeq;
+}
+
+//-----------------------------------------------------------------------------
+static
+sal_uInt8 * implSeqAlloc(sal_Int32 _nElements, sal_uInt32 _nElemSize)
+{
+ sal_uInt32 nTotalSize = implGetHeaderSize(_nElemSize) + _nElements * _nElemSize;
+
+ sal_uInt8 * aResult = (sal_uInt8 *) (new sal_uInt8[nTotalSize]);
+
+ implGetSize(aResult) = _nElements;
+
+ return aResult;
+}
+
+//-----------------------------------------------------------------------------
+
+static
+void allocSeqData(sal_uInt8 *_pDestAddr,
+ sal_uInt8 _aElementType,
+ sal_Int32 _nElements, sal_uInt32 _nElementSize,
+ void const * _pSourceData)
+{
+ OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype));
+ OSL_ASSERT(_nElementSize == implGetElementSize(_aElementType));
+ switch (_aElementType)
+ {
+ case Type::value_boolean:
+ case Type::value_short:
+ case Type::value_int:
+ case Type::value_long:
+ case Type::value_double:
+ ::memcpy(_pDestAddr,_pSourceData,_nElements * _nElementSize);
+ break;
+
+ case Type::value_string:
+ {
+ OSL_ASSERT(_nElementSize == sizeof(rtl_uString *));
+
+ rtl::OUString const * pSource = static_cast<rtl::OUString const *>(_pSourceData);
+
+ while (--_nElements >= 0)
+ {
+ rtl_uString * aElement = acquireString(*pSource);
+
+ rtl_uString * * pDest = reinterpret_cast<rtl_uString **>(_pDestAddr);
+ *pDest = aElement;
+
+ ++pSource;
+ _pDestAddr += sizeof *pDest;
+ }
+ }
+ break;
+
+ case Type::value_binary:
+ {
+ OSL_ASSERT(_nElementSize == sizeof(sal_uInt8 *));
+
+ uno::Sequence< sal_Int8 > const * pSource = static_cast<uno::Sequence< sal_Int8 > const *>(_pSourceData);
+
+ while (--_nElements >= 0)
+ {
+ sal_uInt8 * aElement = allocBinary(*pSource);
+
+ sal_uInt8 * * pDest = (sal_uInt8 * *) _pDestAddr;
+ *pDest = aElement;
+
+ ++pSource;
+ _pDestAddr += sizeof *pDest;
+ }
+ }
+ break;
+
+ case Type::value_any:
+ default:
+ OSL_ENSURE(false, "Invalid element type");
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------
+sal_uInt8 * allocSequence(sal_uInt8 _aElementType, ::sal_Sequence const * _pSeqData)
+{
+ OSL_ENSURE(_aElementType == (_aElementType & Type::mask_valuetype), "Invalid type code");
+
+ OSL_ENSURE(_pSeqData, "ERROR: Trying to allocate from a NULL sequence");
+ if (_pSeqData == NULL) return 0;
+
+ // OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype));
+ _aElementType &= Type::mask_basetype;
+
+ sal_uInt32 const nElementSize = implGetElementSize(_aElementType);
+ sal_Int32 const nElements = _pSeqData->nElements;
+
+ sal_uInt8 * aResult = implSeqAlloc(nElements,nElementSize);
+
+ if (aResult)
+ allocSeqData( aResult + implGetHeaderSize(nElementSize),
+ _aElementType, nElements, nElementSize,
+ _pSeqData->elements);
+
+ return aResult;
+}
+
+//-----------------------------------------------------------------------------
+sal_uInt8 * allocBinary(uno::Sequence<sal_Int8> const & _aBinaryValue)
+{
+ sal_uInt32 const nElementSize = 1;
+ sal_Int32 const nLength = _aBinaryValue.getLength();
+
+ sal_uInt8 * aResult = implSeqAlloc(nLength,nElementSize);
+
+ if (aResult)
+ {
+ sal_uInt8 *pElementBaseAddr = aResult + implGetHeaderSize(nElementSize);
+ ::memcpy(pElementBaseAddr, _aBinaryValue.getConstArray(), nLength);
+ }
+
+ return aResult;
+}
+
+//-----------------------------------------------------------------------------
+static
+void freeSeqData(sal_uInt8 *_pDataAddr,
+ sal_uInt8 _aElementType, sal_Int32 _nElements)
+{
+ OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype));
+
+ switch (_aElementType)
+ {
+ case Type::value_boolean:
+ case Type::value_short:
+ case Type::value_int:
+ case Type::value_long:
+ case Type::value_double:
+ // nothing to do
+ break;
+
+ case Type::value_string:
+ {
+ rtl_uString * * pElements = reinterpret_cast<rtl_uString **>( _pDataAddr );
+
+ for (sal_Int32 i = 0; i < _nElements; ++i)
+ {
+ rtl_uString_release(pElements[i]);
+ }
+ }
+ break;
+
+ case Type::value_binary:
+ {
+ sal_uInt8 * * pElements = reinterpret_cast<sal_uInt8 **>( _pDataAddr );
+
+ for (sal_Int32 i = 0; i < _nElements; ++i)
+ {
+ freeBinary(pElements[i]);
+ }
+ }
+ break;
+
+ case Type::value_any:
+ default:
+ OSL_ENSURE(false, "Invalid element type");
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void freeSequence(sal_uInt8 _aElementType, sal_uInt8 * _aSeq)
+{
+ OSL_ENSURE(_aElementType == (_aElementType & Type::mask_valuetype), "Invalid type code");
+
+ OSL_ENSURE(_aSeq, "ERROR: Trying to free a NULL sequence");
+ if (_aSeq == 0) return;
+
+ // OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype));
+ _aElementType &= Type::mask_basetype;
+
+ sal_uInt32 nHeaderSize = implGetHeaderSize( implGetElementSize( _aElementType ) );
+
+ freeSeqData(_aSeq + nHeaderSize, _aElementType, implGetSize(_aSeq));
+
+ delete[] (sal_uInt8 *)_aSeq;
+}
+
+//-----------------------------------------------------------------------------
+void freeBinary(sal_uInt8 * _aSeq)
+{
+ OSL_ENSURE(_aSeq, "ERROR: Trying to free a NULL sequence");
+ if (_aSeq == 0) return;
+
+ delete[] (sal_uInt8 *)_aSeq;
+}
+
+//-----------------------------------------------------------------------------
+
+static inline
+sal_Sequence * implCreateSequence(void const * _pElements, sal_uInt8 _aElementType, sal_Int32 _nElements)
+{
+ uno::Type aUnoType = getUnoType( sal_uInt8( _aElementType | Type::flag_sequence ));
+
+ sal_Sequence * pResult = NULL;
+ ::uno_type_sequence_construct( &pResult, aUnoType.getTypeLibType(),
+ const_cast< void * >( _pElements ),
+ _nElements, NULL );
+
+ OSL_ASSERT(pResult->nRefCount == 1);
+ return pResult;
+}
+
+//-----------------------------------------------------------------------------
+static
+sal_Sequence * readSeqData(sal_uInt8 *_pDataAddr, sal_uInt8 _aElementType, sal_Int32 _nElements)
+{
+ OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype));
+
+ void const * pElementData = (void const *)_pDataAddr;
+ switch (_aElementType)
+ {
+ case Type::value_boolean:
+ case Type::value_short:
+ case Type::value_int:
+ case Type::value_long:
+ case Type::value_double:
+ return implCreateSequence(pElementData,_aElementType,_nElements);
+
+ case Type::value_string:
+ {
+ uno::Sequence<rtl::OUString> aResult(_nElements);
+ rtl::OUString * pResult = aResult.getArray();
+
+ rtl_uString * const * pElements = static_cast<rtl_uString * const *>( pElementData );
+
+ for (sal_Int32 i = 0; i < _nElements; ++i)
+ {
+ pResult[i] = rtl::OUString(pElements[i]);
+ }
+
+ sal_Sequence * pRet = aResult.get();
+ ++pRet->nRefCount;
+ return pRet;
+ }
+
+ case Type::value_binary:
+ {
+ uno::Sequence< uno::Sequence< sal_Int8 > > aResult(_nElements);
+ uno::Sequence< sal_Int8 > * pResult = aResult.getArray();
+
+ sal_uInt8 * const * pElements = static_cast<sal_uInt8 * const *>( pElementData );
+
+ for (sal_Int32 i = 0; i < _nElements; ++i)
+ {
+ pResult[i] = readBinary(pElements[i]);
+ }
+
+ sal_Sequence * pRet = aResult.get();
+ ++pRet->nRefCount;
+ return pRet;
+ }
+
+ case Type::value_any:
+ default:
+ OSL_ENSURE(false, "Invalid element type");
+ return NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+::sal_Sequence * readSequence(sal_uInt8 _aElementType, sal_uInt8 * _aSeq)
+{
+ OSL_ENSURE(_aElementType == (_aElementType & Type::mask_valuetype), "Invalid type code");
+
+ OSL_ENSURE(_aSeq, "ERROR: Trying to read from a NULL sequence");
+ if (_aSeq == 0) return NULL;
+
+ // OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype));
+ _aElementType &= Type::mask_basetype;
+
+ sal_uInt32 nHeaderSize = implGetHeaderSize( implGetElementSize( _aElementType ) );
+
+ return readSeqData(_aSeq + nHeaderSize, _aElementType, implGetSize(_aSeq));
+}
+
+//-----------------------------------------------------------------------------
+uno::Any readAnySequence(sal_uInt8 _aElementType, sal_uInt8 * _aSeq)
+{
+ sal_Sequence * pRawSequence = readSequence(_aElementType, _aSeq);
+
+ uno::Any aResult;
+
+ if (pRawSequence != NULL)
+ switch (_aElementType & Type::mask_basetype)
+ {
+ case Type::value_string:
+ {
+ uno::Sequence< rtl::OUString > aSequence(pRawSequence,SAL_NO_ACQUIRE);
+ aResult <<=aSequence ;
+ }
+ break;
+
+ case Type::value_boolean:
+ {
+ uno::Sequence< sal_Bool > aSequence(pRawSequence,SAL_NO_ACQUIRE);
+ aResult <<=aSequence ;
+ }
+ break;
+
+ case Type::value_short:
+ {
+ uno::Sequence< sal_Int16 > aSequence(pRawSequence,SAL_NO_ACQUIRE);
+ aResult <<=aSequence ;
+ }
+ break;
+
+ case Type::value_int:
+ {
+ uno::Sequence< sal_Int32 > aSequence(pRawSequence,SAL_NO_ACQUIRE);
+ aResult <<=aSequence ;
+ }
+ break;
+
+ case Type::value_long:
+ {
+ uno::Sequence< sal_Int64 > aSequence(pRawSequence,SAL_NO_ACQUIRE);
+ aResult <<=aSequence ;
+ }
+ break;
+
+ case Type::value_double:
+ {
+ uno::Sequence< double > aSequence(pRawSequence,SAL_NO_ACQUIRE);
+ aResult <<=aSequence ;
+ }
+ break;
+
+ case Type::value_binary:
+ {
+ uno::Sequence< uno::Sequence< sal_Int8 > > aSequence(pRawSequence,SAL_NO_ACQUIRE);
+ aResult <<=aSequence ;
+ }
+ break;
+
+ case Type::value_any: // from value_invalid ??
+ default:
+ OSL_ENSURE( false, "Invalid type code" );
+ break;
+ }
+
+ OSL_ASSERT(!aResult.hasValue() || aResult.getValueType() == getUnoType(sal_uInt8(_aElementType | Type::flag_sequence)));
+
+ return aResult;
+}
+
+//-----------------------------------------------------------------------------
+uno::Sequence<sal_Int8> readBinary(sal_uInt8 * _aSeq)
+{
+ OSL_ENSURE(_aSeq, "ERROR: Trying to read from a NULL sequence");
+ if (_aSeq == 0) return uno::Sequence<sal_Int8>();
+
+ return uno::Sequence< sal_Int8 >((const sal_Int8 *)(_aSeq + implGetHeaderSize(1)),
+ implGetSize(_aSeq));
+}
+
+//-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+} // namespace
+
+// Remaining 'global' mutex bits - should move to api2 ...
+namespace configmgr
+{
+ osl::Mutex UnoApiLock::aCoreLock;
+ volatile oslInterlockedCount UnoApiLock::nHeld = 0;
+
+ UnoApiLockReleaser::UnoApiLockReleaser()
+ {
+ mnCount = UnoApiLock::nHeld;
+ for (oslInterlockedCount i = 0; i < mnCount; i++)
+ UnoApiLock::release();
+ }
+
+ UnoApiLockReleaser::~UnoApiLockReleaser()
+ {
+ for (oslInterlockedCount i = 0; i < mnCount; i++)
+ UnoApiLock::acquire();
+ }
+} // namespace configmgr
diff --git a/configmgr/source/inc/anydata.hxx b/configmgr/source/inc/anydata.hxx
new file mode 100644
index 000000000000..9e53a320e464
--- /dev/null
+++ b/configmgr/source/inc/anydata.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: anydata.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_SHARABLE_ANYDATA_HXX
+#define INCLUDED_SHARABLE_ANYDATA_HXX
+
+#include "rtl/ustring.h"
+#include "sal/types.h"
+
+//-----------------------------------------------------------------------------
+namespace com { namespace sun { namespace star { namespace uno {
+ class Any;
+ class Type;
+} } } }
+//-----------------------------------------------------------------------------
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+
+ namespace sharable
+ {
+ //-----------------------------------------------------------------------------
+
+ union AnyData
+ {
+ sal_Bool boolValue;
+ sal_Int16 shortValue;
+ sal_Int32 intValue;
+ sal_Int64 *longValue;
+ double *doubleValue;
+ sal_uInt8 * binaryValue; // points to counted sal_(u)Int8 []
+ rtl_uString * stringValue; // points to counted sal_Unicode []
+ sal_uInt8 * sequenceValue; // points to counted AnyData [] (or SomeType [] ?)
+ void *data; // used to initialize to 0
+ };
+
+ //-----------------------------------------------------------------------------
+
+ sal_uInt8 getTypeCode(::com::sun::star::uno::Type const & _aType);
+ ::com::sun::star::uno::Type getUnoType( sal_uInt8 _aType);
+
+ AnyData allocData(sal_uInt8 _aType, ::com::sun::star::uno::Any const & _aAny);
+ void freeData(sal_uInt8 _aType, AnyData _aData);
+ ::com::sun::star::uno::Any readData(sal_uInt8 _aType, AnyData _aData);
+
+ //-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
+
+#endif // INCLUDED_SHARABLE_ANYDATA_HXX
+
diff --git a/configmgr/source/inc/anynoderef.hxx b/configmgr/source/inc/anynoderef.hxx
new file mode 100644
index 000000000000..f1ce1ec1a154
--- /dev/null
+++ b/configmgr/source/inc/anynoderef.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: anynoderef.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGANYNODE_HXX_
+#define CONFIGMGR_CONFIGANYNODE_HXX_
+
+#include "noderef.hxx"
+
+namespace configmgr
+{
+ namespace configapi { class Factory; }
+ namespace node { struct Attributes; }
+
+ namespace configuration
+ {
+ //-------------------------------------------------------------------------
+ class NodeRef;
+ class ValueRef;
+ class AnyNodeRef;
+ class NodeID;
+ class Tree;
+ //-------------------------------------------------------------------------
+
+ /// represents any node in some tree
+ class AnyNodeRef
+ {
+ public:
+ /// constructs an empty (invalid) node
+ AnyNodeRef();
+
+ AnyNodeRef(unsigned int nParentPos, unsigned int m_nDepth);
+ AnyNodeRef(rtl::OUString const& aName, unsigned int nParentPos);
+
+ /// converts an inner node
+ explicit AnyNodeRef(NodeRef const& aInnerNode);
+ /// converts a value node
+ explicit AnyNodeRef(ValueRef const& aValueNode);
+
+ /// copy a node (with reference semantics)
+ AnyNodeRef(AnyNodeRef const& rOther);
+ /// copy a node (with reference semantics)
+ AnyNodeRef& operator=(AnyNodeRef const& rOther);
+
+ void swap(AnyNodeRef& rOther);
+
+ ~AnyNodeRef();
+
+ /// checks, if this represents an existing node
+ inline bool isValid() const;
+
+ /// checks if this a node (rather than a value only)
+ bool isNode() const;
+
+ /// converts this, if it is a value
+ ValueRef toValue() const;
+
+ /// converts this, if it is a inner node
+ NodeRef toNode() const;
+
+#if OSL_DEBUG_LEVEL > 0
+ bool checkValidState() const;
+#endif
+
+ rtl::OUString m_sNodeName;
+ unsigned int m_nUsedPos;
+ unsigned int m_nDepth;
+ };
+ //-------------------------------------------------------------------------
+
+ /** checks whether there is an immediate child of <var>aNode</var> (which is in <var>aTree</var>)
+ specified by <var>aName</var>
+
+ @return
+ <TRUE/> if the child node exists
+ <FALSE/> otherwise
+ */
+ inline
+ bool hasChildOrElement(rtl::Reference< Tree > const& aTree, AnyNodeRef const& aNode, rtl::OUString const& aName)
+ { return aNode.isNode() && hasChildOrElement(aTree,aNode.toNode(),aName); }
+
+ /** tries to find the immediate child of <var>aNode</var> (which is in <var>aTree</var>)
+ specified by <var>aName</var>
+ <p> On return <var>aNode</var> is modified to refer to the node found and
+ <var>aTree</var> will then refer to the tree that node is in.
+ <p/>
+
+ @return The requested child node, if it exists
+ (then <var>aTree</var> refers to the tree containing the desired node),
+ */
+ AnyNodeRef getChildOrElement(rtl::Reference< Tree > & aTree, NodeRef const& aParentNode, rtl::OUString const& aName);
+
+ /** tries to find the descendant of <var>aNode</var> specified by <var>aPath</var> within <var>aTree</var>
+ <p> This function follows the given path stepwise, until a requested node is missing in the tree.</p>
+ <p> On return <var>aNode</var> is modified to refer to the last inner node found
+ and <var>aTree</var> will be unchanged (except for deprecated usage).
+ <p/>
+ <p> Also, <var>aPath</var> is modified to contain the unresolved part of the original path.
+ </p>
+
+ @return the requested node, if the path could be resolved completely
+ (so <var>aNode</var> refers to the desired node or its parent,
+ and <var>aPath</var> is empty)<BR/>
+ an invalid node otherwise
+ */
+ AnyNodeRef getLocalDescendant(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, RelativePath const& aPath);
+
+ /** tries to find the descendant of <var>aNode</var> (which is in <var>aTree</var>) specified by <var>aPath</var>
+ <p> This function follows the given path stepwise, until a requested node is missing in the tree.</p>
+ <p> On return <var>aNode</var> is modified to refer to the last inner node found and
+ <var>aTree</var> will then refer to the tree that node is in.
+ <p/>
+ <p> Also, <var>aPath</var> is modified to contain the unresolved part of the original path.
+ </p>
+
+ @return the requested node, if the path could be resolved completely
+ (so <var>aNode</var> and <var>aTree</var> refer to the desired node or its parent,
+ and <var>aPath</var> is empty)<BR/>
+ an invalid node otherwise
+ */
+ AnyNodeRef getDeepDescendant(rtl::Reference< Tree > & aTree, NodeRef& aNode, RelativePath& aPath);
+
+ //-------------------------------------------------------------------------
+ inline bool AnyNodeRef::isValid() const
+ {
+ OSL_ASSERT( m_nUsedPos == 0 || checkValidState() );
+ return m_nUsedPos != 0;
+ }
+
+ //-------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGANYNODE_HXX_
diff --git a/configmgr/source/inc/anypair.hxx b/configmgr/source/inc/anypair.hxx
new file mode 100644
index 000000000000..0ce5c9628179
--- /dev/null
+++ b/configmgr/source/inc/anypair.hxx
@@ -0,0 +1,118 @@
+#ifndef CFGMGR_ANYPAIR_HXX
+#define CFGMGR_ANYPAIR_HXX
+
+#include <uno/any2.h>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+namespace configmgr
+{
+ namespace css = com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+
+ //==========================================================================
+ //= flags for handling the state of an Anypair
+ //==========================================================================
+ enum {
+ cfgmgr_SELECT_FIRST = 0x01,
+ cfgmgr_SELECT_SECOND = 0x02,
+ cfgmgr_SELECT_BOTH = cfgmgr_SELECT_FIRST | cfgmgr_SELECT_SECOND
+ };
+
+ //==========================================================================
+ //= data structure for descriptive data for an AnyPair
+ //==========================================================================
+ struct cfgmgr_AnyPair_Desc
+ {
+ typelib_TypeDescriptionReference * pType;
+ sal_uInt8 nState;
+ };
+
+ inline bool cfgmgr_AnyPair_isNull(cfgmgr_AnyPair_Desc const* _pDesc, sal_uInt8 nSelect)
+ { return (_pDesc->nState & nSelect) == 0; }
+
+ inline bool cfgmgr_AnyPair_isEmpty(cfgmgr_AnyPair_Desc const* _pDesc)
+ { return (typelib_TypeClass_VOID == _pDesc->pType->eTypeClass); }
+
+ //==========================================================================
+ //= cfgmgr_AnyPair Basic (POD) data structure for a nullable pair of Anys
+ //==========================================================================
+
+ struct cfgmgr_AnyPair
+ {
+ cfgmgr_AnyPair_Desc desc;
+ const void * first;
+ const void * second;
+ };
+
+// -----------------------------------------------------------------------------
+ //==========================================================================
+ //= AnyPair
+ //==========================================================================
+ // this AnyPair holds 2 nullable Any's which have to have the same type.
+
+ class AnyPair
+ {
+ cfgmgr_AnyPair m_aAnyPair;
+
+ public:
+ enum SelectMember
+ {
+ SELECT_FIRST = cfgmgr_SELECT_FIRST,
+ SELECT_SECOND = cfgmgr_SELECT_SECOND,
+ SELECT_BOTH = cfgmgr_SELECT_BOTH
+ };
+ public:
+ explicit AnyPair(uno::Type const& _aType); // one Type, any's are null
+ explicit AnyPair(uno::Any const& _aAny, SelectMember _select); // one selected any
+
+ explicit AnyPair(uno::Any const& _aAny, uno::Any const& _aAny2) SAL_THROW((lang::IllegalArgumentException));
+
+ // copy
+ AnyPair(AnyPair const& _aAny);
+ AnyPair& operator=(AnyPair const& _aAny);
+
+ // d-tor
+ ~AnyPair();
+
+ // elementwise setters
+ sal_Bool setFirst(uno::Any const& _aAny);
+ sal_Bool setSecond(uno::Any const& _aAny);
+
+ // clear data (but not type)
+ void clear(SelectMember _select = SELECT_BOTH);
+
+
+ // checking state and availablity of values
+ bool isEmpty() const { return cfgmgr_AnyPair_isEmpty(&m_aAnyPair.desc); }
+
+ bool isNull () const { return ! hasValue(); }
+
+ bool hasValue(SelectMember _select = SELECT_BOTH) const
+ {
+ return !cfgmgr_AnyPair_isNull(&m_aAnyPair.desc, (sal_uInt8)_select);
+ }
+ bool hasFirst() const
+ {
+ return hasValue(SELECT_FIRST);
+ }
+ bool hasSecond() const
+ {
+ return hasValue(SELECT_SECOND);
+ }
+
+ // elementwise getters
+ uno::Type getValueType() const;
+ uno::Any getFirst() const;
+ uno::Any getSecond() const;
+ uno::Any getValue(SelectMember _select) const;
+
+ };
+
+
+
+
+} // namespace
+
+#endif
diff --git a/configmgr/source/inc/apitypes.hxx b/configmgr/source/inc/apitypes.hxx
new file mode 100644
index 000000000000..22a5bc5152db
--- /dev/null
+++ b/configmgr/source/inc/apitypes.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: apitypes.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_APITYPES_HXX_
+#define CONFIGMGR_API_APITYPES_HXX_
+
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <rtl/ustring.hxx>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif // INCLUDED_VECTOR
+
+namespace configmgr
+{
+ namespace configapi
+ {
+ namespace uno = ::com::sun::star::uno;
+
+ inline
+ uno::Type getAnyType( )
+ {
+ return ::getCppuType( static_cast< uno::Any const * >(0) );
+ }
+
+ inline
+ uno::Type getUnoInterfaceType( )
+ {
+ return ::getCppuType( static_cast< uno::Reference< uno::XInterface > const * >(0) );
+ }
+
+ template <typename Interface>
+ inline
+ uno::Type getReferenceType( Interface const* )
+ {
+ return ::getCppuType( static_cast< uno::Reference<Interface> const * >(0) );
+ }
+
+ template <typename Type>
+ inline
+ uno::Type getSequenceType( Type const* )
+ {
+ return ::getCppuType( static_cast< uno::Sequence<Type> const * >(0) );
+ }
+
+ template <typename T>
+ inline
+ uno::Sequence<T> makeSequence(::std::vector<T> const& aVector)
+ {
+ if (aVector.empty())
+ return uno::Sequence<T>();
+ return uno::Sequence<T>(&aVector[0],aVector.size());
+ }
+ }
+
+}
+
+#endif // CONFIGMGR_API_APITYPES_HXX_
+
+
diff --git a/configmgr/source/inc/attributes.hxx b/configmgr/source/inc/attributes.hxx
new file mode 100644
index 000000000000..b42785b35cb5
--- /dev/null
+++ b/configmgr/source/inc/attributes.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: attributes.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGURATION_ATTRIBUTES_HXX_
+#define CONFIGMGR_CONFIGURATION_ATTRIBUTES_HXX_
+namespace configmgr
+{
+ namespace node
+ {
+ enum State
+ {
+ isDefault, isToDefault = isDefault,
+ isMerged, isModification = isMerged,
+ isReplaced, isReplacement = isReplaced,
+ isAdded, isAddition = isAdded
+ };
+ enum Access
+ {
+ accessNull = 0,
+ accessWritable = 0,
+ accessFinal = 1,
+ accessReadonly = 2,
+ accessReadonlyAndFinal = 3
+ };
+ inline Access makeAccess(bool readonly, bool final)
+ { return Access( (readonly ? accessReadonly : accessNull) | (final ? accessFinal : accessNull) ); }
+ inline bool isAccessReadonly(Access access)
+ { return (access & accessReadonly) != 0; }
+ inline bool isAccessFinal(Access access)
+ { return (access & accessFinal) != 0; }
+
+ inline bool existsInDefault(State eState) { return eState <= isReplaced;}
+ inline bool isReplacedForUser(State eState) { return eState >= isReplaced;}
+
+ /// holds attributes a node in the schema
+ struct Attributes
+ {
+ Attributes()
+ : state_(node::isMerged)
+ , bReadonly(false)
+ , bFinalized(false)
+ , bNullable(true)
+ , bLocalized(false)
+ , bMandatory(false)
+ , bRemovable(false)
+ {}
+
+ State state() const { return State(0x03 & state_); }
+ void setState(State _state) { this->state_ = _state; }
+
+ bool isWritable() const { return!bReadonly; }
+ bool isReadonly() const { return bReadonly; }
+ bool isFinalized() const { return bFinalized; }
+
+ void markReadonly() { bReadonly = true; }
+
+ Access getAccess() const
+ { return makeAccess(bReadonly,bFinalized); }
+
+ void setAccess(bool _bReadonly, bool _bFinalized)
+ { bReadonly = _bReadonly; bFinalized = _bFinalized; }
+
+ void setAccess(Access _aAccessLevel)
+ { setAccess( isAccessReadonly(_aAccessLevel), isAccessFinal(_aAccessLevel) ); }
+
+ bool isNullable() const { return bNullable; }
+ void setNullable (bool _bNullable) {bNullable = _bNullable; }
+
+ bool isLocalized() const { return bLocalized; }
+ void setLocalized (bool _bLocalized) {bLocalized = _bLocalized; }
+
+ bool isMandatory() const { return bMandatory; }
+ bool isRemovable() const { return bRemovable; }
+
+ void markMandatory() { bMandatory = true; }
+ void markRemovable() { bRemovable = true; }
+
+ void setRemovability(bool _bRemovable, bool _bMandatory)
+ { bRemovable = _bRemovable; bMandatory = _bMandatory; }
+
+ bool isDefault() const { return this->state() == node::isDefault;}
+ bool existsInDefault() const { return node::existsInDefault(this->state());}
+ bool isReplacedForUser() const { return node::isReplacedForUser(this->state());}
+
+ void markAsDefault(bool _bDefault = true)
+ {
+ if (_bDefault)
+ this->state_ = node::isDefault;
+ else if (this->isDefault())
+ this->state_ = node::isMerged;
+ }
+
+ private:
+ State state_ : 2; // merged/replaced/default state
+
+ bool bReadonly : 1; // write-protected, if true
+ bool bFinalized : 1; // can not be overridden - write protected when merged upwards
+
+ bool bNullable : 1; // values only: can be NULL
+ bool bLocalized : 1; // values only: value may depend on locale
+
+ bool bMandatory : 1; // cannot be removed/replaced in subsequent layers
+ bool bRemovable : 1; // can be removed
+ };
+
+ }
+}
+
+#endif
diff --git a/configmgr/source/inc/autoobject.hxx b/configmgr/source/inc/autoobject.hxx
new file mode 100644
index 000000000000..91ca2fee0c98
--- /dev/null
+++ b/configmgr/source/inc/autoobject.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: autoobject.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_AUTOOBJECT_HXX
+#define CONFIGMGR_AUTOOBJECT_HXX
+
+#include "sal/config.h"
+
+#include "boost/utility.hpp"
+
+#include "utility.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ template < class Object >
+ class AutoObject: private boost::noncopyable
+ {
+ public:
+ AutoObject() : m_pObject(NULL) {}
+ AutoObject(Object * _obj) : m_pObject(_obj) {}
+ ~AutoObject() { delete m_pObject; }
+
+ bool is() const;
+ Object * get() const;
+ Object * getOrCreate();
+ private:
+ Object * internalCreate();
+ private:
+ Object * m_pObject;
+ };
+//-----------------------------------------------------------------------------
+
+ template < class Object >
+ inline
+ Object * AutoObject<Object>::get() const
+ {
+ return m_pObject;
+ }
+//-----------------------------------------------------------------------------
+
+ template < class Object >
+ inline
+ bool AutoObject<Object>::is() const
+ {
+ return get() != NULL;
+ }
+//-----------------------------------------------------------------------------
+
+ template < class Object >
+ Object * AutoObject<Object>::getOrCreate()
+ {
+ Object * p = get();
+ return p ? p : internalCreate();
+ }
+//-----------------------------------------------------------------------------
+
+ template < class Object >
+ Object * AutoObject<Object>::internalCreate()
+ {
+ if (m_pObject == NULL)
+ m_pObject = new Object();
+ return m_pObject;
+
+ }
+//-----------------------------------------------------------------------------
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/inc/autoreferencemap.hxx b/configmgr/source/inc/autoreferencemap.hxx
new file mode 100644
index 000000000000..ea12095400b5
--- /dev/null
+++ b/configmgr/source/inc/autoreferencemap.hxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: autoreferencemap.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_AUTOREFERENCEMAP_HXX
+#define CONFIGMGR_AUTOREFERENCEMAP_HXX
+
+#include <rtl/ref.hxx>
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+
+ template < class Key, class Object, class KeyCompare = std::less<Key> >
+ class AutoReferenceMap
+ {
+ public:
+ typedef std::map<Key,rtl::Reference<Object>,KeyCompare> Map;
+ public:
+ AutoReferenceMap() {}
+ ~AutoReferenceMap() {}
+
+ Map copy() const
+ {
+ return m_aMap;
+ }
+ void swap(Map & _rOtherData)
+ {
+ m_aMap.swap( _rOtherData );
+ }
+ void swap(AutoReferenceMap & _rOther)
+ {
+ this->swap( _rOther.m_aMap );
+ }
+
+
+ bool has(Key const & _aKey) const;
+ rtl::Reference<Object> get(Key const & _aKey) const;
+
+ rtl::Reference<Object> insert(Key const & _aKey, rtl::Reference<Object> const & _anEntry);
+ rtl::Reference<Object> remove(Key const & _aKey);
+
+ private:
+ rtl::Reference<Object> internalGet(Key const & _aKey) const
+ {
+ typename Map::const_iterator it = m_aMap.find(_aKey);
+
+ return it != m_aMap.end() ? it->second : rtl::Reference<Object>();
+ }
+
+ rtl::Reference<Object> internalAdd(Key const & _aKey, rtl::Reference<Object> const & _aNewRef)
+ {
+ return m_aMap[_aKey] = _aNewRef;
+ }
+
+ void internalDrop(Key const & _aKey)
+ {
+ m_aMap.erase(_aKey);
+ }
+ private:
+ Map m_aMap;
+ };
+//-----------------------------------------------------------------------------
+
+ template < class Key, class Object, class KeyCompare >
+ bool AutoReferenceMap<Key,Object,KeyCompare>::has(Key const & _aKey) const
+ {
+ return internalGet(_aKey).is();
+ }
+//-----------------------------------------------------------------------------
+
+ template < class Key, class Object, class KeyCompare >
+ rtl::Reference<Object> AutoReferenceMap<Key,Object,KeyCompare>::get(Key const & _aKey) const
+ {
+ return internalGet(_aKey);
+ }
+//-----------------------------------------------------------------------------
+
+ template < class Key, class Object, class KeyCompare >
+ rtl::Reference<Object> AutoReferenceMap<Key,Object,KeyCompare>::insert(Key const & _aKey, rtl::Reference<Object> const & _anEntry)
+ {
+ rtl::Reference<Object> aRef = internalAdd(_aKey,_anEntry);
+ return aRef;
+
+ }
+//-----------------------------------------------------------------------------
+
+ template < class Key, class Object, class KeyCompare >
+ rtl::Reference<Object> AutoReferenceMap<Key,Object,KeyCompare>::remove(Key const & _aKey)
+ {
+ rtl::Reference<Object> aRef = internalGet(_aKey);
+ internalDrop(_aKey);
+ return aRef;
+ }
+//-----------------------------------------------------------------------------
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/inc/backendfactory.hxx b/configmgr/source/inc/backendfactory.hxx
new file mode 100644
index 000000000000..b977b6745895
--- /dev/null
+++ b/configmgr/source/inc/backendfactory.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backendfactory.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKENDFACTORY_HXX_
+#define CONFIGMGR_BACKENDFACTORY_HXX_
+
+#include <rtl/ref.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace backend
+ {
+//-----------------------------------------------------------------------------
+
+ struct IMergedDataProvider;
+//-----------------------------------------------------------------------------
+ class BackendFactory
+ {
+ public:
+ rtl::Reference<IMergedDataProvider> createBackend();
+
+ com::sun::star::uno::Reference< com::sun::star::configuration::backend::XBackend > getUnoBackend();
+
+ static BackendFactory instance(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & _xCtx);
+
+ private:
+ explicit
+ BackendFactory(com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & _xCtx)
+ : m_xCtx(_xCtx)
+ {}
+
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xCtx;
+ };
+//-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
+
+#endif
+
diff --git a/configmgr/source/inc/bootstrap.hxx b/configmgr/source/inc/bootstrap.hxx
new file mode 100644
index 000000000000..5ffb2cb97756
--- /dev/null
+++ b/configmgr/source/inc/bootstrap.hxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bootstrap.hxx,v $
+ * $Revision: 1.29 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BOOTSTRAP_HXX_
+#define CONFIGMGR_BOOTSTRAP_HXX_
+
+#include "bootstrapcontext.hxx"
+
+// ---------------------------------------------------------------------------------------
+#define CONFIGMGR_INIFILE SAL_CONFIGFILE("configmgr")
+#define BOOTSTRAP_ITEM_INIFILE "CFG_INIFILE"
+// ---------------------------------------------------------------------------------------
+// standard settings
+#define SETTING_UNOSERVICE "BackendService"
+#define SETTING_UNOWRAPPER "BackendWrapper"
+#define SETTING_OFFLINE "Offline"
+#define SETTING_LOCALE_NEW "Locale"
+#define SETTING_ASYNC_NEW "EnableAsync"
+#define SETTING_INIFILE "Inifile"
+
+// Prefixes
+#define CONTEXT_MODULE_PREFIX_ "/modules/com.sun.star.configuration/"
+#define CONTEXT_SECTION_BOOTSTRAP_ "bootstrap/"
+#define CONTEXT_ITEM_PREFIX_ CONTEXT_MODULE_PREFIX_ CONTEXT_SECTION_BOOTSTRAP_
+#define BOOTSTRAP_ITEM_PREFIX_ "CFG_"
+
+// special internal context values
+#define CONTEXT_SECTION_INTERNAL_ "factory/"
+#define CONTEXT_INTERNAL_PREFIX_ CONTEXT_MODULE_PREFIX_ CONTEXT_SECTION_INTERNAL_
+#define CONTEXT_ITEM_ADMINFLAG CONTEXT_INTERNAL_PREFIX_"isAdminConfiguration"
+#define CONTEXT_ITEM_BOOTSTRAP_ERROR CONTEXT_INTERNAL_PREFIX_"theBootstrapError"
+
+#define CONTEXT_ITEM_IS_WRAPPER_CONTEXT CONTEXT_INTERNAL_PREFIX_"isWrapperContext"
+#define CONTEXT_ITEM_IS_BOOTSTRAP_CONTEXT CONTEXT_INTERNAL_PREFIX_"isBootstrapContext"
+
+// ---------------------------------------------------------------------------------------
+#define A_DefaultProviderSingletonName "com.sun.star.configuration.theDefaultProvider"
+#define K_DefaultBackendSingletonName "com.sun.star.configuration.backend.theDefaultBackend"
+#define A_BootstrapContextSingletonName "com.sun.star.configuration.bootstrap.theBootstrapContext"
+// -------------------------------------------------------------------------
+#define A_DefaultProviderServiceAndImplName "com.sun.star.configuration.DefaultProvider"
+#define K_DefaultBackendServiceAndImplName "com.sun.star.configuration.backend.DefaultBackend"
+// ---------------------------------------------------------------------------------------
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------------
+
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace beans = ::com::sun::star::beans;
+ // -----------------------------------------------------------------------------------
+
+ /** Customized ComponentContext for configuration bootstrap data and runtime arguments
+ */
+ class BootstrapContext : public ComponentContext
+ {
+ // creation and destruction
+ private:
+ friend uno::Reference<uno::XInterface> SAL_CALL
+ instantiateBootstrapContext( uno::Reference< uno::XComponentContext > const& xContext );
+
+ // constructor
+ BootstrapContext(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ // two-phase construct
+ void initialize();
+
+ protected:
+ using ComponentContext::initialize;
+
+ public:
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (uno::RuntimeException) ;
+ virtual sal_Bool SAL_CALL supportsService(
+ const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException) ;
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void) throw (uno::RuntimeException) ;
+
+
+ /** Constructs a Context based on the given arguments and context.
+ @param _xContext
+ The base context of this component context.
+
+ @param _aArguments
+ The arguments used to create this component context.
+ */
+ static uno::Reference< uno::XComponentContext > createWrapper(uno::Reference< uno::XComponentContext > const & _xContext, uno::Sequence < beans::NamedValue > const & _aOverrides);
+
+ /** Checks, if the given context is a wrapper.
+ @param _xContext
+ The context that is checked.
+ */
+ static sal_Bool isWrapper(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ /** Retrieves the BootstrapContext for the given non-bootstrap context.
+ @param _xContext
+ The context from which the bootstrap context should be retrieved.
+
+ */
+ static uno::Reference< uno::XComponentContext > get(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ /// Destroys this BootstrapContext
+ ~BootstrapContext();
+
+ // gets the INI that should be used for bootstrap data by default
+ static rtl::OUString getDefaultConfigurationBootstrapURL();
+
+ // interface implementations
+ public:
+ // XComponentContext
+ /** Retrieves a value from this context.
+
+ @param name
+ The name of the value to retrieve.
+ A prefix of "com.sun.star.configuration.bootstrap." is stripped/ignored
+
+ @returns
+ The requested value, or <VOID/> if the value is not found.
+ */
+ virtual uno::Any SAL_CALL
+ getValueByName( const rtl::OUString& name )
+ throw (uno::RuntimeException);
+
+ public: // used by ArgumentHelper
+ static rtl::OUString makeContextName (rtl::OUString const & _aShortName);
+
+ private:
+ static rtl::OUString makeBootstrapName(rtl::OUString const & _aLongName);
+ uno::Any makeBootstrapException();
+ };
+// -----------------------------------------------------------------------------
+ class ContextReader
+ {
+ public:
+ explicit
+ ContextReader(uno::Reference< uno::XComponentContext > const & context);
+
+ // the underlying contexts
+ sal_Bool hasBootstrapContext() const { return m_fullcontext.is(); }
+ uno::Reference< uno::XComponentContext > const & getBootstrapContext() const { return m_fullcontext; }
+ uno::Reference< uno::XComponentContext > const & getBaseContext() const { return m_basecontext; }
+ uno::Reference< uno::XComponentContext > const & getBestContext() const { return m_fullcontext.is() ? m_fullcontext : m_basecontext; }
+
+ uno::Reference< lang::XMultiComponentFactory > getServiceManager() const;
+
+ /** Checks, if the given context has the given 'admin' flag setting..
+ @param _xContext
+ The context that is checked.
+ */
+ static bool testAdminService(uno::Reference< uno::XComponentContext > const & context, bool bAdmin);
+
+ // general settings
+ sal_Bool isUnoBackend() const;
+
+ sal_Bool hasUnoBackendService() const;
+ sal_Bool hasUnoBackendWrapper() const;
+
+ sal_Bool hasLocale() const;
+ sal_Bool hasAsyncSetting() const;
+ sal_Bool hasOfflineSetting() const;
+
+ rtl::OUString getUnoBackendService() const;
+ rtl::OUString getUnoBackendWrapper() const;
+
+ rtl::OUString getLocale() const;
+ sal_Bool getAsyncSetting() const;
+ sal_Bool getOfflineSetting() const;
+
+ // internal settings - should only ever be in configmgr::BootstrapContext instances
+ // get a special setting
+ sal_Bool isAdminService() const;
+
+ // access to error diagnostics
+ sal_Bool isBootstrapValid() const;
+ uno::Any getBootstrapError() const;
+ private:
+ sal_Bool hasSetting(rtl::OUString const & _aSetting) const;
+ sal_Bool getBoolSetting(rtl::OUString const & _aSetting, sal_Bool bValue) const;
+ rtl::OUString getStringSetting(rtl::OUString const & _aSetting, rtl::OUString aValue) const;
+ uno::Any getSetting(rtl::OUString const & _aSetting) const;
+ private:
+ uno::Reference< uno::XComponentContext > m_basecontext;
+ uno::Reference< uno::XComponentContext > m_fullcontext;
+ };
+ //------------------------------------------------------------------------
+
+ class ArgumentHelper
+ {
+ public:
+ explicit
+ ArgumentHelper(uno::Reference< uno::XComponentContext > const & context)
+ : m_context(context)
+ , m_bHasBackendArguments(false)
+ {}
+
+ bool hasBackendArguments() const { return m_bHasBackendArguments; }
+ bool checkBackendArgument(beans::NamedValue const & aAdjustedValue);
+
+ bool filterAndAdjustArgument(beans::NamedValue & rValue);
+
+ static
+ bool extractArgument(beans::NamedValue & rValue, uno::Any const & aArgument);
+
+ static beans::NamedValue makeAdminServiceOverride(sal_Bool bAdmin);
+ private:
+ uno::Reference< uno::XComponentContext > m_context; // context used to strip identical arguments
+ bool m_bHasBackendArguments;
+ };
+// -----------------------------------------------------------------------------------
+
+}
+
+#endif // CONFIGMGR_BOOTSTRAP_HXX_
+
+
diff --git a/configmgr/source/inc/bootstrapcontext.hxx b/configmgr/source/inc/bootstrapcontext.hxx
new file mode 100644
index 000000000000..5b3f7906ecb9
--- /dev/null
+++ b/configmgr/source/inc/bootstrapcontext.hxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bootstrapcontext.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BOOTSTRAPCONTEXT_HXX_
+#define CONFIGMGR_BOOTSTRAPCONTEXT_HXX_
+
+#include <cppuhelper/compbase3.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/bootstrap.h>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+} } } }
+
+// -----------------------------------------------------------------------------
+#define SINGLETON_ "/singletons/"
+#define SINGLETON( NAME ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SINGLETON_ NAME ) )
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace beans = ::com::sun::star::beans;
+// -----------------------------------------------------------------------------
+ /** Base class for customized ComponentContext using bootstrap data and overrides
+ */
+ class ComponentContext : public cppu::WeakComponentImplHelper3 < uno::XComponentContext, uno::XCurrentContext, lang::XServiceInfo >
+ {
+ // creation and destruction
+ public:
+ /** Constructs a ComponentContext based on the given overrides and context.
+ Initially no bootstrap data will be used.
+
+ @param _xContext
+ The base context of this component context.
+ Values from here take precedence over values from bootstrap data.
+
+ @param _aOverrides
+ The overrides used to create this component context.
+ These values take precedence over values from the base context or bootstrap data.
+ */
+ explicit
+ ComponentContext(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ /// Destroys this BootstrapContext
+ ~ComponentContext();
+
+ // gets the INI in use for getting bootstrap data
+ rtl::OUString getBootstrapURL() const;
+
+ static sal_Bool isPassthrough(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ static beans::NamedValue makePassthroughMarker(sal_Bool bPassthrough = true);
+ // interface implementations
+ public:
+
+ // XComponentContext only
+ virtual uno::Reference< lang::XMultiComponentFactory > SAL_CALL
+ getServiceManager( )
+ throw (uno::RuntimeException);
+
+ protected:
+ // ComponentHelper
+ virtual void SAL_CALL disposing();
+
+ protected:
+ // two phase construct - also initialized the bootstrap data
+ void initialize(const rtl::OUString& _aBootstrapURL);
+
+ bool lookupInContext ( uno::Any & _rValue, const rtl::OUString& _aName ) const;
+ bool lookupInBootstrap( uno::Any & _rValue, const rtl::OUString& _aName ) const;
+
+ uno::Reference< uno::XComponentContext > const & basecontext() const { return m_xContext; }
+
+ private:
+ /// The context that most requests are delegated to
+ uno::Reference< uno::XComponentContext > m_xContext;
+ /// The bootstrap data consulted as fallback
+ rtlBootstrapHandle m_hBootstrapData;
+ /// The service manager associated with this context
+ uno::Reference< lang::XMultiComponentFactory > m_xServiceManager;
+ };
+// -----------------------------------------------------------------------------
+
+ class UnoContextTunnel
+ {
+ public:
+ UnoContextTunnel();
+ ~UnoContextTunnel();
+ void tunnel(uno::Reference< uno::XComponentContext > const & xContext);
+ void passthru(uno::Reference< uno::XComponentContext > const & xContext);
+ uno::Any recoverFailure(bool bRaise); // true, if there is a failure
+
+ static uno::Reference< uno::XComponentContext > recoverContext(uno::Reference< uno::XComponentContext > const & xFallback = uno::Reference< uno::XComponentContext >());
+ static bool tunnelFailure(uno::Any const & aException, bool bRaise = false);
+ private:
+ uno::Reference< uno::XCurrentContext > m_xOldContext;
+ uno::Reference< lang::XUnoTunnel > m_xActiveTunnel;
+ class Tunnel;
+ };
+// -----------------------------------------------------------------------------
+
+ class DisposingForwarder : public cppu::WeakImplHelper1< lang::XEventListener >
+ {
+ uno::Reference< lang::XComponent > m_xTarget;
+
+ DisposingForwarder( uno::Reference< lang::XComponent > const & xTarget ) SAL_THROW( () )
+ : m_xTarget( xTarget )
+ { OSL_ASSERT( m_xTarget.is() ); }
+
+ virtual void SAL_CALL disposing( lang::EventObject const & rSource )
+ throw (uno::RuntimeException);
+ public:
+ // listens at source for disposing, then disposes target
+ static inline void forward(
+ uno::Reference< lang::XComponent > const & xSource,
+ uno::Reference< lang::XComponent > const & xTarget )
+ SAL_THROW( (uno::RuntimeException) );
+ };
+//__________________________________________________________________________________________________
+ inline void DisposingForwarder::forward(
+ uno::Reference< lang::XComponent > const & xSource,
+ uno::Reference< lang::XComponent > const & xTarget )
+ SAL_THROW( (uno::RuntimeException) )
+ {
+ if (xSource.is())
+ {
+ xSource->addEventListener( new DisposingForwarder( xTarget ) );
+ }
+ }
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
+
diff --git a/configmgr/source/inc/bufferedfile.hxx b/configmgr/source/inc/bufferedfile.hxx
new file mode 100644
index 000000000000..937355c3ba74
--- /dev/null
+++ b/configmgr/source/inc/bufferedfile.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bufferedfile.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BUFFEREDFILE_HXX
+#define CONFIGMGR_BUFFEREDFILE_HXX
+
+#include "utility.hxx"
+#include <boost/utility.hpp>
+#include <osl/file.hxx>
+#include <com/sun/star/io/IOException.hpp>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace configmgr
+{
+
+ namespace io = com::sun::star::io;
+
+ class BufferedOutputFile: private boost::noncopyable, public osl::FileBase
+ {
+ osl::File * m_pFile;
+ std::vector<sal_uInt8> m_buffer;
+ public:
+ BufferedOutputFile( rtl::OUString const& aFileURL, sal_uInt32 nBufferSizeHint = 0 );
+ ~BufferedOutputFile ();
+
+ RC open( sal_uInt32 uFlags );
+ RC close();
+
+ //RC getPos( sal_uInt64& uPos )
+ RC write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten);
+
+ // as opposed to osl::File, this method is not const here
+ RC sync();
+ };
+} // namespace
+
+#endif
diff --git a/configmgr/source/inc/builddata.hxx b/configmgr/source/inc/builddata.hxx
new file mode 100644
index 000000000000..a82e64084b5a
--- /dev/null
+++ b/configmgr/source/inc/builddata.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: builddata.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BUILDDATA_HXX
+#define CONFIGMGR_BUILDDATA_HXX
+
+#include "treefragment.hxx"
+#ifndef INCLUDED_MEMORY
+#define INCLUDED_MEMORY
+#include <memory>
+#endif
+//-----------------------------------------------------------------------------
+namespace rtl { class OUString; }
+//-----------------------------------------------------------------------------
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ class INode;
+ class ISubtree;
+ class ValueNode;
+//-----------------------------------------------------------------------------
+ namespace sharable { struct TreeFragment; }
+ namespace data
+ {
+//-----------------------------------------------------------------------------
+ sharable::TreeFragment * buildTree(sharable::TreeFragment * tree);
+//-----------------------------------------------------------------------------
+ sharable::TreeFragment * buildTree(rtl::OUString const & _aTreeName, INode const& _aNode, bool _bWithDefaults);
+//-----------------------------------------------------------------------------
+ sharable::TreeFragment * buildElementTree(INode const& _aNode, rtl::OUString const & _aTypeName, bool _bWithDefaults);
+//-----------------------------------------------------------------------------
+ void mergeDefaults(sharable::TreeFragment * _aBaseAddress, INode const& _aDefaultNode);
+//-----------------------------------------------------------------------------
+ void destroyTree(sharable::TreeFragment * _aBaseAddress);
+//-----------------------------------------------------------------------------
+ std::auto_ptr<INode> convertTree(sharable::TreeFragment * tree, bool _bUseTreeName);
+//-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+} // namespace configmgr
+//-----------------------------------------------------------------------------
+
+#endif // CONFIGMGR_BUILDDATA_HXX
+
+
diff --git a/configmgr/source/inc/cachefactory.hxx b/configmgr/source/inc/cachefactory.hxx
new file mode 100644
index 000000000000..5d9eabbd8dc1
--- /dev/null
+++ b/configmgr/source/inc/cachefactory.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachefactory.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CACHEFACTORY_HXX_
+#define CONFIGMGR_CACHEFACTORY_HXX_
+
+#include <rtl/ref.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ class TreeManager;
+//-----------------------------------------------------------------------------
+ struct CacheFactory
+ {
+ rtl::Reference<TreeManager>
+ createCacheManager(::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & _xContext);
+
+ static CacheFactory & instance();
+ };
+//-----------------------------------------------------------------------------
+}
+
+
+#endif // CONFIGMGR_CACHEFACTORY_HXX_
+
diff --git a/configmgr/source/inc/change.hxx b/configmgr/source/inc/change.hxx
new file mode 100644
index 000000000000..29d226d86715
--- /dev/null
+++ b/configmgr/source/inc/change.hxx
@@ -0,0 +1,507 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: change.hxx,v $
+ * $Revision: 1.28 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CHANGE_HXX
+#define CONFIGMGR_CHANGE_HXX
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#pragma warning(disable : 4350) // behavior change: 'member1' called instead of 'member2'
+#endif
+
+#include "valuenode.hxx"
+#include "treesegment.hxx"
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+
+ namespace uno = com::sun::star::uno;
+
+ class Change;
+ class SubtreeChange;
+ class ValueChange;
+ class AddNode;
+ class RemoveNode;
+
+
+ //==========================================================================
+ //= ChangeTreeAction
+ //==========================================================================
+ struct ChangeTreeAction
+ {
+ virtual void handle(ValueChange const& aValueNode) = 0;
+ virtual void handle(AddNode const& aAddNode) = 0;
+ virtual void handle(RemoveNode const& aRemoveNode) = 0;
+ virtual void handle(SubtreeChange const& aSubtree) = 0;
+
+ void applyToChange(Change const& aChange);
+ void applyToChildren(SubtreeChange const& aSubtree);
+ protected:
+ virtual ~ChangeTreeAction() {}
+ };
+
+ struct ChangeTreeModification
+ {
+ virtual void handle(ValueChange& aValueNode) = 0;
+ virtual void handle(AddNode& aAddNode) = 0;
+ virtual void handle(RemoveNode& aRemoveNode) = 0;
+ virtual void handle(SubtreeChange& aSubtree) = 0;
+
+ void applyToChange(Change& aChange);
+ void applyToChildren(SubtreeChange& aSubtree);
+ protected:
+ virtual ~ChangeTreeModification() {}
+ };
+
+ //==========================================================================
+ //= Change
+ //==========================================================================
+ class Change
+ {
+ protected:
+ rtl::OUString m_aName;
+ bool m_bIsToDefault;
+
+ void swap(Change& aOther);
+
+ public:
+ explicit
+ Change(rtl::OUString const& _rName, bool _bToDefault)
+ : m_aName(_rName)
+ , m_bIsToDefault(_bToDefault)
+ {}
+
+ virtual ~Change() {}
+
+ rtl::OUString getNodeName() const { return m_aName; }
+ void setNodeName(const rtl::OUString &aName) {m_aName = aName;}
+
+ bool isToDefault() const { return m_bIsToDefault; }
+
+ Change* getSubChange(rtl::OUString const& _rName) { return doGetChild(_rName); }
+ Change const* getSubChange(rtl::OUString const& _rName) const { return doGetChild(_rName); }
+
+ virtual void dispatch(ChangeTreeAction& anAction) const = 0;
+ virtual void dispatch(ChangeTreeModification& anAction) = 0;
+
+ virtual std::auto_ptr<Change> clone() const = 0;
+
+ private:
+ virtual Change* doGetChild(rtl::OUString const& ) const { return 0; }
+ };
+
+ //==========================================================================
+ //= ValueChange
+ //==========================================================================
+ class ValueChange : public Change
+ {
+ public:
+ struct SetToDefault {};
+ enum Mode { wasDefault, changeValue, setToDefault, changeDefault };
+
+ private:
+ uno::Type m_aValueType;
+ uno::Any m_aValue;
+ uno::Any m_aOldValue;
+ node::Attributes m_aAttributes;
+ Mode m_eMode;
+ public:
+ ValueChange(
+ rtl::OUString const& _rName,
+ const node::Attributes& _rAttributes,
+ Mode aMode,
+ uno::Any const & aNewValue,
+ uno::Any const & aOldValue = uno::Any());
+
+ virtual std::auto_ptr<Change> clone() const;
+
+ bool isChange() const;
+
+ uno::Type getValueType() const { return m_aValueType; }
+
+ uno::Any getNewValue() const { return m_aValue; }
+ uno::Any getOldValue() const { return m_aOldValue; }
+
+ void setNewValue(const uno::Any& _rNewVal);
+ void setNewValue(const uno::Any& _rNewVal, Mode aMode)
+ { setNewValue(_rNewVal); m_eMode = aMode;}
+
+ bool isReplacedValue() const {return m_aAttributes.isReplacedForUser();}
+ bool isLocalizedValue() const {return m_aAttributes.isLocalized();}
+
+ Mode getMode() const { return m_eMode; }
+
+ const node::Attributes& getAttributes() const {return m_aAttributes;}
+
+ void applyChangeNoRecover(ValueNode& aNode) const;
+
+ virtual void dispatch(ChangeTreeAction& anAction) const { anAction.handle(*this); }
+ virtual void dispatch(ChangeTreeModification& anAction) { anAction.handle(*this); }
+
+ friend class ApplyValueChange;
+ };
+
+ //==========================================================================
+ //= AddNode
+ //==========================================================================
+ class AddNode : public Change
+ {
+ rtl::Reference< data::TreeSegment > m_aOwnNewNode;
+ rtl::Reference< data::TreeSegment > m_aOwnOldNode;
+ sharable::TreeFragment * m_aInsertedTree;
+ bool m_bReplacing;
+
+ private:
+ void operator=(AddNode const&); // not implemented
+
+ // needed for clone()
+ AddNode(AddNode const&);
+ public:
+ AddNode(rtl::Reference< data::TreeSegment > const & _aAddedTree, rtl::OUString const& _rName, bool _bToDefault);
+ ~AddNode();
+
+ virtual std::auto_ptr<Change> clone() const;
+
+ /// marks this as not merely adding a node but replacing another
+ void setReplacing() { m_bReplacing = true; }
+ /// is this not merely adding a node but replacing another ?
+ bool isReplacing() const { return m_bReplacing; }
+
+ /// has this been applied and inserted
+ bool wasInserted() const { return m_aInsertedTree != NULL; }
+
+ /** returns the node this change represents, even if this node does not own the new Node object any more.
+ This is somewhat dangerous if the node referenced by this object dies before the object itself does.<BR>
+ In this case all calls to this method will return nonsense. This case can be detected by testing
+ whether <method>getAddedNode</method> returns NULL.
+ */
+ sharable::TreeFragment * getInsertedTree() const { return m_aInsertedTree; }
+
+ /** returns the node this change represents; The Node object is owned by this change until
+ <method>releaseAddedNode</method> is called.<BR>
+ After ownership is lost this method returns NULL.
+ */
+ sharable::TreeFragment const * getNewTreeData() const { return m_aOwnNewNode.is() ? m_aOwnNewNode->fragment : 0; }
+
+ /** returns the node the change represents. .
+ */
+ rtl::Reference< data::TreeSegment > getNewTree() const { return m_aOwnNewNode; }
+
+ /** returns the node the change represents, and releases ownership of it. This means that
+ afterwards <method>getAddedNode</method> will return NULL. This change object keeps a reference
+ to the node though which can be retrieved using <method>getAddedNode_unsafe</method>.
+ */
+ void clearNewTree() { m_aOwnNewNode.clear(); }
+
+ /** .
+ */
+ void setInsertedAddress(sharable::TreeFragment * const & _aInsertedAddress);
+
+
+ /** returns the node this change replaces, ihe Node object is owned by this change.
+ After ownership is lost this method returns NULL.
+ */
+ sharable::TreeFragment const * getReplacedTreeData() const { return m_aOwnOldNode.is() ? m_aOwnOldNode->fragment : 0; }
+
+ /** returns the node the change replaces.
+ */
+ rtl::Reference< data::TreeSegment > getReplacedTree() const { return m_aOwnOldNode; }
+
+ /** forgets about the node the change replaces
+ */
+ void clearReplacedTree() { m_aOwnOldNode.clear(); }
+
+ void takeReplacedTree(rtl::Reference< data::TreeSegment > const& _aTree);
+
+ virtual void dispatch(ChangeTreeAction& anAction) const { anAction.handle(*this); }
+ virtual void dispatch(ChangeTreeModification& anAction) { anAction.handle(*this); }
+ };
+
+ //==========================================================================
+ //= RemoveNode
+ //==========================================================================
+ class RemoveNode : public Change
+ {
+ protected:
+ rtl::Reference< data::TreeSegment > m_aOwnOldNode;
+ bool m_bIsToDefault;
+
+ private:
+ RemoveNode& operator=(const RemoveNode&); // not implemented
+ // needed for clone()
+ RemoveNode(const RemoveNode&);
+ public:
+ explicit
+ RemoveNode(rtl::OUString const& _rName, bool _bToDefault);
+ ~RemoveNode();
+
+ virtual std::auto_ptr<Change> clone() const;
+
+ virtual void dispatch(ChangeTreeAction& anAction) const { anAction.handle(*this); }
+ virtual void dispatch(ChangeTreeModification& anAction) { anAction.handle(*this); }
+
+ /** returns the node this change removes, ihe Node object is owned by this change.
+ After ownership is lost this method returns NULL.
+ */
+ sharable::TreeFragment const * getRemovedTreeData() const { return m_aOwnOldNode.is() ? m_aOwnOldNode->fragment : 0; }
+ /** returns the node the change removes.
+ */
+ rtl::Reference< data::TreeSegment > getRemovedTree() const { return m_aOwnOldNode; }
+
+ /** forgets about the node the change removes, returning the previous setting with ownership
+ */
+ void clearRemovedTree() { m_aOwnOldNode.clear(); }
+
+ void takeRemovedTree(rtl::Reference< data::TreeSegment > const & _aTree);
+ };
+
+ //==========================================================================
+ //= SubtreeChange
+ //==========================================================================
+ class SubtreeChange : public Change
+ {
+ protected:
+ typedef ::std::map< ::rtl::OUString,Change* > Children;
+ Children m_aChanges;
+ ::rtl::OUString m_sTemplateName; /// path of the template for child instantiation
+ ::rtl::OUString m_sTemplateModule; /// module of the template for child instantiation
+ node::Attributes m_aAttributes;
+
+ // don't create copy ops automatically
+ SubtreeChange(const SubtreeChange&);
+ void operator=(SubtreeChange&);
+
+ using Change::swap;
+
+ public:
+ class ChildIterator;
+ ChildIterator begin() const throw();
+ ChildIterator end() const throw();
+
+ class MutatingChildIterator;
+ MutatingChildIterator begin_changes() throw();
+ MutatingChildIterator end_changes() throw();
+
+ friend class MutatingChildIterator;
+ public:
+ SubtreeChange(const rtl::OUString& _rName,
+ const node::Attributes& _rAttr,
+ bool _bToDefault = false)
+ : Change(_rName,_bToDefault)
+ , m_aAttributes(_rAttr)
+ {
+ m_aAttributes.markAsDefault(_bToDefault);
+ }
+
+ SubtreeChange(const rtl::OUString& _rName,
+ const rtl::OUString& _rTemplateName,
+ const rtl::OUString& _rTemplateModule,
+ const node::Attributes& _rAttr,
+ bool _bToDefault = false)
+ : Change(_rName,_bToDefault)
+ , m_sTemplateName(_rTemplateName)
+ , m_sTemplateModule(_rTemplateModule)
+ , m_aAttributes(_rAttr)
+ {
+ m_aAttributes.markAsDefault(_bToDefault);
+ }
+
+ SubtreeChange(const ISubtree& _rTree, bool _bToDefault = false)
+ : Change(_rTree.getName(),_bToDefault)
+ , m_sTemplateName(_rTree.getElementTemplateName())
+ , m_sTemplateModule(_rTree.getElementTemplateModule())
+ , m_aAttributes(_rTree.getAttributes())
+ {
+ m_aAttributes.markAsDefault(_bToDefault);
+ }
+
+ SubtreeChange(const SubtreeChange& _rChange, treeop::NoChildCopy)
+ : Change(_rChange)
+ , m_sTemplateName(_rChange.getElementTemplateName())
+ , m_sTemplateModule(_rChange.getElementTemplateModule())
+ , m_aAttributes(_rChange.getAttributes())
+ {}
+
+ ~SubtreeChange();
+
+ SubtreeChange(const SubtreeChange&, treeop::DeepChildCopy);
+
+ virtual std::auto_ptr<Change> clone() const;
+
+ void swap(SubtreeChange& aOther);
+
+ bool isReplacedNode() const { return m_aAttributes.isReplacedForUser(); }
+ bool isLocalizedContainer() const { return m_aAttributes.isLocalized(); }
+
+ const node::Attributes& getAttributes() const {return m_aAttributes;}
+
+ bool isSetNodeChange() const { return m_sTemplateName.getLength() != 0; }
+
+ rtl::OUString getElementTemplateName() const { return m_sTemplateName; }
+ rtl::OUString getElementTemplateModule() const { return m_sTemplateModule; }
+
+ void setElementTemplate(const rtl::OUString& _rName, const rtl::OUString& _rModule)
+ { m_sTemplateName = _rName; m_sTemplateModule = _rModule; }
+
+ sal_Int32 size() const { return m_aChanges.size(); }
+ uno::Sequence< rtl::OUString > elementNames() const;
+
+ void addChange(std::auto_ptr<Change> aChange);
+ ::std::auto_ptr<Change> removeChange(rtl::OUString const& _rName);
+
+ Change* getChange(rtl::OUString const& _rName);
+ Change const* getChange(rtl::OUString const& _rName) const;
+
+ virtual void dispatch(ChangeTreeAction& _anAction) const;
+ virtual void dispatch(ChangeTreeModification& _anAction);
+
+ void forEachChange(ChangeTreeAction& _anAction) const;
+ void forEachChange(ChangeTreeModification& _anAction);
+
+ private:
+ virtual Change* doGetChild(rtl::OUString const& _rName) const;
+ };
+
+ /** iterates through all children of a <type>SubtreeChange</type>. Every non-const action on the object
+ which is beeing iterated invalidates the iterator.
+ <BR>
+ beware of the lifetime of the tree change object : it has to live as long as the iterator does (at least) !!
+ */
+ class SubtreeChange::ChildIterator
+ {
+ protected:
+ uno::Sequence< rtl::OUString > m_aNames;
+ const SubtreeChange* m_pTree;
+ sal_Int32 m_nPos;
+
+ friend class SubtreeChange;
+ struct EndPos { };
+ ChildIterator(const SubtreeChange* _pTree, struct EndPos);
+
+ inline sal_Bool isValid() const { return m_nPos >= 0 && m_nPos < m_aNames.getLength(); }
+
+ public:
+ ChildIterator(const SubtreeChange* _pTree);
+
+ const Change& operator*() const;
+ const Change* operator->() const;
+
+ ChildIterator& operator++();
+ ChildIterator operator++(int) { ChildIterator ret(*this); ++*this; return ret; }
+
+ ChildIterator& operator--();
+ ChildIterator operator--(int) { ChildIterator ret(*this); --*this; return ret; }
+
+ friend bool operator==(ChildIterator const& lhs, ChildIterator const& rhs);
+ friend bool operator!=(ChildIterator const& lhs, ChildIterator const& rhs) { return !(lhs == rhs); }
+ };
+
+ /** iterates through all children of a <type>SubtreeChange</type>. Every non-const action on the object
+ which is beeing iterated invalidates the iterator.
+ <BR>
+ beware of the lifetime of the tree change object : it has to live as long as the iterator does (at least) !!
+ */
+ class SubtreeChange::MutatingChildIterator
+ {
+ protected:
+ SubtreeChange::Children::iterator m_aBaseIter;
+
+ friend class SubtreeChange;
+ MutatingChildIterator(SubtreeChange::Children::iterator aBase) : m_aBaseIter(aBase) {};
+
+ public:
+ Change& current() const { return *m_aBaseIter->second; }
+
+ Change& operator*() const { return current(); }
+ Change* operator->() const { return &current(); }
+
+ MutatingChildIterator& operator++() { ++m_aBaseIter; return *this; }
+ MutatingChildIterator operator++(int) { return MutatingChildIterator(m_aBaseIter++); }
+
+ MutatingChildIterator& operator--() { ++m_aBaseIter; return *this; }
+ MutatingChildIterator operator--(int) { return MutatingChildIterator(m_aBaseIter++); }
+
+ friend bool operator==(MutatingChildIterator const& lhs, MutatingChildIterator const& rhs)
+ { return lhs.m_aBaseIter == rhs.m_aBaseIter; }
+ friend bool operator!=(MutatingChildIterator const& lhs, MutatingChildIterator const& rhs) { return !(lhs == rhs); }
+ };
+ //==========================================================================
+ //= SubtreeChangeReferrer
+ //==========================================================================
+ /** a specialized SubtreeChange, which, upon desctruction, does not delete the changes
+ it holds
+
+ <BR>
+ This implies that when using this class, you have to beware of the lifetime of the involved objects
+ */
+ class SubtreeChangeReferrer : public SubtreeChange
+ {
+ // no explicit construction
+ SubtreeChangeReferrer() : SubtreeChange(::rtl::OUString(), node::Attributes()) { }
+
+ public:
+ SubtreeChangeReferrer(const SubtreeChange& _rSource);
+ ~SubtreeChangeReferrer();
+ };
+
+////////////////////////////////////////////////////////////////////////////////
+ //==========================================================================
+ extern bool isLocalizedValueSet(SubtreeChange const& _aSubtree);
+ extern bool isValueSet(SubtreeChange const& _aSubtree);
+
+ //==========================================================================
+ //= inlines
+ //==========================================================================
+ inline void ChangeTreeAction::applyToChange(Change const& aChange)
+ { aChange.dispatch(*this); }
+ inline void ChangeTreeAction::applyToChildren(SubtreeChange const& aSubtree)
+ { aSubtree.forEachChange(*this); }
+
+ inline void ChangeTreeModification::applyToChange(Change& aChange)
+ { aChange.dispatch(*this); }
+ inline void ChangeTreeModification::applyToChildren(SubtreeChange& aSubtree)
+ { aSubtree.forEachChange(*this); }
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/inc/confapifactory.hxx b/configmgr/source/inc/confapifactory.hxx
new file mode 100644
index 000000000000..63b11f5546cd
--- /dev/null
+++ b/configmgr/source/inc/confapifactory.hxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: confapifactory.hxx,v $
+ * $Revision: 1.19 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#define CONFIGMGR_API_FACTORY_HXX_
+
+#include <sal/types.h>
+
+namespace com { namespace sun { namespace star {
+ namespace uno
+ {
+ class XInterface;
+ template <class> class Reference;
+ class XComponentContext;
+ }
+ namespace lang
+ {
+ class XSingleComponentFactory;
+ }
+} } }
+namespace rtl { class OUString; }
+
+namespace configmgr
+{
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ extern
+ uno::Reference< lang::XSingleComponentFactory > SAL_CALL
+ createProviderFactory(
+ ::rtl::OUString const & aImplementationName,
+ bool bAdmin
+ )
+ SAL_THROW( () );
+
+ struct ServiceRegistrationInfo;
+ struct SingletonRegistrationInfo;
+
+// provider instantiation
+ uno::Reference<uno::XInterface> SAL_CALL
+ getDefaultConfigProviderSingleton( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateDefaultProvider( uno::Reference< uno::XComponentContext > const& xContext );
+
+// provider service info
+ const SingletonRegistrationInfo * getDefaultProviderSingletonInfo();
+ const ServiceRegistrationInfo * getConfigurationProviderServiceInfo();
+ const ServiceRegistrationInfo * getDefaultProviderServiceInfo();
+ const ServiceRegistrationInfo * getAdminProviderServiceInfo();
+
+// other services - instantiation and info
+ uno::Reference< uno::XInterface > SAL_CALL
+ instantiateConfigRegistry( uno::Reference< uno::XComponentContext > const& xContext );
+
+ const ServiceRegistrationInfo* getConfigurationRegistryServiceInfo();
+
+// bootstrap context support
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateBootstrapContext( uno::Reference< uno::XComponentContext > const& xContext );
+
+ const SingletonRegistrationInfo * getBootstrapContextSingletonInfo();
+ const ServiceRegistrationInfo * getBootstrapContextServiceInfo();
+
+ namespace xml
+ {
+ uno::Reference< uno::XInterface > SAL_CALL instantiateSchemaParser
+ ( uno::Reference< uno::XComponentContext > const& xContext );
+ uno::Reference< uno::XInterface > SAL_CALL instantiateLayerParser
+ ( uno::Reference< uno::XComponentContext > const& xContext );
+ uno::Reference< uno::XInterface > SAL_CALL instantiateLayerWriter
+ ( uno::Reference< uno::XComponentContext > const& xContext );
+
+ const ServiceRegistrationInfo* getSchemaParserServiceInfo();
+ const ServiceRegistrationInfo* getLayerParserServiceInfo();
+ const ServiceRegistrationInfo* getLayerWriterServiceInfo();
+ }
+ namespace backend
+ {
+ uno::Reference<uno::XInterface> SAL_CALL
+ getDefaultBackendSingleton( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateDefaultBackend( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference< uno::XInterface > SAL_CALL
+ instantiateUpdateMerger( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateSingleBackendAdapter( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference< uno::XInterface > SAL_CALL
+ instantiateMergeImporter( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference< uno::XInterface > SAL_CALL
+ instantiateCopyImporter( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateMultiStratumBackend( uno::Reference< uno::XComponentContext > const& xContext );
+
+ const SingletonRegistrationInfo * getDefaultBackendSingletonInfo();
+ const ServiceRegistrationInfo * getDefaultBackendServiceInfo();
+
+ const ServiceRegistrationInfo * getUpdateMergerServiceInfo();
+ const ServiceRegistrationInfo * getSingleBackendAdapterServiceInfo();
+ const ServiceRegistrationInfo * getMergeImportServiceInfo();
+ const ServiceRegistrationInfo * getCopyImportServiceInfo();
+ const ServiceRegistrationInfo * getMultiStratumBackendServiceInfo();
+ }
+ namespace localbe
+ {
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalBackend( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalDataImporter( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalHierarchyBrowser( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalSchemaSupplier( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalLegacyStratum( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalDataStratum( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalReadonlyStratum( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalResourceStratum( uno::Reference< uno::XComponentContext > const& xContext );
+
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateLocalMultiStratum( uno::Reference< uno::XComponentContext > const& xContext );
+
+ const ServiceRegistrationInfo * getLocalBackendServiceInfo();
+ const ServiceRegistrationInfo * getLocalDataImportServiceInfo();
+ const ServiceRegistrationInfo * getLocalHierarchyBrowserServiceInfo();
+ const ServiceRegistrationInfo * getLocalSchemaSupplierServiceInfo();
+ const ServiceRegistrationInfo * getLocalLegacyStratumServiceInfo();
+ const ServiceRegistrationInfo * getLocalDataStratumServiceInfo();
+ const ServiceRegistrationInfo * getLocalReadonlyStratumServiceInfo();
+ const ServiceRegistrationInfo * getLocalResourceStratumServiceInfo();
+ const ServiceRegistrationInfo * getLocalMultiStratumServiceInfo();
+ } // localbe
+
+} // namespace configmgr
+
+#endif // CONFIGMGR_API_FACTORY_HXX_
+
+
diff --git a/configmgr/source/inc/confevents.hxx b/configmgr/source/inc/confevents.hxx
new file mode 100644
index 000000000000..3f2ae862a7a9
--- /dev/null
+++ b/configmgr/source/inc/confevents.hxx
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: confevents.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_EVENTS_HXX_
+#define CONFIGMGR_API_EVENTS_HXX_
+
+#include <hash_set>
+#include <map>
+#include <set>
+
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "configpath.hxx"
+#include "utility.hxx"
+
+namespace rtl { class OUString; }
+
+namespace configmgr
+{
+ class Change;
+ struct TreeChangeList;
+ class TreeManager;
+
+ namespace configuration { class AbsolutePath; }
+
+ struct IConfigListener : public salhelper::SimpleReferenceObject
+ {
+ virtual void disposing(TreeManager * pSource) = 0;
+ };
+ struct INodeListener : IConfigListener
+ {
+ virtual void nodeChanged(Change const& aChange, configuration::AbsolutePath const& aPath, TreeManager * pSource) = 0;
+ virtual void nodeDeleted(configuration::AbsolutePath const& aPath, TreeManager * pSource) = 0;
+ };
+
+ namespace internal
+ {
+
+ ////////////////////////////////////////////////////////////////////////
+ template <class ListenerRef>
+ class BroadcastImplHelper
+ {
+ public:
+ osl::Mutex mutex;
+
+ public:
+ BroadcastImplHelper()
+ {}
+
+ ~BroadcastImplHelper()
+ {
+ OSL_ENSURE(m_aInterfaces.empty(), "Configuration Broadcaster was not disposed properly");
+ }
+
+ public:
+ typedef std::set<ListenerRef> Interfaces;
+
+ public:
+ typename Interfaces::iterator addListener(ListenerRef aListener)
+ {
+ return m_aInterfaces.insert(aListener).first;
+ }
+ void removeListener(ListenerRef aListener)
+ {
+ m_aInterfaces.erase(aListener);
+ }
+
+ void disposing(TreeManager * pSource);
+
+ public:
+ typename Interfaces::const_iterator begin() const { return m_aInterfaces.begin(); }
+ typename Interfaces::const_iterator end() const { return m_aInterfaces.end(); }
+
+ typename Interfaces::const_iterator find(ListenerRef aListener) const { return m_aInterfaces.find(aListener); }
+ typename Interfaces::iterator findFull(ListenerRef aListener) { return m_aInterfaces.find(aListener); }
+ private:
+ Interfaces m_aInterfaces;
+
+ // no implementation - not copyable
+ BroadcastImplHelper(BroadcastImplHelper&);
+ void operator=(BroadcastImplHelper&);
+ };
+
+ ////////////////////////////////////////////////////////////////////////
+ template <class Listener>
+ void BroadcastImplHelper<Listener>::disposing(TreeManager * pSource)
+ {
+ osl::ClearableMutexGuard aGuard(this->mutex); // ensure that no notifications are running
+
+ Interfaces aTargets;
+ aTargets.swap(m_aInterfaces);
+
+ aGuard.clear();
+ for(typename Interfaces::iterator it = aTargets.begin(); it != aTargets.end(); )
+ {
+ typename Interfaces::iterator cur = it++;
+ if (*cur)
+ (*cur)->disposing(pSource);
+ }
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////
+
+ class NodeListenerInfo
+ {
+ public:
+ typedef std::hash_set<configuration::AbsolutePath, configuration::Path::Hash, configuration::Path::Equiv> Pathes;
+
+ public:
+ NodeListenerInfo(rtl::Reference<INodeListener> const& pListener)
+ : m_pListener(pListener)
+ {
+ }
+
+ // path handling
+ Pathes const& pathList() const { return m_aPathes; }
+
+ void addPath(configuration::AbsolutePath const& sPath) const { m_aPathes.insert(sPath); }
+ void removePath(configuration::AbsolutePath const& sPath) const { m_aPathes.erase(sPath); }
+ //void removeChildPathes(OUString const& sPath);
+
+ // behave as pointer for use as a 'reference' class
+ rtl::Reference<INodeListener> get() const { return m_pListener; }
+ rtl::Reference<INodeListener> operator->() const { return get(); }
+ INodeListener& operator*() const { return *m_pListener; }
+ // needed to allow if (info) ...
+ struct HasListener;
+ operator HasListener const*() const { return reinterpret_cast<HasListener*>(m_pListener.get()); }
+
+ bool operator < (NodeListenerInfo const& aInfo) const
+ { return std::less<INodeListener*>()(m_pListener.get(), aInfo.m_pListener.get()); }
+
+ bool operator == (NodeListenerInfo const& aInfo) const
+ { return !!( m_pListener == aInfo.m_pListener); }
+
+ bool operator > (NodeListenerInfo const& aInfo) const
+ { return aInfo.operator < (*this); }
+ bool operator >= (NodeListenerInfo const& aInfo) const
+ { return !operator<(aInfo); }
+ bool operator <= (NodeListenerInfo const& aInfo) const
+ { return !operator>(aInfo); }
+
+ bool operator != (NodeListenerInfo const& aInfo) const
+ { return !operator==(aInfo); }
+
+ private:
+ rtl::Reference<INodeListener> m_pListener;
+ mutable Pathes m_aPathes; // hack to be mutable even as set element
+ };
+ } // namespace
+
+ /////////////////////////////////////////////////////////////////////////
+ class ConfigChangeBroadcastHelper // broadcasts changes for a given set of options
+ {
+ public:
+ ConfigChangeBroadcastHelper();
+ ~ConfigChangeBroadcastHelper();
+
+ void broadcast(TreeChangeList const& anUpdate, sal_Bool bError, TreeManager * pSource);
+
+ void addListener(configuration::AbsolutePath const& aName, rtl::Reference<INodeListener> const& );
+ void removeListener(rtl::Reference<INodeListener> const&);
+
+ void dispose(TreeManager * pSource);
+
+ private:
+ void add(configuration::AbsolutePath const& aPath, rtl::Reference<INodeListener> const& pListener);
+ void remove(rtl::Reference<INodeListener> const& pListener);
+
+ void dispatch(Change const& rBaseChange, configuration::AbsolutePath const& sChangeLocation, sal_Bool _bError, TreeManager * pSource);
+ void dispatch(TreeChangeList const& rList_, sal_Bool _bError, TreeManager * pSource);
+ void disposing(TreeManager * pSource);
+
+ void dispatchInner(rtl::Reference<INodeListener> const& pTarget, configuration::AbsolutePath const& sTargetPath, Change const& rBaseChange, configuration::AbsolutePath const& sChangeLocation, sal_Bool _bError, TreeManager * pSource);
+ void dispatchOuter(rtl::Reference<INodeListener> const& pTarget, configuration::AbsolutePath const& sTargetPath, Change const& rBaseChange, configuration::AbsolutePath const& sChangeLocation, sal_Bool _bError, TreeManager * pSource);
+
+ typedef std::multimap<configuration::AbsolutePath, internal::BroadcastImplHelper<internal::NodeListenerInfo>::Interfaces::iterator, configuration::Path::Before> PathMap;
+ internal::BroadcastImplHelper<internal::NodeListenerInfo> m_aListeners;
+ PathMap m_aPathMap;
+ };
+} // namespace
+
+#endif // CONFIGMGR_API_EVENTS_HXX_
+
+
+
diff --git a/configmgr/source/inc/configdefaultprovider.hxx b/configmgr/source/inc/configdefaultprovider.hxx
new file mode 100644
index 000000000000..fcb1eb137aa0
--- /dev/null
+++ b/configmgr/source/inc/configdefaultprovider.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configdefaultprovider.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIG_DEFAULTPROVIDER_HXX_
+#define CONFIGMGR_CONFIG_DEFAULTPROVIDER_HXX_
+
+#include "utility.hxx"
+#include <com/sun/star/uno/Exception.hpp>
+#include <rtl/ref.hxx>
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ class ISubtree;
+ class IDefaultableTreeManager;
+ class RequestOptions;
+ class TreeManager;
+
+ namespace uno = com::sun::star::uno;
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+ class Tree;
+ class NodeRef;
+//-----------------------------------------------------------------------------
+
+ /// provides access to the default for a given request
+ class DefaultProviderProxy;
+
+ class DefaultProvider
+ {
+ rtl::Reference< DefaultProviderProxy > m_aProxy;
+ public:
+ // factory methods
+ static DefaultProvider createEmpty();
+ static DefaultProvider create(rtl::Reference< Tree > const& _aRootTree,
+ RequestOptions const& _xOptions,
+ rtl::Reference< TreeManager > const & _xDefaultProvider,
+ IDefaultableTreeManager* _pDefaultableTree);
+
+ // actual c'tor
+ explicit
+ DefaultProvider(rtl::Reference< DefaultProviderProxy > const& _xProviderProxy);
+
+ // standard c/d-tors to make compiler barrier
+ DefaultProvider(DefaultProvider const& _aOther);
+ DefaultProvider& operator=(DefaultProvider const& _aOther);
+ ~DefaultProvider();
+
+ bool isValid() const { return !! m_aProxy.is(); }
+
+ /// tries to load a default instance of the specified node
+ std::auto_ptr<ISubtree> getDefaultTree(rtl::Reference< Tree > const& _aTree, NodeRef const& _aNode) const SAL_THROW((com::sun::star::uno::Exception));
+
+ /// tries to load default data into the specified tree
+ bool fetchDefaultData(rtl::Reference< Tree > const& _aTreeRef) const SAL_THROW((com::sun::star::uno::Exception));
+ };
+
+//-----------------------------------------------------------------------------
+
+ }
+}
+
+#endif // CONFIGMGR_CONFIG_DEFAULTPROVIDER_HXX_
diff --git a/configmgr/source/inc/configexcept.hxx b/configmgr/source/inc/configexcept.hxx
new file mode 100644
index 000000000000..ab536b64caa1
--- /dev/null
+++ b/configmgr/source/inc/configexcept.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configexcept.hxx,v $
+ * $Revision: 1.6.10.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGEXCEPT_HXX_
+#define CONFIGMGR_CONFIGEXCEPT_HXX_
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+namespace configmgr
+{
+//-------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+ //-------------------------------------------------------------------------
+
+ class Exception
+ {
+ rtl::OString m_sAsciiMessage;
+ public:
+ Exception(char const* sAsciiMessage);
+ Exception(rtl::OString const& sAsciiMessage);
+ virtual ~Exception() {}
+
+ virtual rtl::OUString message() const;
+ virtual char const* what() const;
+ };
+ //-------------------------------------------------------------------------
+
+ class InvalidName : public Exception
+ {
+ rtl::OUString m_sName;
+ public:
+ InvalidName(rtl::OUString const& sName, char const* sAsciiDescription);
+
+ virtual rtl::OUString message() const;
+ };
+ //-------------------------------------------------------------------------
+
+ class ConstraintViolation
+ : public Exception
+ {
+ public:
+ ConstraintViolation(char const* sConstraint);
+ };
+ //-------------------------------------------------------------------------
+
+ class TypeMismatch : public Exception
+ {
+ rtl::OUString m_sTypes;
+ static rtl::OUString describe(rtl::OUString const& sFoundType, rtl::OUString const& sExpectedType);
+ public:
+ TypeMismatch(rtl::OUString const& sFoundType, rtl::OUString const& sExpectedType);
+ TypeMismatch(rtl::OUString const& sFoundType, rtl::OUString const& sExpectedType, char const* sAsciiDescription);
+
+ virtual rtl::OUString message() const;
+ };
+ //-------------------------------------------------------------------------
+ }
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+ namespace configapi
+ {
+ //-------------------------------------------------------------------------
+ class ExceptionMapper
+ {
+ configuration::Exception& m_eOriginal;
+ uno::Reference<uno::XInterface> m_xContext;
+ rtl::OUString m_sMessage;
+ public:
+ ExceptionMapper(configuration::Exception& e);
+ ~ExceptionMapper();
+
+ void setContext(uno::XInterface* pContext);
+
+ rtl::OUString message() const;
+ uno::Reference<uno::XInterface> context() const;
+
+ void illegalArgument(sal_Int16 nArgument = -1) throw(lang::IllegalArgumentException);
+ void unhandled() throw(uno::RuntimeException);
+ };
+ //-------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
+#endif // CONFIGMGR_CONFIGEXCEPT_HXX_
diff --git a/configmgr/source/inc/configgroup.hxx b/configmgr/source/inc/configgroup.hxx
new file mode 100644
index 000000000000..97696d369ae1
--- /dev/null
+++ b/configmgr/source/inc/configgroup.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configgroup.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGGROUP_HXX_
+#define CONFIGMGR_CONFIGGROUP_HXX_
+
+#include "configexcept.hxx"
+#include "noderef.hxx"
+#include "configdefaultprovider.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace script { class XTypeConverter; }
+} } }
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+ class NodeChange;
+ class RelativePath;
+//-----------------------------------------------------------------------------
+
+ /// helper for updating a <type>NodeRef</type> that refers to a Group
+ class GroupUpdateHelper
+ {
+ rtl::Reference< Tree > m_aTree;
+ NodeRef m_aNode;
+ public:
+ GroupUpdateHelper(rtl::Reference< Tree > const& aParentTree, NodeRef const& aGroupNode);
+ ~GroupUpdateHelper() {}
+
+ void validateNode(ValueRef const& aNode) const;
+ void validateNode(NodeRef const& aNode) const;
+
+ rtl::Reference< Tree > const& tree() const { return m_aTree; }
+ NodeRef const& node() const { return m_aNode; }
+ private:
+ void implValidateTree(rtl::Reference< Tree > const& aTree) const;
+ void implValidateNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode) const;
+ void implValidateNode(rtl::Reference< Tree > const& aTree, ValueRef const& aNode) const;
+ };
+//-----------------------------------------------------------------------------
+ /// allows to update values of a simple type within a <type>NodeRef</type> that refers to a Group
+ class GroupUpdater
+ {
+ GroupUpdateHelper m_aHelper;
+ com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> m_xTypeConverter;
+ public:
+ GroupUpdater(rtl::Reference< Tree > const& aParentTree, NodeRef const& aGroupNode, com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> const& xConverter);
+
+ NodeChange validateSetValue(ValueRef const& aValueNode, com::sun::star::uno::Any const& newValue );
+
+ private:
+ com::sun::star::uno::Any implValidateValue(rtl::Reference< Tree > const& aTree, ValueRef const& aNode, com::sun::star::uno::Any const& aValue) const;
+ };
+//-----------------------------------------------------------------------------
+
+ /// allows to reset to default value or state members of a <type>NodeRef</type> that refers to a Group
+ class GroupDefaulter
+ {
+ GroupUpdateHelper m_aHelper;
+ DefaultProvider m_aDefaultProvider;
+ bool m_bHasDoneSet;
+ public:
+ GroupDefaulter(rtl::Reference< Tree > const& _aParentTree, NodeRef const& _aGroupNode, DefaultProvider const& _aProvider);
+
+ bool hasDoneSet() const { return m_bHasDoneSet; }
+
+ NodeChange validateSetToDefaultValue(ValueRef const& aValueNode);
+
+ NodeChange validateSetToDefaultState(NodeRef const& aNode);
+
+ NodeChanges validateSetAllToDefault();
+
+ static bool isDataAvailable(rtl::Reference< Tree > const& _aParentTree, NodeRef const& _aGroupNode);
+ static bool ensureDataAvailable(rtl::Reference< Tree > const& _aParentTree, NodeRef const& _aGroupNode, DefaultProvider const& _aSource);
+ };
+//-----------------------------------------------------------------------------
+ bool isPossibleValueType(com::sun::star::uno::Type const& aValueType);
+//-----------------------------------------------------------------------------
+ bool convertCompatibleValue(com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> const& xConverter, uno::Any& rConverted,
+ com::sun::star::uno::Any const& rNewValue, com::sun::star::uno::Type const& rTargetType);
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGGROUP_HXX_
diff --git a/configmgr/source/inc/configinteractionhandler.hxx b/configmgr/source/inc/configinteractionhandler.hxx
new file mode 100644
index 000000000000..a2eb8d640406
--- /dev/null
+++ b/configmgr/source/inc/configinteractionhandler.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configinteractionhandler.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGINTERACTIONHANDLER_HXX
+#define CONFIGMGR_CONFIGINTERACTIONHANDLER_HXX
+
+#include "sal/config.h"
+#include "com/sun/star/uno/Reference.hxx"
+#include "rtl/ref.hxx"
+#include "uno/current_context.hxx"
+
+namespace com { namespace sun { namespace star {
+ namespace task { class XInteractionHandler; }
+ namespace uno { class Any; }
+} } }
+namespace rtl { class OUString; }
+
+namespace configmgr { namespace apihelper {
+
+/**
+ represents the InteractionHandler for configuration errors from the current
+ context.
+
+ <p>Should only be kept in scope while the error is being handled.</p>
+*/
+class ConfigurationInteractionHandler {
+public:
+ ConfigurationInteractionHandler();
+
+ ~ConfigurationInteractionHandler();
+
+ com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler >
+ get() const; // throw (com::sun::star::uno::RuntimeException)
+
+ void setRecursive(
+ com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionHandler > const & handler);
+
+private:
+ ConfigurationInteractionHandler(ConfigurationInteractionHandler &);
+ // not defined
+ void operator =(ConfigurationInteractionHandler &); // not defined
+
+ com::sun::star::uno::Any getPreviousContextValue(
+ rtl::OUString const & name) const;
+ // throw (com::sun::star::uno::RuntimeException)
+
+ class Context;
+ friend class Context;
+
+ rtl::Reference< Context > m_context;
+ com::sun::star::uno::ContextLayer m_layer;
+};
+
+} }
+
+#endif
diff --git a/configmgr/source/inc/configpath.hxx b/configmgr/source/inc/configpath.hxx
new file mode 100644
index 000000000000..4b1076fa1518
--- /dev/null
+++ b/configmgr/source/inc/configpath.hxx
@@ -0,0 +1,449 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configpath.hxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGPATH_HXX_
+#define CONFIGMGR_CONFIGPATH_HXX_
+
+#include <rtl/ustring.hxx>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif // INCLUDED_VECTOR
+
+namespace configmgr
+{
+ namespace configuration
+ {
+ //--------------------------------------------------------------------
+
+ /** check if this is a well-formed name for a
+ config Node (excluding set elements)
+ */
+ bool isSimpleName(rtl::OUString const& sName) SAL_THROW(());
+
+ /** make a name out of <var>sName</var>,
+ validating that it can be used for a config Node (excluding set elements)
+ or template name.
+ @throws InvalidName
+ if the name is not valid for that purpose
+ */
+ rtl::OUString validateNodeName(rtl::OUString const& sName);
+
+ /** make a name out of <var>sName</var>
+ validating that it can be used for a config set element
+ @throws InvalidName
+ if the name is not valid for that purpose
+ */
+ rtl::OUString validateElementName(rtl::OUString const& sName);
+ //------------------------------------------------------------------------
+
+ //------------------------------------------------------------------------
+ namespace Path
+ {
+ //------------------------------------------------------------------------
+
+ class Component
+ {
+ /// holds the contents of this path component
+ rtl::OUString m_aName;
+ public:
+ /// construct a path component from a string, without any validation
+ Component(rtl::OUString const& _sName) SAL_THROW(());
+
+ /// is this component an empty name ?
+ bool isEmpty() const SAL_THROW(()) { return m_aName.getLength() == 0; }
+ /// is this component a simple name ?
+ bool isSimpleName() const SAL_THROW(());
+ /// get the inner name for this component
+ rtl::OUString getName() const SAL_THROW(());
+ /// get the embedded type name for this component (if any)
+ rtl::OUString getTypeName() const SAL_THROW(());
+
+ /// get the contents of this as string (unparsed).
+ rtl::OUString toPathString() const SAL_THROW(()) { return m_aName; }
+
+ // hashing - for hash maps. compatible to equiv or matches
+ size_t hashCode() const SAL_THROW(())
+ { return this->getName().hashCode(); }
+
+ /// get the contents of this as a name (unparsed). Use with care !
+ rtl::OUString const& getInternalName() const SAL_THROW(()) { return m_aName; }
+
+ };
+
+ //-------------------------------------------------------------------------
+
+ /// compare taking type wildcards into account
+ bool matches(Component const& lhs,Component const& rhs) SAL_THROW(());
+
+ /// compare by inner names only
+ bool before(Component const& lhs,Component const& rhs) SAL_THROW(());
+
+ /// compare by inner names only
+ bool equiv(Component const& lhs,Component const& rhs) SAL_THROW(());
+ //-------------------------------------------------------------------------
+
+ /// construct a empty path component
+ Component makeEmptyComponent() SAL_THROW(());
+
+ //-------------------------------------------------------------------------
+ /// construct a path component from a name, validating it as simple name
+ Component wrapSimpleName(rtl::OUString const& _aName);
+
+ /// construct a path component from a type and element name, using a wildcard if no type is available
+ Component makeCompositeName(rtl::OUString const& _aElementName, rtl::OUString const& _aTypeName);
+
+ //-----------------------------------------------------------------------------
+ /// construct a composite path component from a element name or string, using a wildcard type
+ template <class NameRep>
+ Component wrapElementName(NameRep const& _aElementName) SAL_THROW(())
+ {
+ return makeCompositeName(_aElementName, NameRep());
+ }
+
+ //-------------------------------------------------------------------------
+ /// construct a path component from an arbitrary na,e or string
+ template <class NameRep>
+ Component wrapSafeName(NameRep const& _aName) SAL_THROW(())
+ {
+ return isSimpleName(_aName) ? wrapSimpleName(_aName) : wrapElementName(_aName);
+ }
+
+ //-----------------------------------------------------------------------------
+ /** lower-level representation of a path within the configuration
+ <p>Keeps the data in a vector of names in reverse order! </P>
+ */
+ class Rep
+ {
+ public:
+ /// construct an empty path
+ Rep() SAL_THROW(()) : m_aComponents() {}
+
+ /// construct a path consisting of a single component <var>_aName</var>
+ explicit Rep(Component const& _aName) SAL_THROW(()) : m_aComponents(1,_aName) {}
+
+ /// construct a path consisting of a path subrange
+ explicit Rep(std::vector<Component>::const_reverse_iterator const& _first, std::vector<Component>::const_reverse_iterator const& _last)
+ : m_aComponents(_last.base(), _first.base()) {}
+
+ /// swap contents with another instance
+ void swap(Rep& _aOther) SAL_THROW(()) { m_aComponents.swap(_aOther.m_aComponents); }
+
+ /// modify a path by prepending <var>aName</var>
+ void prepend(Component const& _aName) SAL_THROW(()) { m_aComponents.push_back(_aName); }
+
+ /// modify a path by prepending <var>aName</var>
+ void prepend(Rep const& _aOther) SAL_THROW(());
+
+ /// get the local name (the last component of this path)
+ Component const& getLocalName() const { check_not_empty(); return m_aComponents.front(); }
+
+ /// get the next name (the first component of this path)
+ Component const& getFirstName() const { check_not_empty(); return m_aComponents.back(); }
+
+ /// set this to the remainder after the first name (drop the first component of this path)
+ void dropFirstName() { check_not_empty(); m_aComponents.pop_back(); }
+
+ /// get a /-separated string representation of this
+ rtl::OUString toString(bool _bAbsolute) const SAL_THROW(());
+
+ public:
+ /// check if this is an empty path
+ bool isEmpty() const SAL_THROW(()) { return m_aComponents.empty(); }
+
+ /// Count the components of this
+ std::vector<Component>::size_type countComponents() const SAL_THROW(()) { return m_aComponents.size(); }
+
+ /// Insert a component into this path
+ void insertComponent(std::vector<Component>::reverse_iterator _it, Component _aName)
+ { m_aComponents.insert(_it.base(),_aName); }
+
+ /// Remove a component from this path
+ void removeComponent(std::vector<Component>::reverse_iterator _it) { m_aComponents.erase(_it.base()); }
+
+ /// Remove all components from this path
+ void clearComponents() SAL_THROW(()) { m_aComponents.clear(); }
+
+ /// get a STL style iterator to the first component
+ std::vector<Component>::const_reverse_iterator begin() const SAL_THROW(()) { return m_aComponents.rbegin(); }
+ /// get a STL style iterator to after the last component
+ std::vector<Component>::const_reverse_iterator end() const SAL_THROW(()) { return m_aComponents.rend(); }
+
+ /// get a STL style iterator to the first component
+ std::vector<Component>::reverse_iterator begin_mutate() SAL_THROW(()) { return m_aComponents.rbegin(); }
+ /// get a STL style iterator to after the last component
+ std::vector<Component>::reverse_iterator end_mutate() SAL_THROW(()) { return m_aComponents.rend(); }
+
+ // hashing - for hash maps
+ size_t hashCode() const SAL_THROW(());
+
+ /// preflight check for operations that require a non-empty path
+ void check_not_empty() const;
+
+ private:
+ std::vector<Component> m_aComponents;
+ };
+ //------------------------------------------------------------------------
+
+ /// compare taking type wildcards into account
+ bool matches(Rep const& lhs,Rep const& rhs) SAL_THROW(());
+
+ /// compare by inner names only
+ bool before(Rep const& lhs,Rep const& rhs) SAL_THROW(());
+
+ /// compare by inner names only
+ bool equiv(Rep const& lhs,Rep const& rhs) SAL_THROW(());
+ //------------------------------------------------------------------------
+
+ /// check a path for a prefix
+ bool hasMatchingPrefix(Rep const& _aPath,Rep const& _aPrefix) SAL_THROW(());
+
+ /// remove a prefix from a path. Throws InvalidName if it isn't a prefix
+ Rep stripMatchingPrefix(Rep const& _aPath,Rep const& _aPrefix);
+ //------------------------------------------------------------------------
+
+ /// distinguishes which kind of path is present in a string
+ bool isAbsolutePath(rtl::OUString const& _sPath);
+ //------------------------------------------------------------------------
+ }
+ //------------------------------------------------------------------------
+
+ class RelativePath
+ {
+ Path::Rep m_aRep;
+ public:
+ // Construction
+ /// construct a relative path from <var>aString</var> throwing InvalidName for parse errors
+ static RelativePath parse(rtl::OUString const& _aString);
+
+ /// construct an empty relative path
+ RelativePath() SAL_THROW(()) : m_aRep() { init(); }
+
+ /// construct a relative path having <var>aRep</var> as representation
+ explicit RelativePath(Path::Rep const& _aRep)
+ : m_aRep(_aRep) { init(); }
+
+ /// CONVERSION: construct a relative path having <var>aName</var> as single component
+ RelativePath(Path::Component const& _aName) SAL_THROW(());
+
+ /// build the Path that results from appending <var>aPath</var> to this
+ RelativePath compose(RelativePath const& _aPath) const SAL_THROW(());
+
+ /// check if this is an empty path
+ bool isEmpty() const SAL_THROW(()) { return m_aRep.isEmpty(); }
+
+ /// Count the components of this
+ std::vector<Path::Component>::size_type getDepth() const SAL_THROW(()) { return m_aRep.countComponents(); }
+
+ /// get the local name (the last component of this path)
+ Path::Component const& getLocalName() const { return m_aRep.getLocalName(); }
+
+ /// get the local name (the first component of this path)
+ Path::Component const& getFirstName() const { return m_aRep.getFirstName(); }
+
+ /// set this to the remainder of this path after the first name (drop the first component of this path)
+ void dropFirstName() { m_aRep.dropFirstName(); }
+
+ /// get a /-separated string representation of this
+ rtl::OUString toString() const SAL_THROW(());
+ public:
+ // Iteration support
+ /// get a STL style iterator to the first component
+ std::vector<Path::Component>::const_reverse_iterator begin() const SAL_THROW(()) { return m_aRep.begin(); }
+ /// get a STL style iterator to after the last component
+ std::vector<Path::Component>::const_reverse_iterator end() const SAL_THROW(()) { return m_aRep.end(); }
+
+ /// get a STL style iterator to the first component
+ std::vector<Path::Component>::reverse_iterator begin_mutate() SAL_THROW(()) { return m_aRep.begin_mutate(); }
+ /// get a STL style iterator to after the last component
+ std::vector<Path::Component>::reverse_iterator end_mutate() SAL_THROW(()) { return m_aRep.end_mutate(); }
+
+ // Direct access - 'package' visible
+ /// Get a reference to (or copy of) the internal PathRep of this
+ Path::Rep const& rep() const SAL_THROW(()) { return m_aRep; }
+
+ private:
+ void init();
+ };
+
+ /// compare taking type wildcards into account
+ inline bool matches(RelativePath const& lhs,RelativePath const& rhs) SAL_THROW(())
+ { return Path::matches(lhs.rep(),rhs.rep()); }
+
+ //------------------------------------------------------------------------
+
+ class AbsolutePath
+ {
+ Path::Rep m_aRep;
+ public:
+ // Construction
+ /// construct a absolute path from <var>aString</var> throwing InvalidName for parse errors
+ static AbsolutePath parse(rtl::OUString const& _aString);
+
+ /// construct a absolute path to a whole module (toplevel) without error checking
+ static AbsolutePath makeModulePath(rtl::OUString const& _aString) SAL_THROW(());
+
+ /// construct an absolute path to the (virtual) hierarchy root
+ static AbsolutePath root() SAL_THROW(());
+
+ /// construct an (otherwise invalid) substitute path for the root of a free-floating node
+ static AbsolutePath detachedRoot() SAL_THROW(());
+
+ /// construct a absolute path having <var>aRep</var> as representation
+ explicit AbsolutePath(Path::Rep const& _aRep) SAL_THROW(())
+ : m_aRep(_aRep) { init(); }
+
+ /// build the absolute path that results from appending <var>aPath</var> to this
+ AbsolutePath compose(RelativePath const& _aPath) const SAL_THROW(());
+
+ /// build the absolute path that results from removing the last component of this
+ AbsolutePath getParentPath() const;
+
+ /// check if this is the path to the (imaginary) root node
+ bool isRoot() const SAL_THROW(()) { return m_aRep.isEmpty(); }
+#if OSL_DEBUG_LEVEL > 0
+ /// check if this is a path to a detached node
+ bool isDetached() const SAL_THROW(());
+#endif
+ /// get the local name (the last component of this path)
+ Path::Component const& getLocalName() const { return m_aRep.getLocalName(); }
+
+ rtl::OUString const & getModuleName() const { return m_aRep.getFirstName().getInternalName(); }
+
+ /// get a /-separated string representation of this
+ rtl::OUString toString() const SAL_THROW(());
+
+ /// Count the components of this
+ std::vector<Path::Component>::size_type getDepth() const SAL_THROW(()) { return m_aRep.countComponents(); }
+ public:
+ // Iteration support
+ /// get a STL style iterator to the first component
+ std::vector<Path::Component>::const_reverse_iterator begin() const SAL_THROW(()) { return m_aRep.begin(); }
+ /// get a STL style iterator to after the last component
+ std::vector<Path::Component>::const_reverse_iterator end() const SAL_THROW(()) { return m_aRep.end(); }
+
+ /// get a STL style iterator to the first component
+ std::vector<Path::Component>::reverse_iterator begin_mutate() SAL_THROW(()) { return m_aRep.begin_mutate(); }
+ /// get a STL style iterator to after the last component
+ std::vector<Path::Component>::reverse_iterator end_mutate() SAL_THROW(()) { return m_aRep.end_mutate(); }
+
+ // Direct access - 'package' visible
+ /// Get a reference to (or copy of) the internal PathRep of this
+ Path::Rep const& rep() const SAL_THROW(()) { return m_aRep; }
+ private:
+ void init() SAL_THROW(());
+ };
+
+ /// compare taking type wildcards into account
+ inline bool matches(AbsolutePath const& lhs,AbsolutePath const& rhs) SAL_THROW(())
+ { return Path::matches(lhs.rep(),rhs.rep()); }
+
+ namespace Path
+ {
+ //------------------------------------------------------------------------
+ template <class PathClass>
+ bool hasPrefix(PathClass const& _aPath, PathClass const& _aPrefix) SAL_THROW(())
+ {
+ return hasMatchingPrefix(_aPath.rep(),_aPrefix.rep() );
+ }
+ //------------------------------------------------------------------------
+
+ template <class PathClass>
+ RelativePath stripPrefix(PathClass const& _aPath, PathClass const& _aPrefix)
+ {
+ return RelativePath( stripMatchingPrefix(_aPath.rep(),_aPrefix.rep()) );
+ }
+ //------------------------------------------------------------------------
+
+ // STL Helpers
+ //------------------------------------------------------------------------
+
+ /// a weak strict ordering considering only the name part
+ struct Before
+ {
+ bool operator()(Component const& lhs, Component const& rhs) const SAL_THROW(())
+ { return before(lhs,rhs); }
+ bool operator()(Rep const& lhs, Rep const& rhs) const SAL_THROW(())
+ { return before(lhs,rhs); }
+ bool operator()(AbsolutePath const& lhs, AbsolutePath const& rhs) const SAL_THROW(())
+ { return before(lhs.rep(),rhs.rep()); }
+ bool operator()(RelativePath const& lhs, RelativePath const& rhs) const SAL_THROW(())
+ { return before(lhs.rep(),rhs.rep()); }
+ };
+ //------------------------------------------------------------------------
+
+ /// an equality relation considering only the name part (compatible to Before)
+ struct Equiv
+ {
+ bool operator()(Component const& lhs, Component const& rhs) const SAL_THROW(())
+ { return equiv(lhs,rhs); }
+ bool operator()(Rep const& lhs, Rep const& rhs) const SAL_THROW(())
+ { return equiv(lhs,rhs); }
+ bool operator()(AbsolutePath const& lhs, AbsolutePath const& rhs) const SAL_THROW(())
+ { return equiv(lhs.rep(),rhs.rep()); }
+ bool operator()(RelativePath const& lhs, RelativePath const& rhs) const SAL_THROW(())
+ { return equiv(lhs.rep(),rhs.rep()); }
+ };
+ //------------------------------------------------------------------------
+
+ /// a hash generator (compatible to Equiv and Before)
+ struct Hash
+ {
+ size_t operator()(Component const& _aObject) const SAL_THROW(())
+ { return _aObject.hashCode(); }
+ size_t operator()(Rep const& _aObject) const SAL_THROW(())
+ { return _aObject.hashCode(); }
+ size_t operator()(AbsolutePath const& _aObject) const SAL_THROW(())
+ { return _aObject.rep().hashCode(); }
+ size_t operator()(RelativePath const& _aObject) const SAL_THROW(())
+ { return _aObject.rep().hashCode(); }
+ };
+ //------------------------------------------------------------------------
+ /// a binary predicate that is not (!) an equivalence relation
+
+ struct Matches
+ {
+ bool operator()(Component const& lhs, Component const& rhs) const SAL_THROW(())
+ { return matches(lhs,rhs); }
+ bool operator()(Rep const& lhs, Rep const& rhs) const SAL_THROW(())
+ { return matches(lhs,rhs); }
+ bool operator()(AbsolutePath const& lhs, AbsolutePath const& rhs) const SAL_THROW(())
+ { return matches(lhs.rep(),rhs.rep()); }
+ bool operator()(RelativePath const& lhs, RelativePath const& rhs) const SAL_THROW(())
+ { return matches(lhs.rep(),rhs.rep()); }
+ };
+ //------------------------------------------------------------------------
+ }
+ //------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGNAME_HXX_
diff --git a/configmgr/source/inc/configset.hxx b/configmgr/source/inc/configset.hxx
new file mode 100644
index 000000000000..8d7394ad7b09
--- /dev/null
+++ b/configmgr/source/inc/configset.hxx
@@ -0,0 +1,146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configset.hxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGSET_HXX_
+#define CONFIGMGR_CONFIGSET_HXX_
+
+#include "configexcept.hxx"
+#include "configdefaultprovider.hxx"
+#include "template.hxx"
+#include "noderef.hxx"
+#include <rtl/ref.hxx>
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace com { namespace sun { namespace star {
+ namespace script { class XTypeConverter; }
+} } }
+
+namespace configmgr
+{
+ namespace data { class TreeSegment; }
+
+ namespace configuration
+ {
+ namespace Path { class Component; }
+ //---------------------------------------------------------------------
+
+ class ElementTree;
+
+ class NodeChange;
+ class Template;
+
+ class SetElementFactory
+ {
+ TemplateProvider m_aProvider;
+ public:
+ SetElementFactory(TemplateProvider const& aProvider);
+ SetElementFactory(SetElementFactory const& aOther);
+ SetElementFactory& operator=(SetElementFactory const& aOther);
+ ~SetElementFactory();
+
+ rtl::Reference< ElementTree > instantiateTemplate(rtl::Reference<Template> const& aTemplate);
+ rtl::Reference< ElementTree > instantiateOnDefault(rtl::Reference< data::TreeSegment > const& _aTree, rtl::Reference<Template> const& aDummyTemplate);
+
+ static TemplateProvider findTemplateProvider(rtl::Reference< Tree > const& aTree, NodeRef const& aNode);
+ };
+
+//-----------------------------------------------------------------------------
+
+ /// allows to insert,remove and replace an element of a <type>Node</type> that is a Container ("set") of full-fledged trees.
+ class TreeSetUpdater
+ {
+ rtl::Reference< Tree > m_aParentTree;
+ NodeRef m_aSetNode;
+ rtl::Reference<Template> m_aTemplate;
+ public:
+ TreeSetUpdater(rtl::Reference< Tree > const& aParentTree, NodeRef const& aSetNode, rtl::Reference< Template > const& aTemplate);
+
+ NodeChange validateInsertElement (rtl::OUString const& aName, rtl::Reference< ElementTree > const& aNewElement);
+
+ NodeChange validateReplaceElement(rtl::Reference< ElementTree > const& aElement, rtl::Reference< ElementTree > const& aNewElement);
+
+ NodeChange validateRemoveElement (rtl::Reference< ElementTree > const& aElement);
+ private:
+ void implValidateSet();
+ Path::Component implValidateElement(rtl::Reference< ElementTree > const& aElement, bool bReqRemovable);
+ void implValidateTree(rtl::Reference< ElementTree > const& aElementTree);
+ };
+//-----------------------------------------------------------------------------
+ /// allows to insert,remove and replace an element of a <type>Node</type> that is a Container ("set") of simple values.
+ class ValueSetUpdater
+ {
+ rtl::Reference< Tree > m_aParentTree;
+ NodeRef m_aSetNode;
+ rtl::Reference<Template> m_aTemplate;
+ com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> m_xTypeConverter;
+ public:
+ ValueSetUpdater(rtl::Reference< Tree > const& aParentTree, NodeRef const& aSetNode,
+ rtl::Reference< Template > const& aTemplate, com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> const& xConverter);
+
+ NodeChange validateInsertElement (rtl::OUString const& aName, com::sun::star::uno::Any const& aNewValue);
+
+ NodeChange validateReplaceElement(rtl::Reference< ElementTree > const& aElement, com::sun::star::uno::Any const& aNewValue);
+
+ NodeChange validateRemoveElement (rtl::Reference< ElementTree > const& aElement);
+ private:
+ void implValidateSet();
+ Path::Component implValidateElement(rtl::Reference< ElementTree > const& aElement, bool bReqRemovable);
+ com::sun::star::uno::Any implValidateValue(rtl::Reference< Tree > const& aElementTree, com::sun::star::uno::Any const& aValue);
+ com::sun::star::uno::Any implValidateValue(com::sun::star::uno::Any const& aValue);
+
+ rtl::Reference<ElementTree> makeValueElement(rtl::OUString const& aName, rtl::Reference< Tree > const& aElementTree, com::sun::star::uno::Any const& aValue, bool bInserting);
+ rtl::Reference<ElementTree> makeValueElement(rtl::OUString const& aName, com::sun::star::uno::Any const& aValue, bool bInserting);
+ rtl::Reference< Tree > extractElementNode(rtl::Reference< ElementTree > const& aElement);
+ };
+//-----------------------------------------------------------------------------
+
+ /// allows to restore to its default state a <type>Node</type> that is a Container ("set") of full-fledged trees.
+ class SetDefaulter
+ {
+ rtl::Reference< Tree > m_aParentTree;
+ NodeRef m_aSetNode;
+ DefaultProvider m_aDefaultProvider;
+ public:
+ SetDefaulter(rtl::Reference< Tree > const& aParentTree, NodeRef const& aSetNode, DefaultProvider const& aDefaultProvider);
+
+ NodeChange validateSetToDefaultState();
+
+ private:
+ void implValidateSet();
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGSET_HXX_
diff --git a/configmgr/source/inc/confsvccomponent.hxx b/configmgr/source/inc/confsvccomponent.hxx
new file mode 100644
index 000000000000..174d13e675ac
--- /dev/null
+++ b/configmgr/source/inc/confsvccomponent.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: confsvccomponent.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_API_SVCCOMPONENT_HXX_
+#define CONFIGMGR_API_SVCCOMPONENT_HXX_
+
+#include "serviceinfohelper.hxx"
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/compbase1.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+#ifndef _OSL_MUTEX_HXX_
+#include <osl/Mutex.hxx>
+#endif
+#include <rtl/ustring.hxx>
+
+namespace configmgr
+{
+
+//----------------------------------------------------------------------------
+ namespace css = ::com::sun::star;
+ namespace uno = css::uno;
+ namespace lang = css::lang;
+
+//----------------------------------------------------------------------------
+ class ServiceComponentImpl
+ : public ::cppu::WeakComponentImplHelper1< lang::XServiceInfo >
+ {
+ protected:
+ ServiceImplementationInfo const*const m_info;
+ public:
+ ServiceComponentImpl(ServiceImplementationInfo const* aInfo);
+
+ // XTypeProvider
+ virtual uno::Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw(uno::RuntimeException);
+ //virtual uno::Sequence<uno::Type> SAL_CALL getTypes( ) throw(uno::RuntimeException) = 0;
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName( ) throw(uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException);
+ virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw(uno::RuntimeException);
+
+ // Component Helper - force override
+ virtual void SAL_CALL disposing() = 0;
+ // Component Helper - check object state
+ virtual void checkAlive() throw (uno::RuntimeException);
+ void checkAlive(char const* message) throw (uno::RuntimeException)
+ { checkAlive( rtl::OUString::createFromAscii(message) ); }
+ void checkAlive(rtl::OUString const& message) throw (uno::RuntimeException);
+
+ // Extra helpers
+ static uno::Sequence<sal_Int8> getStaticImplementationId(ServiceImplementationInfo const* pServiceInfo) throw(uno::RuntimeException);
+
+ private: // no implementation
+ ServiceComponentImpl(ServiceComponentImpl&);
+ void operator=(ServiceComponentImpl&);
+ };
+//----------------------------------------------------------------------------
+
+} // namespace configmgr
+
+#endif // CONFIGMGR_API_SVCCOMPONENT_HXX_
+
+
diff --git a/configmgr/source/inc/datalock.hxx b/configmgr/source/inc/datalock.hxx
new file mode 100644
index 000000000000..127763ea1026
--- /dev/null
+++ b/configmgr/source/inc/datalock.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: datalock.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_DATALOCK_HXX_
+#define CONFIGMGR_DATALOCK_HXX_
+
+#include "sal/config.h"
+
+#include "osl/interlck.h"
+#include "osl/mutex.hxx"
+
+namespace configmgr {
+
+ class UnoApiLock
+ {
+ static osl::Mutex aCoreLock;
+ public:
+ static volatile oslInterlockedCount nHeld;
+ UnoApiLock() { acquire(); }
+ ~UnoApiLock() { release(); }
+
+ static osl::Mutex &getLock() { return aCoreLock; }
+ static void acquire() { aCoreLock.acquire(); nHeld++; }
+ static void release() { nHeld--; aCoreLock.release(); }
+ static bool isHeld() { return nHeld != 0; }
+ };
+ class UnoApiLockReleaser
+ {
+ oslInterlockedCount mnCount;
+ public:
+ UnoApiLockReleaser();
+ ~UnoApiLockReleaser();
+ };
+ class UnoApiLockClearable : public UnoApiLock
+ {
+ bool mbSet;
+ public:
+ UnoApiLockClearable() : mbSet(true) { acquire(); }
+ ~UnoApiLockClearable() { clear(); }
+ void clear() { if (mbSet) { mbSet = false; release(); } }
+ };
+}
+
+#endif // CONFIGMGR_DATALOCK_HXX_
diff --git a/configmgr/source/inc/defaultprovider.hxx b/configmgr/source/inc/defaultprovider.hxx
new file mode 100644
index 000000000000..9f60224c2e9f
--- /dev/null
+++ b/configmgr/source/inc/defaultprovider.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: defaultprovider.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_DEFAULTPROVIDER_HXX
+#define CONFIGMGR_DEFAULTPROVIDER_HXX
+
+#include "sal/config.h"
+
+#include "com/sun/star/uno/Exception.hpp"
+#include "sal/types.h"
+
+#include "utility.hxx"
+
+namespace configmgr
+{
+ namespace configuration
+ {
+ class AbsolutePath;
+ }
+ //-------------------------
+ class RequestOptions;
+ //==========================================================================
+ //= IDefaultableTreeManager
+ //==========================================================================
+ /* is a supplementary interface for an <type>OProviderImpl</type>.
+ <p>Supports functionality to load default data into the managed tree</p>
+ */
+ class SAL_NO_VTABLE IDefaultableTreeManager
+ {
+ public:
+ /** attempt to load default data into the tree named by a path using certain options
+ and requiring a specific loading depth.
+
+ @returns
+ <TRUE/>, if some default data is available within the tree
+ <FALSE/>, if no default data is available for the tree
+ */
+ virtual sal_Bool fetchDefaultData(configuration::AbsolutePath const& aSubtreePath,
+ const RequestOptions& _xOptions
+ ) SAL_THROW((com::sun::star::uno::Exception)) = 0;
+
+ };
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/inc/emptylayer.hxx b/configmgr/source/inc/emptylayer.hxx
new file mode 100644
index 000000000000..946ecf6a6ed1
--- /dev/null
+++ b/configmgr/source/inc/emptylayer.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: emptylayer.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_EMPTYLAYER_HXX
+#define CONFIGMGR_BACKEND_EMPTYLAYER_HXX
+
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace backend
+ {
+ // -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+
+ // -----------------------------------------------------------------------------
+ uno::Reference< backenduno::XLayer > createEmptyLayer();
+
+ bool checkEmptyLayer(uno::Reference< backenduno::XLayer > const & xLayer );
+ // -----------------------------------------------------------------------------
+ } // namespace xml
+ // -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
diff --git a/configmgr/source/inc/filehelper.hxx b/configmgr/source/inc/filehelper.hxx
new file mode 100644
index 000000000000..0712f68eb8f8
--- /dev/null
+++ b/configmgr/source/inc/filehelper.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: filehelper.hxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_FILEHELPER_HXX_
+#define _CONFIGMGR_FILEHELPER_HXX_
+
+#include "utility.hxx"
+#include <osl/file.hxx>
+#include <com/sun/star/io/IOException.hpp>
+
+namespace io = com::sun::star::io;
+
+namespace configmgr
+{
+ //==========================================================================
+ //= FileHelper
+ //==========================================================================
+ /** Within the FileHelper namespace there is a list of methods declared, which ease
+ specific file operations.
+ */
+ namespace FileHelper
+ {
+ /// delimiter used in URLs and ConfPath
+ static const ::sal_Unicode delimiter = sal_Unicode('/');
+
+ /// Tests if the file exists.
+ bool fileExists(rtl::OUString const& _sFileURL);
+
+ /// Tests if the directory exists.
+ bool dirExists(rtl::OUString const& _sDirURL);
+
+ /** Returns the parent part of the pathname of this File URL,
+ or an empty string if the name has no parent part.
+ The parent part is generally everything leading up to the last occurrence
+ of the separator character.
+ */
+ rtl::OUString getParentDir(rtl::OUString const& _aFileURL);
+
+ /**
+ Returns the file name part of a file URL.
+
+ @param aFileUrl file URL
+ @return everything in the URL from the last delimiter on
+ */
+ rtl::OUString getFileName(const rtl::OUString& aFileUrl) ;
+
+ /**
+ Splits a file URL between its parent directory/file name
+ parts.
+
+ @param aFileUrl file URL
+ @param aParentDirectory parent directory filled on return
+ @param aFileName file name filled on return
+ */
+ void splitFileUrl(const rtl::OUString& aFileUrl,
+ rtl::OUString& aParentDirectory,
+ rtl::OUString& aFileName) ;
+
+ /** creates a directory whose pathname is specified by a FileURL.
+ @return true if directory could be created or does exist, otherwise false.
+ */
+ osl::FileBase::RC mkdir(rtl::OUString const& _sDirURL);
+
+ /** creates a directory whose pathname is specified by a FileURL,
+ including any necessary parent directories.
+ @return true if directory (or directories) could be created or do(es) exist, otherwise false.
+ */
+ osl::FileBase::RC mkdirs(rtl::OUString const& _aDirectory);
+
+ /** replaces a file specified by _aToURL with a file specified by _aFromURL.
+ */
+ void replaceFile(const rtl::OUString& _aToURL, const rtl::OUString &_aFromURL) SAL_THROW((io::IOException));
+
+ /** removes a file specified by _aURL. Ignores the case of a non-existing file.
+ */
+ bool tryToRemoveFile(const rtl::OUString& _aURL, bool tryBackupFirst);
+
+ /** creates an error msg string for a given file error return code.
+ */
+ rtl::OUString createOSLErrorString(osl::FileBase::RC eError);
+
+ /** determines the status of a directory entry specified by a URL.
+ @return the Size of the file in bytes and the TimeValue of the last modification, if the file exists,
+ otherwise 0 and a TimeValue(0,0).
+ */
+ sal_uInt64 getModifyStatus(rtl::OUString const& _aNormalizedFilename, TimeValue & rModifyTime);
+ }
+} // namespace configmgr
+
+#endif
diff --git a/configmgr/source/inc/flags.hxx b/configmgr/source/inc/flags.hxx
new file mode 100644
index 000000000000..1ddac8ac52e7
--- /dev/null
+++ b/configmgr/source/inc/flags.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: flags.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DATA_FLAGS_HXX
+#define INCLUDED_DATA_FLAGS_HXX
+
+#include <sal/types.h>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace data
+ {
+ //-----------------------------------------------------------------------------
+ // node type + value type selector - fits into a byte (bit 5 currently unassigned)
+ namespace Type
+ {
+ enum Type
+ {
+ // Primitive Data Type is stored in bits 0-4 (bit 3 currently unused)
+ // base data types
+ value_any, // = 0
+ value_string, // = 1
+ value_boolean, // = 2
+ value_short, // = 3
+ value_int, // = 4
+ value_long, // = 5
+ value_double, // = 6
+ value_binary, // = 7
+
+ mask_basetype = 0x0F,
+
+ // sequence data types
+ flag_sequence = 0x10,
+
+ value_invalid = value_any | flag_sequence,
+
+ value_string_list = value_string | flag_sequence,
+ value_boolean_list = value_boolean | flag_sequence,
+ value_short_list = value_short | flag_sequence,
+ value_int_list = value_int | flag_sequence,
+ value_long_list = value_long | flag_sequence,
+ value_double_list = value_double | flag_sequence,
+ value_binary_list = value_binary | flag_sequence,
+
+ mask_valuetype = mask_basetype | flag_sequence, // 0x1F
+
+ // Node Type is stored in bits 6+7
+ nodetype_shift_ = 6,
+ mask_nodetype = 0x03 << nodetype_shift_, // 0xC0
+
+ // maybe we should use 0 for node type 'value'
+ // to make the complete type be the valuetype ?
+ nodetype_invalid= 0x00,
+
+ nodetype_value = 0x01 << nodetype_shift_, // 0x40
+ nodetype_group = 0x02 << nodetype_shift_, // 0x80
+ nodetype_set = 0x03 << nodetype_shift_, // 0xC0
+
+ flag_innernode = 0x02 << nodetype_shift_, // 0x80
+ flag_setnode = 0x01 << nodetype_shift_ // 0x40
+ };
+ }
+
+ //-----------------------------------------------------------------------------
+ // node attributes
+ namespace Flags
+ {
+ enum Type
+ {
+ readonly = 0x01,
+ finalized = 0x02,
+
+ nullable = 0x04,
+ localized = 0x08,
+
+ valueAvailable = 0x10, // only used for value nodes
+ defaultAvailable = 0x20, // only used for value nodes
+
+ defaulted = 0x40, // somewhat redundant with State
+ defaultable = 0x80 // redundant with State (merged || defaulted)
+ };
+ }
+ //-----------------------------------------------------------------------------
+ // set element or tree state
+ namespace State
+ {
+ enum Type
+ {
+ merged, // = 0, - result of merging defaults + changes
+ defaulted, // = 1, - result of copying defaults unchanged
+ replaced, // = 2, - result of copying new layer unchanged
+ added, // = 3, - same as 'replaced', but it is known,
+ // that there is no corresponding default
+
+ mask_state = 0x0F, // leaves bits 3+4 reserved for states
+
+ flag_mandatory = 0x10, // marks this element as non-removable/replacable
+ flag_readonly = 0x20, // marks this element as read-only
+ flag_default_avail = 0x40, // marks this element as containing default values
+ flag_removable = 0x80 // marks this element as removable
+ };
+ }
+ //-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
+#endif // INCLUDED_DATA_FLAGS_HXX
diff --git a/configmgr/source/inc/interactionrequest.hxx b/configmgr/source/inc/interactionrequest.hxx
new file mode 100644
index 000000000000..55947fb72519
--- /dev/null
+++ b/configmgr/source/inc/interactionrequest.hxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: interactionrequest.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_INTERACTIONREQUEST_HXX
+#define CONFIGMGR_INTERACTIONREQUEST_HXX
+
+#include <com/sun/star/task/XInteractionRequest.hpp>
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/task/XInteractionRetry.hpp>
+#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionDisapprove.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+namespace configmgr {
+namespace apihelper {
+ namespace uno = com::sun::star::uno;
+ namespace task = com::sun::star::task;
+//============================================================================
+
+/**
+ * This class implements the interface XInteractionRequest. Instances can
+ * be passed directly to XInteractionHandler::handle(...). Each interaction
+ * request contains an exception describing the error and a number of
+ * interaction continuations describing the possible "answers" for the request.
+ * After the request was passed to XInteractionHandler::handle(...) the method
+ * getSelection() returns the continuation choosen by the interaction handler.
+ *
+ * The typical usage of this class would be:
+ *
+ * 1) Create exception object that shall be handled by the interaction handler.
+ * 2) Create InteractionRequest, supply exception as ctor parameter
+ * 3) Create continuations needed and add them to a sequence
+ * 4) Supply the continuations to the InteractionRequest by calling
+ * setContinuations(...)
+ *
+ * This class can also be used as base class for more specialized requests,
+ * like authentication requests.
+ */
+class InteractionRequest : public cppu::WeakImplHelper1<com::sun::star::task::XInteractionRequest>
+{
+ struct Impl;
+ Impl * m_pImpl;
+
+protected:
+ virtual ~InteractionRequest();
+public:
+ /**
+ * Constructor.
+ *
+ * @param rRequest is the exception describing the error.
+ */
+ InteractionRequest( const com::sun::star::uno::Any & rRequest );
+
+ /**
+ * This method sets the continuations for the request.
+ *
+ * @param rContinuations contains the possible continuations.
+ */
+ void setContinuations(
+ const uno::Sequence< uno::Reference< task::XInteractionContinuation > > &
+ rContinuations );
+
+ // XInteractionRequest
+ virtual uno::Any SAL_CALL
+ getRequest()
+ throw( uno::RuntimeException );
+
+ virtual uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL
+ getContinuations()
+ throw( com::sun::star::uno::RuntimeException );
+
+ // Non-interface methods.
+
+ /**
+ * After passing this request to XInteractionHandler::handle, this method
+ * returns the continuation that was choosen by the interaction handler.
+ *
+ * @return the continuation choosen by an interaction handler or an empty
+ * reference, if the request was not (yet) handled.
+ */
+ uno::Reference< task::XInteractionContinuation > getSelection() const;
+
+ /**
+ * This method sets a continuation for the request. It also can be used
+ * to reset the continuation set by a previous XInteractionHandler::handle
+ * call in order to use this request object more then once.
+ *
+ * @param rxSelection is the interaction continuation to activate for
+ * the request or an empty reference in order to reset the
+ * current selection.
+ */
+ void setSelection(
+ const uno::Reference< task::XInteractionContinuation > & rxSelection );
+};
+
+//============================================================================
+
+/**
+ * This template class implements a simple standard interaction continuation
+ * interface provided as template parameter. Classes instantiated from this
+ * template work together with class InteractionRequest.
+ * Instances of such a class can be passed along with an interaction request
+ * to indicate the possiblity to continue the operation that caused the request
+ * as indicated by the interface.
+ */
+template <class XThisContinuation >
+class InteractionContinuation : public cppu::WeakImplHelper1< XThisContinuation >
+{
+ InteractionRequest * m_pRequest;
+public:
+ InteractionContinuation( InteractionRequest * pRequest )
+ : m_pRequest( pRequest ) {}
+
+ // XInteractionContinuation
+ /**
+ * This method marks this continuation as "selected" at the request it
+ * belongs to.
+ *
+ * Derived classes must implement their XInteractionContinuation::select()
+ * method the way that they call this method.
+ */
+ virtual void SAL_CALL select()
+ throw( com::sun::star::uno::RuntimeException );
+};
+//============================================================================
+
+template <class XThisContinuation >
+void SAL_CALL InteractionContinuation< XThisContinuation >::select()
+ throw( com::sun::star::uno::RuntimeException )
+{
+ m_pRequest->setSelection(this);
+}
+//============================================================================
+
+
+} // namespace apihelper
+} // namespace configmgr
+
+#endif /* !CONFIGMGR_INTERACTIONREQUEST_HXX */
diff --git a/configmgr/source/inc/localizedtreeactions.hxx b/configmgr/source/inc/localizedtreeactions.hxx
new file mode 100644
index 000000000000..b0d009d9206c
--- /dev/null
+++ b/configmgr/source/inc/localizedtreeactions.hxx
@@ -0,0 +1,55 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localizedtreeactions.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALIZEDTREEACTIONS_HXX
+#define CONFIGMGR_LOCALIZEDTREEACTIONS_HXX
+
+#include "valuenode.hxx"
+#include "treesegment.hxx"
+//..........................................................................
+namespace configmgr
+{
+class SubtreeChange;
+
+//==========================================================================
+// Helper function to invoke the previous ones properly
+
+// convert to the given locale format, assuming the original representation was expanded
+rtl::Reference< data::TreeSegment > cloneExpandedForLocale(sharable::TreeFragment * tree, rtl::OUString const& _sLocale);
+// convert to the given locale format, assuming the original representation was expanded
+std::auto_ptr<INode> reduceExpandedForLocale(std::auto_ptr<ISubtree> _pNode, rtl::OUString const& _sLocale);
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+#endif // CONFIGMGR_LOCALIZEDTREEACTIONS_HXX
+
+
diff --git a/configmgr/source/inc/logger.hxx b/configmgr/source/inc/logger.hxx
new file mode 100644
index 000000000000..7054214dfd0e
--- /dev/null
+++ b/configmgr/source/inc/logger.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: logger.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOGGER_HXX
+#define CONFIGMGR_LOGGER_HXX
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/util/logging/XLogger.hpp>
+#include <com/sun/star/util/logging/LogLevel.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace uno = com::sun::star::uno;
+ namespace logging = com::sun::star::util::logging;
+ namespace LogLevel = logging::LogLevel;
+
+ /// class providing access to a log output sink in the context
+ class Logger
+ {
+ uno::Reference< logging::XLogger > m_xLogger;
+ public:
+ Logger() : m_xLogger() {}
+
+ Logger(uno::Reference< logging::XLogger > const & xLogger)
+ : m_xLogger(xLogger)
+ {}
+
+ explicit
+ Logger(uno::Reference< uno::XComponentContext > const & xContext)
+ : m_xLogger( getUnoLoggerFromContext(xContext) )
+ {}
+
+ sal_Int32 level() const
+ { return m_xLogger.is() ? m_xLogger->getLevel() : LogLevel::OFF; }
+
+ bool isLogging(sal_Int32 nLogLevel) const
+ { return m_xLogger.is() && m_xLogger->isLoggable(nLogLevel); }
+
+ /// log output to the logger
+ void log(sal_Int32 nLevel, const rtl::OUString & msg, const char * sourceMethod = 0, const char * sourceClass = 0) const;
+ void log(sal_Int32 nLevel, const char * msg, const char * sourceMethod = 0, const char * sourceClass = 0) const;
+
+ void error(const rtl::OUString & msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::SEVERE, msg, sourceMethod, sourceClass); }
+ void error(const char * msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::SEVERE, msg, sourceMethod, sourceClass); }
+
+ void warning(const rtl::OUString & msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::WARNING, msg, sourceMethod, sourceClass); }
+ void warning(const char * msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::WARNING, msg, sourceMethod, sourceClass); }
+
+ void info(const rtl::OUString & msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::INFO, msg, sourceMethod, sourceClass); }
+ void info(const char * msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::INFO, msg, sourceMethod, sourceClass); }
+
+ void config(const rtl::OUString & msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::CONFIG, msg, sourceMethod, sourceClass); }
+ void config(const char * msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::CONFIG, msg, sourceMethod, sourceClass); }
+
+ void fine(const rtl::OUString & msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::FINE, msg, sourceMethod, sourceClass); }
+ void fine(const char * msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::FINE, msg, sourceMethod, sourceClass); }
+
+ void finer(const rtl::OUString & msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::FINER, msg, sourceMethod, sourceClass); }
+ void finer(const char * msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::FINER, msg, sourceMethod, sourceClass); }
+
+ void finest(const rtl::OUString & msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::FINEST, msg, sourceMethod, sourceClass); }
+ void finest(const char * msg, const char * sourceMethod = 0, const char * sourceClass = 0) const
+ { log( LogLevel::FINEST, msg, sourceMethod, sourceClass); }
+
+ uno::Reference< logging::XLogger > getUnoLogger() const { return m_xLogger; }
+
+ static
+ uno::Reference< logging::XLogger >
+ getUnoLoggerFromContext(uno::Reference< uno::XComponentContext > const & xContext);
+ };
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif // CONFIGMGR_LOGGER_HXX
+
diff --git a/configmgr/source/inc/matchlocale.hxx b/configmgr/source/inc/matchlocale.hxx
new file mode 100644
index 000000000000..328f21daf420
--- /dev/null
+++ b/configmgr/source/inc/matchlocale.hxx
@@ -0,0 +1,218 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: matchlocale.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */
+
+#ifndef CONFIGMGR_MATCHLOCALE_HXX
+#define CONFIGMGR_MATCHLOCALE_HXX
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+
+#include <rtl/ustring.hxx>
+#include <vector>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+
+ namespace localehelper
+ {
+ // -------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ // -------------------------------------------------------------------------
+ extern char const * const c_sAnyLanguage;
+ extern char const * const c_sDefLanguage;
+
+ extern bool isAnyLanguage(rtl::OUString const & _sLanguage);
+ extern bool isDefaultLanguage(rtl::OUString const & _sLanguage);
+
+ extern rtl::OUString getAnyLanguage();
+ extern rtl::OUString getDefaultLanguage();
+
+ extern com::sun::star::lang::Locale getAnyLocale();
+ extern com::sun::star::lang::Locale getDefaultLocale();
+
+ // -------------------------------------------------------------------------
+ // the max value of std::vector< com::sun::star::lang::Locale >::size_type - marks out-of-range (Value == -1 == ~0)
+ std::vector< com::sun::star::lang::Locale >::size_type const c_noPosition = std::vector< com::sun::star::lang::Locale >::size_type(0)-std::vector< com::sun::star::lang::Locale >::size_type(1);
+
+ // conversion helpers
+ com::sun::star::lang::Locale makeLocale(rtl::OUString const& sLocaleName_);
+ rtl::OUString makeIsoLocale(com::sun::star::lang::Locale const& aUnoLocale_);
+
+ std::vector< com::sun::star::lang::Locale > makeLocaleSequence(uno::Sequence<rtl::OUString> const& sLocaleNames_);
+ uno::Sequence<rtl::OUString> makeIsoSequence(std::vector< com::sun::star::lang::Locale > const& aLocales_);
+
+ inline
+ bool equalLocale(com::sun::star::lang::Locale const & lhs, com::sun::star::lang::Locale const & rhs)
+ { return lhs.Language == rhs.Language && lhs.Country == rhs.Country; }
+
+ inline
+ bool equalLanguage(com::sun::star::lang::Locale const & lhs, com::sun::star::lang::Locale const & rhs)
+ { return lhs.Language == rhs.Language; }
+ // -------------------------------------------------------------------------
+ bool designatesAllLocales(com::sun::star::lang::Locale const& aLocale_);
+ bool designatesAllLocales(std::vector< com::sun::star::lang::Locale > const& aLocales_);
+ // -------------------------------------------------------------------------
+
+ /// result of matching a locale against a target locale
+ enum MatchQuality
+ {
+ MISMATCH = 0, /// match: locales do not match (must be zero!)
+ MATCH_LANGUAGE, /// match: languages match - country mismatch
+ MATCH_LANGUAGE_PLAIN, /// match: languages match - no country to match
+ MATCH_LOCALE, /// match: full match
+ BEST_MATCH = MATCH_LOCALE
+ };
+
+ /// compare two locales for 'nearness'
+ MatchQuality match(com::sun::star::lang::Locale const& aLocale_, com::sun::star::lang::Locale const& aTarget_);
+
+
+ // -------------------------------------------------------------------------
+ /// result of matching a Locale against a target sequence of locales
+ class MatchResult
+ {
+ std::vector< com::sun::star::lang::Locale >::size_type m_nPos;
+ MatchQuality m_eQuality;
+
+ public:
+ /// construct a default (no match) result
+ MatchResult()
+ { reset(); }
+
+ /// construct a result from given parameters - use with care
+ MatchResult(std::vector< com::sun::star::lang::Locale >::size_type nPos_, MatchQuality eQuality_)
+ : m_nPos( nPos_ )
+ , m_eQuality(eQuality_)
+ {}
+
+ /// construct an optimum result
+ static MatchResult best() { return MatchResult(0,MATCH_LOCALE); }
+
+ /// has there been a match
+ bool isMatch() const { return m_eQuality != MISMATCH; }
+ /// is this the best match possible ?
+ bool isBest() const { return m_nPos == 0 && m_eQuality == MATCH_LOCALE; }
+
+ /// retrieve the position that was matched
+ std::vector< com::sun::star::lang::Locale >::size_type position() const { return m_nPos; }
+ /// retrieve the quality of match
+ MatchQuality quality() const { return m_eQuality; }
+
+ /// assign the given position and quality, if they are an improvement
+ bool improve(std::vector< com::sun::star::lang::Locale >::size_type nPos, MatchQuality eQuality_);
+
+ /// reset to no match or best match state
+ void reset()
+ {
+ m_nPos = c_noPosition;
+ m_eQuality = MISMATCH;
+ }
+
+ // ---------------------------------------------------------------------
+ // comparing MatchResults
+ friend bool operator ==(MatchResult const& lhs, MatchResult const& rhs)
+ {
+ return lhs.m_nPos == rhs.m_nPos &&
+ lhs.m_eQuality == rhs.m_eQuality;
+ }
+
+ // ordering of MatchResults - greater is better
+ friend bool operator < (MatchResult const& lhs, MatchResult const& rhs)
+ {
+ if (lhs.m_nPos > rhs.m_nPos) return true; // greater position is worse
+ if (lhs.m_nPos < rhs.m_nPos) return false;
+
+ return (lhs.m_eQuality < rhs.m_eQuality); // least Quality is worse
+ }
+
+ };
+
+ // ---------------------------------------------------------------------
+ // derived relational operators
+ inline bool operator !=(MatchResult const& lhs, MatchResult const& rhs)
+ { return !(lhs == rhs); }
+ inline bool operator > (MatchResult const& lhs, MatchResult const& rhs)
+ { return rhs < lhs; }
+ inline bool operator <= (MatchResult const& lhs, MatchResult const& rhs)
+ { return !(rhs < lhs); }
+ inline bool operator >=(MatchResult const& lhs, MatchResult const& rhs)
+ { return !(lhs < rhs); }
+
+ /// improve an existing match of a locale against a sequence of locales
+ bool improveMatch(MatchResult& rMatch_, com::sun::star::lang::Locale const& aLocale_, std::vector< com::sun::star::lang::Locale > const& aTarget_);
+
+ /// match a locale against a sequence of locales for a given quality level
+ bool isMatch(com::sun::star::lang::Locale const& aLocales, std::vector< com::sun::star::lang::Locale > const& aTarget_, MatchQuality eRequiredQuality_);
+
+ // -------------------------------------------------------------------------
+ /// add defaults to a sequence of locales
+ void addFallbackLocales(std::vector< com::sun::star::lang::Locale >& aTargetList_);
+
+ // -------------------------------------------------------------------------
+ class FindBestLocale
+ {
+ public:
+ /// construct a MatchLocale with a single target locale
+ FindBestLocale(com::sun::star::lang::Locale const& aTarget_);
+
+ /// is there any match ?
+ bool isMatch() const { return m_aResult.isMatch(); }
+
+ /// is there an optimum match (so we are done) ?
+ bool isBestMatch() const { return m_aResult.isBest(); }
+
+ /// get the quality of the best match found
+ MatchQuality getMatchQuality() const { return m_aResult.quality(); }
+
+ /// check, if the given locale improves the quality. if it does, accept it
+ bool accept(com::sun::star::lang::Locale const& aLocale_);
+
+ /// reset the match result, indicating whether a match is needed at all
+ void reset(bool bNeedLocale_ = true);
+
+ private:
+ void implSetTarget(std::vector< com::sun::star::lang::Locale > const& aTarget_);
+
+ std::vector< com::sun::star::lang::Locale > m_aTarget;
+ MatchResult m_aResult;
+ };
+
+ } // namespace
+// -----------------------------------------------------------------------------
+
+} // namespace
+
+#endif
+
diff --git a/configmgr/source/inc/mergechange.hxx b/configmgr/source/inc/mergechange.hxx
new file mode 100644
index 000000000000..2282a484907f
--- /dev/null
+++ b/configmgr/source/inc/mergechange.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mergechange.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_CONFIGMGR_MERGECHANGE_HXX
+#define INCLUDED_CONFIGMGR_MERGECHANGE_HXX
+
+#include "namecreator.hxx"
+#include "change.hxx"
+#include "treechangelist.hxx"
+
+namespace configmgr
+{
+ // method that applies changes on a existing subtree
+ void combineUpdates (SubtreeChange const& _anUpdate, SubtreeChange& _aCombinedUpdate);
+
+ // -----------------------------------------------------------------------------
+ class OStripDefaults : private ChangeTreeModification
+ {
+ SubtreeChange& m_rParent;
+ public:
+ OStripDefaults(SubtreeChange& _rSubtree) : m_rParent(_rSubtree) {}
+
+ bool isEmpty() const { return m_rParent.size() == 0; }
+
+ OStripDefaults& strip();
+
+ static bool strip(SubtreeChange& _rSubtree)
+ {
+ return OStripDefaults(_rSubtree).strip().isEmpty();
+ }
+ private:
+ void stripOne(Change& _rChange);
+
+ virtual void handle(ValueChange& _rValueNode);
+ virtual void handle(AddNode& _rAddNode);
+ virtual void handle(RemoveNode& _rRemoveNode);
+ virtual void handle(SubtreeChange& _rSubtree);
+ };
+
+ // -----------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/inc/mergeddataprovider.hxx b/configmgr/source/inc/mergeddataprovider.hxx
new file mode 100644
index 000000000000..73480dced561
--- /dev/null
+++ b/configmgr/source/inc/mergeddataprovider.hxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mergeddataprovider.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_MERGEDDATAPROVIDER_HXX
+#define CONFIGMGR_BACKEND_MERGEDDATAPROVIDER_HXX
+
+#include "sal/config.h"
+
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "request.hxx"
+#include "requesttypes.hxx"
+#include "utility.hxx"
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+ namespace backend
+ {
+// ---------------------------------------------------------------------------
+ /** Listener interface for receiving notifications
+ about changes to previously requested data
+ */
+ struct SAL_NO_VTABLE INodeDataListener
+ {
+ /** is called to indicate changes within the data being observed.
+
+ @param _aOriginalRequest
+ identifies the data that changed
+ */
+ virtual void dataChanged(ComponentRequest const & _aOriginalRequest) SAL_THROW(()) = 0;
+ };
+// ---------------------------------------------------------------------------
+
+ /// Interface providing access to template (schema) data
+ struct SAL_NO_VTABLE ITemplateDataProvider
+ {
+ /** loads a given template and returns it as return value
+
+ @param _aRequest
+ identifies the template to be loaded
+
+ @returns
+ A valid instance of the given template.
+
+ <p> Currently a request with empty template name
+ will retrieve a group node holding all templates
+ of a component.
+ </p>
+
+ @throws com::sun::star::uno::Exception
+ if the template cannot be retrieved.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ virtual ResultHolder< TemplateInstance > getTemplateData(TemplateRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception)) = 0;
+ };
+// ---------------------------------------------------------------------------
+
+ /** Composite interface providing full access to merged configuration data
+ from some data store.
+
+ <p> Loading and updating of data is supported.
+ Support for notification depends on the backend.
+ </p>
+ */
+ struct IMergedDataProvider
+ : salhelper::SimpleReferenceObject
+ , ITemplateDataProvider
+ {
+ /** loads merged data for a (partial) tree and returns it as return value.
+
+ @param _aRequest
+ identifies the component to be loaded
+
+ @param _pListener
+ a listener to observe subsequent changes to the data requested
+
+ <p> If NULL, no notifications will be sent. </p>
+
+ <p> Otherwise the listener will be notified of changes.
+ The listener must subsequently be removed by calling
+ <member>removeRequestListener</member>.
+ The listener must live at least until it is removed.
+ </p>
+
+ @returns
+ A valid component instance for the given request.
+
+ @throws com::sun::star::uno::Exception
+ if the node cannot be retrieved.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ virtual ResultHolder< ComponentInstance > getNodeData(ComponentRequest const & _aRequest,
+ ITemplateDataProvider* _aTemplateProvider,
+ INodeDataListener * _pListener = NULL)
+ SAL_THROW((com::sun::star::uno::Exception)) = 0;
+
+ /** remove a listener registered for a previous request.
+ <p>This may also release some open resources for the request.</p>
+
+ @param _pListener
+ a listener that was passed to a previous succes
+
+ @param _aRequest
+ identifies the component associated with the listener
+ */
+ virtual void removeRequestListener(INodeDataListener * _pListener,
+ const ComponentRequest& aRequest) SAL_THROW(()) = 0;
+
+ /** applies an update to the stored data.
+
+ @param _anUpdate
+ identifies the node to be updated and
+ describes the changes to be applied.
+
+ @throws com::sun::star::uno::Exception
+ if the node cannot be updated.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ virtual void updateNodeData(UpdateRequest const & _anUpdate)
+ SAL_THROW((com::sun::star::uno::Exception)) = 0;
+
+ /** loads default data for a (partial) tree and returns it as return value
+
+ @param _aRequest
+ identifies the node to be loaded
+
+ @returns
+ A valid node instance for the default state of the given node.
+
+ <p>May be NULL, if the node exists but has no default equivalent.</p>
+
+ @throws com::sun::star::uno::Exception
+ if the default cannot be retrieved.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ virtual ResultHolder< NodeInstance > getDefaultData(NodeRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception)) = 0;
+ };
+
+// ---------------------------------------------------------------------------
+ } // namespace backend
+
+// ---------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/inc/namecreator.hxx b/configmgr/source/inc/namecreator.hxx
new file mode 100644
index 000000000000..e09e0ab36625
--- /dev/null
+++ b/configmgr/source/inc/namecreator.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: namecreator.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_CONFIGMGR_NAMECREATOR_HXX
+#define INCLUDED_CONFIGMGR_NAMECREATOR_HXX
+
+#include "configpath.hxx"
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ class Change;
+ class SubtreeChange;
+ // -----------------------------------------------------------------------------
+
+ class ONameCreator
+ {
+ public:
+ ONameCreator() {}
+
+ void pushName(const configuration::Path::Component &_aName) { m_aNameList.push_back(_aName); }
+ void popName() { m_aNameList.pop_back(); }
+
+ void clear() { m_aNameList.clear(); }
+
+ static configuration::Path::Component createName(Change const& _rChange, SubtreeChange const* _pParent);
+ private:
+ std::vector< configuration::Path::Component > m_aNameList;
+ };
+
+ template <class PathClass>
+ class OPathCreator : public ONameCreator
+ {
+ public:
+ OPathCreator() : m_aBasePath( configuration::Path::Rep() ) {}
+ OPathCreator(PathClass const & _aBasePath) : m_aBasePath(_aBasePath) {}
+
+ void init(PathClass const & _aBasePath)
+ { clear(); m_aBasePath = _aBasePath; }
+
+ private:
+ PathClass m_aBasePath;
+ };
+ // -----------------------------------------------------------------------------
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/inc/node.hxx b/configmgr/source/inc/node.hxx
new file mode 100644
index 000000000000..604bc7390619
--- /dev/null
+++ b/configmgr/source/inc/node.hxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: node.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_SHARABLE_NODE_HXX
+#define INCLUDED_SHARABLE_NODE_HXX
+
+#include "rtl/ustring.hxx"
+
+#include "flags.hxx"
+#include "anydata.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace node { struct Attributes; }
+//-----------------------------------------------------------------------------
+ namespace sharable
+ {
+ struct TreeFragment;
+ union Node;
+ //-----------------------------------------------------------------------------
+ struct NodeInfo
+ {
+ rtl_uString * name;
+ sal_uInt16 parent; // always counts backwards
+ sal_uInt8 flags;
+ sal_uInt8 type; // contains discriminator for union
+
+ rtl::OUString getName() const;
+ node::Attributes getNodeInfoAttributes() const;
+ bool isDefault() const;
+ bool isLocalized() const;
+
+ void markAsDefault(bool bDefault = true);
+ };
+ //-----------------------------------------------------------------------------
+ struct GroupNode
+ {
+ NodeInfo info;
+ sal_uInt16 numDescendants; // = number of descendants
+
+ bool hasDefaultsAvailable() const;
+
+ Node * getFirstChild() const;
+ Node * getNextChild(Node * child) const;
+ Node * getChild(rtl::OUString const & name) const;
+
+ static inline GroupNode * from(Node * node);
+ };
+ //-----------------------------------------------------------------------------
+ struct SetNode
+ {
+
+ NodeInfo info;
+ sal_uInt8 * elementType; // points to template [MM:SetNode *?]
+ TreeFragment * elements; // points to first element (TreeFragmentHeader)
+
+ rtl::OUString getElementTemplateName() const;
+ rtl::OUString getElementTemplateModule() const;
+
+ TreeFragment * getFirstElement() const;
+ TreeFragment * getNextElement(TreeFragment * _pElement) const;
+ TreeFragment * getElement(rtl::OUString const & name) const;
+
+ void addElement(TreeFragment * newElement);
+ TreeFragment * removeElement(rtl::OUString const & name);
+
+ static inline SetNode * from(Node * node);
+
+ // low-level helper for template data abstraction
+ static
+ sal_uInt8 * allocTemplateData(const rtl::OUString &rName,
+ const rtl::OUString &rModule);
+ static
+ sal_uInt8 * copyTemplateData(sal_uInt8 * _aTemplateData);
+ static
+ void releaseTemplateData(sal_uInt8 * _aTemplateData);
+ };
+ //-----------------------------------------------------------------------------
+ struct ValueNode
+ {
+ NodeInfo info;
+ AnyData value;
+ AnyData defaultValue;
+
+ bool isNull() const;
+ bool hasUsableDefault() const;
+
+ com::sun::star::uno::Any getValue() const;
+ com::sun::star::uno::Type getValueType() const;
+ com::sun::star::uno::Any getUserValue() const;
+ com::sun::star::uno::Any getDefaultValue() const;
+
+ void setValue(com::sun::star::uno::Any const & newValue);
+ void setToDefault();
+ void changeDefault(com::sun::star::uno::Any const & newDefault);
+
+ static inline ValueNode * from(Node * node);
+
+ private:
+ void releaseValue();
+ sal_uInt8 adaptType(com::sun::star::uno::Any const & newValue);
+ };
+ //-----------------------------------------------------------------------------
+ // TODO: optimized representation of localized values (now as set; mapping locale->element-name)
+ // TODO (?): better representation of sets of values
+ //-----------------------------------------------------------------------------
+ union Node
+ {
+ NodeInfo info;
+ GroupNode group;
+ SetNode set;
+ ValueNode value;
+
+ // info access
+ bool isNamed(rtl::OUString const & _aName) const;
+ rtl::OUString getName() const;
+ node::Attributes getAttributes() const;
+ bool isDefault() const;
+
+ // type checks
+ bool isGroup() const { return typeIs (data::Type::nodetype_group); }
+ bool isSet() const { return typeIs (data::Type::nodetype_set); }
+ bool isValue() const { return typeIs (data::Type::nodetype_value); }
+
+ // checked access
+ inline GroupNode * groupData();
+ inline GroupNode const * groupData() const;
+ inline SetNode * setData();
+ inline SetNode const * setData() const;
+ inline ValueNode * valueData();
+ inline ValueNode const * valueData() const;
+
+ // navigation
+ bool isFragmentRoot() const;
+#if OSL_DEBUG_LEVEL > 0
+ Node * getParentNode();
+ Node const * getParentNode() const;
+#endif
+ TreeFragment * getTreeFragment();
+ TreeFragment const * getTreeFragment() const;
+
+ Node * getSubnode(rtl::OUString const & name);
+
+ private:
+ bool typeIs(data::Type::Type eType) const
+ { return (info.type & data::Type::mask_nodetype) == eType; }
+ };
+
+ //-----------------------------------------------------------------------------
+ inline GroupNode * GroupNode::from(Node * node)
+ { return node == 0 ? 0 : node->groupData(); }
+
+ inline SetNode * SetNode::from(Node * node)
+ { return node == 0 ? 0 : node->setData(); }
+
+ inline ValueNode * ValueNode::from(Node * node)
+ { return node == 0 ? 0 : node->valueData(); }
+
+ inline GroupNode * Node::groupData()
+ { return isGroup() ? &this->group : NULL; }
+ inline GroupNode const * Node::groupData() const
+ { return isGroup() ? &this->group : NULL; }
+ inline SetNode * Node::setData()
+ { return isSet() ? &this->set : NULL; }
+ inline SetNode const * Node::setData() const
+ { return isSet() ? &this->set : NULL; }
+ inline ValueNode * Node::valueData()
+ { return isValue() ? &this->value : NULL; }
+ inline ValueNode const * Node::valueData() const
+ { return isValue() ? &this->value : NULL; }
+
+ inline Node * node(ValueNode * pNode)
+ { return reinterpret_cast<Node*>(pNode); }
+ inline Node * node(GroupNode * pNode)
+ { return reinterpret_cast<Node*>(pNode); }
+ inline Node * node(SetNode * pNode)
+ { return reinterpret_cast<Node*>(pNode); }
+
+ inline Node const * node(ValueNode const* pNode)
+ { return reinterpret_cast<Node const*>(pNode); }
+ inline Node const * node(GroupNode const* pNode)
+ { return reinterpret_cast<Node const*>(pNode); }
+ inline Node const * node(SetNode const* pNode)
+ { return reinterpret_cast<Node const*>(pNode); }
+ //-----------------------------------------------------------------------------
+ inline Node & node(ValueNode & pNode)
+ { return reinterpret_cast<Node&>(pNode); }
+ inline Node & node(GroupNode & pNode)
+ { return reinterpret_cast<Node&>(pNode); }
+ inline Node & node(SetNode & pNode)
+ { return reinterpret_cast<Node&>(pNode); }
+
+ inline Node const & node(ValueNode const& pNode)
+ { return reinterpret_cast<Node const&>(pNode); }
+ inline Node const & node(GroupNode const& pNode)
+ { return reinterpret_cast<Node const&>(pNode); }
+ inline Node const & node(SetNode const& pNode)
+ { return reinterpret_cast<Node const&>(pNode); }
+ //-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
+#endif // INCLUDED_SHARABLE_NODE_HXX
diff --git a/configmgr/source/inc/nodechange.hxx b/configmgr/source/inc/nodechange.hxx
new file mode 100644
index 000000000000..dfb630d88dda
--- /dev/null
+++ b/configmgr/source/inc/nodechange.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodechange.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGCHANGE_HXX_
+#define CONFIGMGR_CONFIGCHANGE_HXX_
+
+#include "rtl/ref.hxx"
+
+#include "configexcept.hxx"
+
+#include <vector>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ class AbsolutePath;
+ class RelativePath;
+ class NodeRef;
+ class NodeID;
+ class SubNodeID;
+ class Tree;
+//-----------------------------------------------------------------------------
+
+ class NodeChange;
+ class NodeChangeImpl;
+ class NodeChangeLocation;
+ class NodeChangeInformation;
+ class NodeChangesInformation;
+//-----------------------------------------------------------------------------
+
+ /// represents a node position in some tree
+ class NodeChange
+ {
+ public:
+ /// constructs an empty (unchanging) node change
+ NodeChange();
+ /// constructs a node change with a given implementation
+ NodeChange(NodeChangeImpl* pImpl);
+ /// copies a node change with reference semantics
+ NodeChange(NodeChange const& rOther);
+ /// copies a node change with reference semantics
+ NodeChange& operator=(NodeChange const& rOther);
+ /// swaps the contents of this with another NodeChange
+ void swap(NodeChange& rOther);
+ /// destroys a node change
+ ~NodeChange();
+
+ /// checks, if this may represent an actual change (might not be tested)
+ bool maybeChange() const;
+ /// checks, if this represents an actual change (PRE: must be tested)
+ bool isChange() const;
+ /// retrieve information about the changed data, appending to a sequence, returning the count
+ sal_uInt32 getChangeInfos(NodeChangesInformation& rInfo) const;
+ /// retrieve information about what node is changed
+ bool getChangeLocation(NodeChangeLocation& rLoc) const;
+
+ /// test whether this would really be a change (as close as possible)
+ NodeChange& test();
+ NodeChange const& test() const;
+
+ /// apply this change and check whether the target node changed
+ NodeChange& apply();
+ NodeChange const& apply() const;
+
+ // retrieve the tree where the change is actually taking place
+ rtl::Reference< Tree > getAffectedTree() const;
+ // retrieve the node where the change is actually taking place
+ NodeRef getAffectedNode() const;
+
+ // Comparison
+ friend bool operator==(NodeChange const& lhs, NodeChange const& rhs)
+ {
+ return lhs.m_pImpl == rhs.m_pImpl;
+ }
+ friend bool operator!=(NodeChange const& lhs, NodeChange const& rhs)
+ {
+ return lhs.m_pImpl != rhs.m_pImpl;
+ }
+
+ /// provides access to the internal Implementation for related classes
+ NodeChangeImpl* impl() const { return m_pImpl; }
+ private:
+ NodeChangeImpl* m_pImpl;
+ void init(), deinit();
+ };
+
+ /** represents a collection of updates to nodes (identified by <type>NodeChange</type>s) within a hierarchy of config entries
+ */
+ class NodeChanges
+ {
+ public:
+ /// Constructs an empty collection of changes
+ NodeChanges();
+
+ /// checks whether there are any (non-empty) changes in this
+ bool isEmpty() const;
+
+ /// retrieves the total count of changes in this collection
+ std::vector<NodeChange>::size_type getCount() const { return m_aChanges.size(); }
+
+ /// retrieve information about the changed data, appending to a sequence, returning the count
+ sal_uInt32 getChangesInfos(NodeChangesInformation& rInfos) const;
+
+ /// test all changes
+ NodeChanges& test() { implTest(); return *this; }
+ NodeChanges const& test() const { implTest(); return *this; }
+
+ /// remove all changes known to be doing nothing from this collection.
+ NodeChanges& compact();
+
+ /** insert a change into this collection
+ */
+ void add(NodeChange const& aChange);
+
+ /// returns an STL-style iterator to the first element of the collection
+ std::vector<NodeChange>::const_iterator begin() const { return m_aChanges.begin(); }
+ std::vector<NodeChange>::iterator begin() { return m_aChanges.begin(); }
+
+ /// returns an STL-style iterator to past the last element of the collection
+ std::vector<NodeChange>::const_iterator end() const { return m_aChanges.end(); }
+ std::vector<NodeChange>::iterator end() { return m_aChanges.end(); }
+
+ private:
+ void implTest() const;
+ std::vector<NodeChange> m_aChanges;
+ };
+
+ }
+}
+
+#endif // CONFIGMGR_CONFIGCHANGE_HXX_
diff --git a/configmgr/source/inc/nodechangeinfo.hxx b/configmgr/source/inc/nodechangeinfo.hxx
new file mode 100644
index 000000000000..db838d62d45d
--- /dev/null
+++ b/configmgr/source/inc/nodechangeinfo.hxx
@@ -0,0 +1,249 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodechangeinfo.hxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGCHANGEINFO_HXX_
+#define CONFIGMGR_CONFIGCHANGEINFO_HXX_
+
+#include "configpath.hxx"
+#include "noderef.hxx"
+#include "valueref.hxx"
+#include <rtl/ref.hxx>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ class NodeRef;
+ class ValueRef;
+ class NodeID;
+ class SubNodeID;
+
+ class ElementTree;
+
+//-----------------------------------------------------------------------------
+ /// captures the values of something changing
+ template <class DataT>
+ struct DataChange
+ {
+ DataT newValue;
+ DataT oldValue;
+
+ DataChange()
+ : newValue(), oldValue()
+ {}
+
+ DataChange(DataT const& newValue_, DataT const& oldValue_)
+ : newValue(newValue_), oldValue(oldValue_)
+ {}
+
+ // note: maybe we should support a comparison object
+ bool isDataChange() const
+ { return !(oldValue == newValue); } // not using != to avoid conversion warning
+ };
+
+//-----------------------------------------------------------------------------
+ /// information about what changed (but close to no context)
+ class NodeChangeData
+ {
+ public:
+ //-------------------------------------------------
+ enum Type
+ {
+ eNoChange,
+
+ // Changes to value nodes
+ eSetValue,
+ eSetDefault,
+
+ // Changes to set nodes
+ eInsertElement,
+ eReplaceElement,
+ eRemoveElement,
+
+ eRenameElementTree, // not fully supported yet
+
+ eResetSetDefault
+ };
+ //-------------------------------------------------
+
+ bool isEmptyChange() const { return eNoChange == type; }
+ bool isValueChange() const { return eSetValue <= type && type <= eSetDefault; }
+ bool isSetChange() const { return eInsertElement <= type && type <= eRemoveElement; }
+ bool isRemoveSetChange() const { return eRemoveElement == type;}
+ bool isReplaceSetChange() const { return eReplaceElement == type;}
+ //-------------------------------------------------
+ bool isDataChange() const;
+
+ //-------------------------------------------------
+ // wrapper object creation
+ rtl::Reference< Tree > getNewElementTree() const;
+ rtl::Reference< Tree > getOldElementTree() const;
+
+ NodeID getNewElementNodeID() const;
+ NodeID getOldElementNodeID() const;
+ //-------------------------------------------------
+
+ //-- Compiler barrier for element tree ------------
+ NodeChangeData();
+ NodeChangeData(NodeChangeData const& aOther);
+ NodeChangeData& operator=(NodeChangeData const& aOther);
+ ~NodeChangeData();
+ //-------------------------------------------------
+ Type type;
+
+ // Value change: old/new value; Set change: new/old api element (if known); Rename: old/new name
+ DataChange< com::sun::star::uno::Any > unoData;
+ // Value change: NULL,NULL; Set change: new/old tree element; Rename: the affected element-tree (twice)
+ DataChange< rtl::Reference<ElementTree> > element;
+ //-------------------------------------------------
+ };
+
+ //-------------------------------------------------
+ // Identify the location of a change. Interpretation of members may depend upon
+ class NodeChangeLocation
+ {
+ public:
+ //-------------------------------------------------
+ // checks whether the base has been properly set up.
+ // Does not check for existence of the affected node
+#if OSL_DEBUG_LEVEL > 0
+ /// check whether the location has been initialized properly
+ bool isValidData() const;
+#endif
+ /// check whether the location is for a valid object
+ bool isValidLocation() const;
+
+ //-------------------------------------------------
+ /// retrieve the path from the base node to the changed node (which might be a child of the affected node)
+ RelativePath getAccessor() const { return m_path; }
+
+ /// retrieve the tree where the change is actually initiated/reported
+ rtl::Reference< Tree > getBaseTree() const;
+ /// retrieve the node where the change is actually initiated/reported
+ NodeRef getBaseNode() const;
+
+ /// retrieve the tree where the change is actually taking place (may be Empty, if the tree has never been accessed)
+ rtl::Reference< Tree > getAffectedTreeRef() const;
+ /// identify the node where the change is actually taking place
+ NodeID getAffectedNodeID() const;
+
+ /// identify the node (within the affected tree), that actually is changed (this one may be a value node)
+ SubNodeID getChangingValueID() const;
+
+ //-------------------------------------------------
+ void setAccessor( RelativePath const& aAccessor );
+
+ void setBase( NodeID const& aBaseID );
+ void setBase( rtl::Reference< Tree > const& aBaseTree, NodeRef const& aBaseNode )
+ { setBase( NodeID(aBaseTree,aBaseNode) ); }
+
+ void setAffected( NodeID const& aTargetID );
+ void setAffected( rtl::Reference< Tree > const& aTargetTree, NodeRef const& aTargetNode )
+ { setAffected( NodeID(aTargetTree,aTargetNode) ); }
+
+ void setChangingSubnode( bool bSubnode = true );
+ //-------------------------------------------------
+ NodeChangeLocation();
+ // NodeChangeLocation(NodeChangeLocation const& aOther);
+ // NodeChangeLocation& operator=(NodeChangeLocation const& aOther);
+ // ~NodeChangeLocation();
+ //-------------------------------------------------
+ private:
+ RelativePath m_path; // path from baseNode to changing node
+ NodeID m_base; // a (non-empty) node
+ NodeID m_affected; // identifies the affected node (if available)
+ bool m_bSubNodeChanging; // do we change a value ?
+ //-------------------------------------------------
+ };
+//-----------------------------------------------------------------------------
+ class NodeChangeInformation
+ {
+ public:
+ //-------------------------------------------------
+ explicit
+ NodeChangeInformation()
+ : change()
+ , location()
+ {
+ }
+ //-------------------------------------------------
+ NodeChangeData change;
+ NodeChangeLocation location;
+
+ //-------------------------------------------------
+ bool hasValidLocation() const { return location.isValidLocation(); }
+ bool isDataChange() const { return change.isDataChange(); }
+
+ bool isEmptyChange() const { return change.isEmptyChange(); }
+ bool isValueChange() const { return change.isValueChange(); }
+ bool isSetChange() const { return change.isSetChange(); }
+ //-------------------------------------------------
+ };
+//-----------------------------------------------------------------------------
+
+ class NodeChangesInformation
+ {
+ public:
+ std::vector< NodeChangeInformation >::size_type size() const { return m_data.size(); }
+ bool empty() const { return m_data.empty(); }
+
+ void reserve(std::vector< NodeChangeInformation >::size_type sz_) { m_data.reserve(sz_); }
+ void clear() { m_data.clear(); }
+ void swap(NodeChangesInformation& aOther) throw() { m_data.swap(aOther.m_data); }
+
+ void push_back(NodeChangeInformation const& aChange_)
+ { m_data.push_back(aChange_); }
+
+ std::vector< NodeChangeInformation >::const_iterator begin() const { return m_data.begin(); }
+ std::vector< NodeChangeInformation >::const_iterator end() const { return m_data.end(); }
+ private:
+ std::vector< NodeChangeInformation > m_data;
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#if !defined(WNT) || (defined(WNT) && _MSC_VER < 1400)
+namespace std
+{
+ template <>
+ inline
+ void swap(configmgr::configuration::NodeChangesInformation& lhs, configmgr::configuration::NodeChangesInformation& rhs)
+ { lhs.swap(rhs); }
+}
+#endif
+
+#endif // CONFIGMGR_CONFIGCHANGEINFO_HXX_
diff --git a/configmgr/source/inc/nodeconverter.hxx b/configmgr/source/inc/nodeconverter.hxx
new file mode 100644
index 000000000000..58340c82d259
--- /dev/null
+++ b/configmgr/source/inc/nodeconverter.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodeconverter.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_NODECONVERTER_HXX
+#define CONFIGMGR_NODECONVERTER_HXX
+
+#include "change.hxx"
+
+//..........................................................................
+namespace configmgr
+{
+//..........................................................................
+ class OTreeNodeFactory;
+//..........................................................................
+ class OTreeNodeConverter
+ {
+ OTreeNodeFactory& m_rFactory;
+ public:
+ OTreeNodeConverter();
+ OTreeNodeConverter(OTreeNodeFactory& _rFactory)
+ : m_rFactory(_rFactory) {}
+
+ OTreeNodeFactory& nodeFactory() const { return m_rFactory; }
+ // node conversion functions
+ std::auto_ptr<ISubtree> createCorrespondingNode(SubtreeChange const& _rChange);
+ std::auto_ptr<ValueNode> createCorrespondingNode(ValueChange const& _rChange);
+
+ std::auto_ptr<ISubtree> createCorrespondingTree(SubtreeChange& _rChange);
+ };
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+#endif // CONFIGMGR_NODECONVERTER_HXX
+
+
diff --git a/configmgr/source/inc/noderef.hxx b/configmgr/source/inc/noderef.hxx
new file mode 100644
index 000000000000..351562d63de3
--- /dev/null
+++ b/configmgr/source/inc/noderef.hxx
@@ -0,0 +1,271 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: noderef.hxx,v $
+ * $Revision: 1.21 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGNODE_HXX_
+#define CONFIGMGR_CONFIGNODE_HXX_
+
+#include "rtl/ref.hxx"
+
+#include "configexcept.hxx"
+#include "configpath.hxx"
+#include "tree.hxx"
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace configmgr
+{
+ class INode;
+
+ namespace view { class ViewTreeAccess; }
+ namespace configapi { class Factory; }
+ namespace node { struct Attributes; }
+ namespace configuration
+ {
+ //-------------------------------------------------------------------------
+ class AbsolutePath;
+ class RelativePath;
+ namespace Path { class Component; }
+
+ class NodeChange;
+ class NodeChanges;
+ class NodeRef;
+ class ValueRef;
+ class AnyNodeRef;
+
+ class NodeID;
+
+ const unsigned int C_TreeDepthAll = ~0u;
+ //-------------------------------------------------------------------------
+
+ /// represents a inner node position in some tree
+ class NodeRef
+ {
+ public:
+ /// constructs an empty (invalid) node
+ NodeRef();
+
+ NodeRef(unsigned int nPos, unsigned int nDepth);
+
+ /// copy a node (with reference semantics)
+ NodeRef(NodeRef const& rOther);
+ /// copy a node (with reference semantics)
+ NodeRef& operator=(NodeRef const& rOther);
+
+ void swap(NodeRef& rOther);
+
+ ~NodeRef();
+
+ /// checks, if this represents an existing node
+ inline bool isValid() const;
+
+ /// returns the offset of this Node
+ inline unsigned int getOffset() const;
+
+ /// returns the offset of this Node
+ inline unsigned int getDepth() const;
+
+ private:
+ friend class AnyNodeRef;
+ private:
+ unsigned int m_nPos;
+ unsigned int m_nDepth;
+ };
+ //-------------------------------------------------------------------------
+
+ class NodeID
+ {
+ public:
+ NodeID(rtl::Reference< Tree > const& rTree, NodeRef const& rNode);
+ NodeID(Tree* pImpl, unsigned int nNode);
+
+ // comparison
+ // equality
+ friend bool operator==(NodeID const& lhs, NodeID const& rhs)
+ { return lhs.m_pTree == rhs.m_pTree && lhs.m_nNode == rhs.m_nNode; }
+ // ordering
+ friend bool operator < (NodeID const& lhs, NodeID const& rhs);
+ // checking
+ bool isEmpty() const;
+ // checking
+ bool isValidNode() const;
+ // hashing
+ size_t hashCode() const;
+ // use as index - returns a value in the range 0..rTree.getContainedNodes() for the tree used to construct this
+ unsigned int toIndex() const;
+
+ Tree * getTree() const { return m_pTree; }
+
+ unsigned int getOffset() const { return m_nNode; }
+
+ NodeRef getNode() const;
+
+ private:
+ Tree* m_pTree;
+ unsigned int m_nNode;
+ };
+ //-------------------------------------------------------------------------
+
+ /** make a name out of <var>sName</var>.
+ @throws InvalidName
+ if <var>sName</var> is not a valid name for a member of group <var>aNode</var> within <var>aTree</var>
+
+ */
+ rtl::OUString validateChildName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode );
+
+ /** make a name out of <var>sName</var>.
+ @throws InvalidName
+ if <var>sName</var> is not a valid name for an element of set <var>aNode</var> within <var>aTree</var>
+
+ */
+ rtl::OUString validateElementName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode );
+
+ /** make a name out of <var>sName</var>.
+ @throws InvalidName
+ if <var>sName</var> is not a valid name for a child of <var>aNode</var> within <var>aTree</var>
+
+ */
+ rtl::OUString validateChildOrElementName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode );
+
+ /** make one path component out of <var>sName</var>.
+ @throws InvalidName
+ if <var>sName</var> is not a valid name for an element of set <var>aNode</var> within <var>aTree</var>
+
+ */
+ Path::Component validateElementPathComponent(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode );
+
+ /** parse <var>aPath</var> into a relative path,
+ valid in the context of node <var>aNode<var/> in <var>aTree<var/>.
+
+ @returns
+ <var>aPath<var/> parsed as a relative path
+ @throws InvalidName
+ if <var>aPath<var/> is not a relative path or not valid in the context of <var>aNode<var/>
+ */
+ RelativePath validateRelativePath(rtl::OUString const& aPath, rtl::Reference< Tree > const& aTree, NodeRef const& aNode);
+
+ /** parse <var>aPath</var> as a configuration path
+ and reduce it to be relative to node <var>aNode<var/> in <var>aTree<var/>.
+
+ @returns
+ the result of parsing <var>aPath<var/>, if that results in a relative path, or
+ the part of it relative to <var>aNode<var/>,
+ if it is an absolute path to a descendant of <var>aNode<var/>
+ @throws InvalidName
+ if <var>aPath<var/> is not awell-formed path or
+ if it is an absolute path that is not to a descendant of <var>aNode<var/>
+ */
+ RelativePath validateAndReducePath(rtl::OUString const& aPath, rtl::Reference< Tree > const& aTree, NodeRef const& aNode);
+ /** checks whether there is an immediate child of <var>aNode</var> (which is in <var>aTree</var>)
+ specified by <var>aName</var>
+
+ @return
+ <TRUE/> if the child node exists
+ <FALSE/> otherwise
+ */
+ bool hasChildOrElement(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, rtl::OUString const& aName);
+
+ /** checks whether there is an immediate child of <var>aNode</var> (which is in <var>aTree</var>)
+ specified by <var>aName</var>
+
+ @return
+ <TRUE/> if the child node exists
+ <FALSE/> otherwise
+ */
+ bool hasChildOrElement(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, Path::Component const& aName);
+
+ /** tries to find the immediate child of <var>aNode</var> (which is in <var>aTree</var>)
+ specified by <var>aName</var>
+ <p> On return <var>aNode</var> is modified to refer to the node found and
+ <var>aTree</var> will then refer to the tree that node is in.
+ <p/>
+ <p>Caution: May miss an existing child unless the child has been accessed before.</p>
+
+ @return
+ <TRUE/> if the child node exists and is available
+ (so <var>aNode</var> and <var>aTree</var> refer to the desired node),
+ <FALSE/> otherwise
+
+ @see NodeRef::getAvailableChild
+ */
+ bool findInnerChildOrAvailableElement(rtl::Reference< Tree >& aTree, NodeRef& aNode, rtl::OUString const& aName);
+
+ /// test whether the given node is a structural (inner) node
+ bool isStructuralNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode);
+
+ /// test whether the given inner node is a group node
+ bool isGroupNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode);
+
+ /// get the value for a node that is a simple value (as tree element)
+ com::sun::star::uno::Any getSimpleElementValue(rtl::Reference< Tree > const& aTree, NodeRef const& aNode);
+
+ /// test whether the given inner node is a set node
+ bool isSetNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode);
+
+ void getAllContainedNodes(rtl::Reference< Tree > const& aTree, std::vector<NodeID>& aList);
+ NodeID findNodeFromIndex(rtl::Reference< Tree > const& aTreeRef, unsigned int nIndex);
+
+ //-------------------------------------------------------------------------
+ inline bool NodeRef::isValid() const
+ {
+ return m_nPos != 0;
+ }
+
+ //-------------------------------------------------------------------------
+ inline unsigned int NodeRef::getOffset() const
+ {
+ return m_nPos;
+ }
+
+ //-------------------------------------------------------------------------
+ inline unsigned int NodeRef::getDepth() const
+ {
+ return m_nDepth;
+ }
+
+ //-------------------------------------------------------------------------
+ inline bool operator!=(NodeID const& lhs, NodeID const& rhs)
+ { return !(lhs == rhs); }
+ //---------------------------------------------------------------------
+
+ inline bool operator>=(NodeID const& lhs, NodeID const& rhs)
+ { return !(lhs < rhs); }
+ //---------------------------------------------------------------------
+ inline bool operator > (NodeID const& lhs, NodeID const& rhs)
+ { return (rhs < lhs); }
+ inline bool operator<=(NodeID const& lhs, NodeID const& rhs)
+ { return !(rhs < lhs); }
+ //-------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGNODE_HXX_
diff --git a/configmgr/source/inc/nodevisitor.hxx b/configmgr/source/inc/nodevisitor.hxx
new file mode 100644
index 000000000000..a61b48f9ed9f
--- /dev/null
+++ b/configmgr/source/inc/nodevisitor.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodevisitor.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_CONFIGMGR_SOURCE_INC_NODEVISITOR_HXX
+#define INCLUDED_CONFIGMGR_SOURCE_INC_NODEVISITOR_HXX
+
+#include "sal/config.h"
+
+namespace configmgr { namespace sharable {
+ struct GroupNode;
+ struct SetNode;
+ struct TreeFragment;
+ struct ValueNode;
+ union Node;
+} }
+
+namespace configmgr { namespace data {
+
+class NodeVisitor {
+public:
+ virtual ~NodeVisitor() = 0;
+
+ bool visitNode(sharable::Node * node);
+
+ bool visitChildren(sharable::GroupNode * node);
+
+protected:
+ virtual bool handle(sharable::Node * node);
+
+ virtual bool handle(sharable::ValueNode * node);
+
+ virtual bool handle(sharable::GroupNode * node);
+
+ virtual bool handle(sharable::SetNode * node);
+};
+
+class SetVisitor: public NodeVisitor {
+public:
+ virtual ~SetVisitor() = 0;
+
+ bool visitTree(sharable::TreeFragment * tree);
+
+ bool visitElements(sharable::SetNode * node);
+
+protected:
+ using NodeVisitor::handle;
+
+ virtual bool handle(sharable::TreeFragment * tree);
+};
+
+} }
+
+#endif
diff --git a/configmgr/source/inc/options.hxx b/configmgr/source/inc/options.hxx
new file mode 100644
index 000000000000..075671b244a0
--- /dev/null
+++ b/configmgr/source/inc/options.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: options.hxx,v $
+ * $Revision: 1.22 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_MISC_OPTIONS_HXX_
+#define CONFIGMGR_MISC_OPTIONS_HXX_
+
+#include "requestoptions.hxx"
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include "utility.hxx"
+#include <salhelper/simplereferenceobject.hxx>
+#include <vos/ref.hxx>
+
+namespace configmgr
+{
+ namespace css = ::com::sun::star;
+
+ /**
+ class OOptions is created one time per Configuration[update]Access
+ all important options should stored in this class.
+ The object will be forwarded to all other objects so we only
+ need to extend this classobject and all other class can work with
+ the new options or important options etc.
+ */
+
+ class OOptions : public salhelper::SimpleReferenceObject
+ {
+ RequestOptions m_aRequestOptions; // current options to use
+
+ public:
+ OOptions()
+ : m_aRequestOptions()
+ {}
+
+ explicit
+ OOptions(const RequestOptions& _aDefaultOptions)
+ : m_aRequestOptions(_aDefaultOptions)
+ {
+ }
+
+ OOptions(const OOptions& _aOtherOptions)
+ : SimpleReferenceObject()
+ , m_aRequestOptions(_aOtherOptions.m_aRequestOptions)
+ {
+ }
+
+ bool isForSessionUser() const { return ! m_aRequestOptions.hasEntity(); }
+
+ rtl::OUString getLocale() const { return m_aRequestOptions.getLocale(); }
+ rtl::OUString getUser() const { return m_aRequestOptions.getEntity(); }
+
+ RequestOptions const & getRequestOptions() const
+ { return m_aRequestOptions; }
+
+ void setUser(const rtl::OUString & _rUser)
+ { m_aRequestOptions.setEntity(_rUser); }
+
+ void setLocale(const com::sun::star::lang::Locale & _rLocale)
+ { m_aRequestOptions.setLocale(_rLocale); }
+
+ void setMultiLocaleMode()
+ { m_aRequestOptions.setAllLocales(); }
+
+ void enableAsync(bool _bEnable)
+ { m_aRequestOptions.enableAsync(_bEnable); }
+ };
+
+ struct ltOptions
+ {
+ lessRequestOptions ltData;
+ bool operator()(vos::ORef<OOptions> const &o1, vos::ORef<OOptions> const &o2) const
+ {
+ return ltData(o1->getRequestOptions(),o2->getRequestOptions());
+ }
+ };
+} // namespace
+
+#endif
diff --git a/configmgr/source/inc/oslstream.hxx b/configmgr/source/inc/oslstream.hxx
new file mode 100644
index 000000000000..75c9ae218c9d
--- /dev/null
+++ b/configmgr/source/inc/oslstream.hxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: oslstream.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_OSLSTREAM_HXX_
+#define _CONFIGMGR_OSLSTREAM_HXX_
+
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <osl/mutex.hxx>
+
+#include "bufferedfile.hxx"
+
+namespace osl
+{
+ class File;
+}
+
+namespace configmgr
+{
+ namespace stario = ::com::sun::star::io;
+ namespace staruno = ::com::sun::star::uno;
+
+// -----------------------------------------------------------------------------
+ /// OSLInputStreamWrapper - implementation of XInputStream on an (unbuffered) osl::File
+ class OSLInputStreamWrapper : public ::cppu::WeakImplHelper1<stario::XInputStream>
+ {
+ ::osl::Mutex m_aMutex;
+ ::osl::File* m_pFile;
+ sal_Bool m_bFileOwner : 1;
+
+ public:
+ /// c'tor. _rStream must live at least until closeInput() is called on this stream
+ OSLInputStreamWrapper(::osl::File& _rStream);
+ /// c'tor. if bOwner is <FALSE/> *pStream must live at least until closeInput() is called on this stream
+ OSLInputStreamWrapper(::osl::File* pStream, sal_Bool bOwner=sal_False);
+ virtual ~OSLInputStreamWrapper();
+
+ // stario::XInputStream
+ virtual sal_Int32 SAL_CALL
+ readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL
+ readSomeBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead)
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException);
+
+ virtual void SAL_CALL
+ skipBytes(sal_Int32 nBytesToSkip)
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL available() throw(stario::NotConnectedException, staruno::RuntimeException);
+ virtual void SAL_CALL closeInput() throw(stario::NotConnectedException, staruno::RuntimeException);
+ };
+
+// -----------------------------------------------------------------------------
+ /// OSLOutputStreamWrapper - implementation of XOutputStream on an (unbuffered) osl::File
+ class OSLOutputStreamWrapper : public ::cppu::WeakImplHelper1<stario::XOutputStream>
+ {
+ ::osl::Mutex m_aMutex;
+ ::osl::File& rFile;
+
+ public:
+ /// c'tor. _rStream must live at least until closeOutput() is called on this stream
+ OSLOutputStreamWrapper(::osl::File& _rFile) :rFile(_rFile) { }
+
+ // stario::XOutputStream
+ virtual void SAL_CALL writeBytes(const staruno::Sequence< sal_Int8 >& aData)
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException);
+
+ virtual void SAL_CALL flush()
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException);
+
+ virtual void SAL_CALL closeOutput()
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException);
+ };
+// -----------------------------------------------------------------------------
+ /// BufferedFileOutputStream - buffered implementation of XOutputStream on an osl::File
+ class BufferedFileOutputStream: public ::cppu::WeakImplHelper1<stario::XOutputStream>
+ {
+ BufferedOutputFile m_aFile;
+
+ public:
+ BufferedFileOutputStream(rtl::OUString const & aFileURL, bool bCreate=true, sal_uInt32 nBufferSizeHint=0);
+ virtual ~BufferedFileOutputStream();
+
+ // stario::XOutputStream
+ virtual void SAL_CALL writeBytes(const staruno::Sequence< sal_Int8 >& aData)
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException,
+ stario::IOException, staruno::RuntimeException);
+
+ virtual void SAL_CALL flush()
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException,
+ stario::IOException, staruno::RuntimeException);
+
+ virtual void SAL_CALL closeOutput()
+ throw(stario::NotConnectedException, stario::BufferSizeExceededException,
+ stario::IOException, staruno::RuntimeException);
+ };
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+
+#endif // _CONFIGMGR_OSLSTREAM_HXX_
+
+
+
diff --git a/configmgr/source/inc/propertysethelper.hxx b/configmgr/source/inc/propertysethelper.hxx
new file mode 100644
index 000000000000..988479b2905f
--- /dev/null
+++ b/configmgr/source/inc/propertysethelper.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertysethelper.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_MISC_PROPERTYSETHELPER_HXX
+#define CONFIGMGR_MISC_PROPERTYSETHELPER_HXX
+
+#include <cppuhelper/propshlp.hxx>
+#include <cppuhelper/weak.hxx>
+
+//..........................................................................
+namespace configmgr {
+ namespace apihelper {
+//..........................................................................
+ namespace uno = com::sun::star::uno;
+ namespace lang = com::sun::star::lang;
+ namespace beans = com::sun::star::beans;
+//..........................................................................
+class BroadcasterBase
+{
+ osl::Mutex m_aMutex;
+ cppu::OBroadcastHelper m_aBroadcastHelper;
+
+protected:
+ BroadcasterBase() : m_aMutex(), m_aBroadcastHelper(m_aMutex) {}
+ ~BroadcasterBase() {}
+
+ osl::Mutex & getBroadcastMutex() { return m_aMutex; }
+ cppu::OBroadcastHelper & getBroadcastHelper() { return m_aBroadcastHelper; }
+};
+
+//..........................................................................
+
+class PropertySetHelper : protected BroadcasterBase // must be first
+ , public cppu::OWeakObject
+ , public cppu::OPropertySetHelper // not copyable
+{
+public:
+ PropertySetHelper();
+ ~PropertySetHelper();
+
+ // XInterface
+ virtual uno::Any SAL_CALL queryInterface( uno::Type const & rType ) throw (uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw ();
+ virtual void SAL_CALL release() throw ();
+ // XTypeProvider
+ virtual uno::Sequence< uno::Type > SAL_CALL getTypes() throw (uno::RuntimeException);
+
+ // to be provided by derived classes
+ // virtual uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (uno::RuntimeException) = 0;
+
+ // XPropertySet
+ virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL
+ getPropertySetInfo( ) throw (uno::RuntimeException);
+
+
+protected:
+// new methods still to be overridden
+ virtual cppu::IPropertyArrayHelper * SAL_CALL newInfoHelper() = 0;
+
+// cppu::OPropertySetHelper interface
+#if 0 // these methods still must be overridden
+ virtual cppu::IPropertyArrayHelper * SAL_CALL newInfoHelper() = 0;
+
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue )
+ throw (uno::Exception) = 0;
+
+ virtual void SAL_CALL getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const = 0;
+#endif
+ virtual cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();
+
+ // default implementation: does not do any conversion
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ uno::Any & rConvertedValue, uno::Any & rOldValue,
+ sal_Int32 nHandle, const uno::Any& rValue )
+ throw (lang::IllegalArgumentException);
+private:
+ cppu::IPropertyArrayHelper * m_pHelper;
+};
+//..........................................................................
+ } // namespace apihelper
+} // namespace configmgr
+//..........................................................................
+
+#endif
+
+
diff --git a/configmgr/source/inc/request.hxx b/configmgr/source/inc/request.hxx
new file mode 100644
index 000000000000..f3d0360590af
--- /dev/null
+++ b/configmgr/source/inc/request.hxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: request.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_REQUEST_HXX_
+#define CONFIGMGR_BACKEND_REQUEST_HXX_
+
+#include "requestoptions.hxx"
+#include "requesttypes.hxx"
+#include "configpath.hxx"
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+ namespace backend
+ {
+// ---------------------------------------------------------------------------
+
+ class NodeRequest
+ {
+ configuration::AbsolutePath m_aNodePath;
+ RequestOptions m_aOptions;
+ public:
+ NodeRequest(configuration::AbsolutePath const& _aNodePath, RequestOptions const & _aOptions)
+ : m_aNodePath(_aNodePath)
+ , m_aOptions(_aOptions)
+ {
+ }
+
+ configuration::AbsolutePath const & getPath() const { return m_aNodePath; }
+ RequestOptions const & getOptions() const { return m_aOptions; }
+ };
+// ---------------------------------------------------------------------------
+
+ class ComponentRequest
+ {
+ rtl::OUString m_aComponentName;
+ RequestOptions m_aOptions;
+ bool m_bForcedReload;
+ public:
+ ComponentRequest(rtl::OUString const& _aComponentName, RequestOptions const & _aOptions)
+ : m_aComponentName(_aComponentName)
+ , m_aOptions(_aOptions)
+ , m_bForcedReload(false)
+ {
+ }
+
+ rtl::OUString const & getComponentName() const { return m_aComponentName; }
+ RequestOptions const & getOptions() const { return m_aOptions; }
+
+ bool isForcingReload() const { return m_bForcedReload; }
+ void forceReload(bool _bForce = true) { m_bForcedReload = _bForce; }
+ };
+// ---------------------------------------------------------------------------
+
+ class TemplateRequest
+ {
+ rtl::OUString m_aComponentName;
+ rtl::OUString m_aTemplateName;
+
+ public:
+ static
+ TemplateRequest forComponent(rtl::OUString const & _aComponentName)
+ {
+ return TemplateRequest( rtl::OUString(), _aComponentName);
+ }
+
+ explicit
+ TemplateRequest(rtl::OUString const & _aTemplateName, rtl::OUString const & _aComponentName)
+ : m_aComponentName(_aComponentName)
+ , m_aTemplateName(_aTemplateName)
+ {}
+
+ bool isComponentRequest() const { return m_aTemplateName.getLength() == 0; }
+ rtl::OUString getTemplateName() const { return m_aTemplateName; }
+ rtl::OUString getComponentName() const { return m_aComponentName; }
+
+ };
+
+// ---------------------------------------------------------------------------
+
+ class UpdateRequest
+ {
+ ConstUpdateInstance m_aUpdate;
+ RequestOptions m_aOptions;
+ rtl::OUString m_aRQID;
+ public:
+ explicit
+ UpdateRequest( UpdateInstance const & _aUpdate,
+ RequestOptions const & _aOptions)
+ : m_aUpdate(_aUpdate)
+ , m_aOptions(_aOptions)
+ {}
+
+ explicit
+ UpdateRequest( ConstUpdateInstance const & _aUpdate,
+ RequestOptions const & _aOptions)
+ : m_aUpdate(_aUpdate)
+ , m_aOptions(_aOptions)
+ {}
+
+ explicit
+ UpdateRequest( ConstUpdateInstance::Data _aUpdateData,
+ configuration::AbsolutePath const & _aRootpath,
+ RequestOptions const & _aOptions)
+ : m_aUpdate(_aUpdateData, _aRootpath)
+ , m_aOptions(_aOptions)
+ {}
+
+ bool isSyncRequired() const { return !m_aOptions.isAsyncEnabled(); }
+
+ RequestOptions const & getOptions() const { return m_aOptions; }
+ configuration::AbsolutePath const & getUpdateRoot() const { return m_aUpdate.root(); }
+
+ ConstUpdateInstance const & getUpdate() const { return m_aUpdate; }
+ ConstUpdateInstance::Data getUpdateData() const { return m_aUpdate.data(); }
+
+ void setRequestId(rtl::OUString const & _aRQID) { m_aRQID = _aRQID; }
+ rtl::OUString getRequestId() const { return m_aRQID; }
+ };
+
+ inline ComponentRequest getComponentRequest(UpdateRequest const & _aUR)
+ { return ComponentRequest(_aUR.getUpdateRoot().getModuleName(), _aUR.getOptions()); }
+// ---------------------------------------------------------------------------
+ } // namespace
+// ---------------------------------------------------------------------------
+} // namespace
+
+#endif
diff --git a/configmgr/source/inc/requestoptions.hxx b/configmgr/source/inc/requestoptions.hxx
new file mode 100644
index 000000000000..5b07ac480b2a
--- /dev/null
+++ b/configmgr/source/inc/requestoptions.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: requestoptions.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_MISC_REQUESTOPTIONS_HXX_
+#define CONFIGMGR_MISC_REQUESTOPTIONS_HXX_
+
+#include <com/sun/star/lang/Locale.hpp>
+#include <rtl/ustring.hxx>
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+
+ /**
+ Options which can be used to modify a request for data
+ */
+ class RequestOptions
+ {
+ public:
+ /// Default constructor. Sets options to use defaults.
+ RequestOptions()
+ : m_sLocale()
+ , m_sEntity()
+ , m_bEnableAsync(true)
+ , m_bReload(false)
+ {}
+
+ /// @returns <TRUE/>, if data can be written asynchronously
+ bool isAsyncEnabled() const { return m_bEnableAsync; }
+ /// @returns <TRUE/>, if data is reloaded into cache
+ bool isRefreshEnabled() const { return m_bReload; }
+ /** @returns
+ <TRUE/>, if a locale is specified, <BR/>
+ <FALSE/>, if the default locale should be used
+ */
+ bool hasLocale() const { return m_sLocale.Language.getLength() != 0; }
+ /// @returns the locale to get data for
+ bool isForAllLocales() const;
+ /// @returns the locale to get data for - compatibilty version
+ rtl::OUString getLocale() const { return getIsoLocale(); }
+ /// @returns the locale to get data for
+ rtl::OUString getIsoLocale() const;
+ /// @returns the locale to get data for
+ com::sun::star::lang::Locale const & getUnoLocale() const { return m_sLocale; }
+
+ /** @returns
+ <TRUE/>, if an entity is specified, <BR/>
+ <FALSE/>, if data of the session user is requested
+ */
+ bool hasEntity() const { return m_sEntity.getLength() != 0; }
+ /// @returns the entity to get data for
+ rtl::OUString getEntity() const { return m_sEntity; }
+
+ /// sets the entity to get data for to the given entity
+ void setEntity(rtl::OUString const & _sEntity) { m_sEntity = _sEntity; }
+ /// resets the entity to get data for to be the session user
+ void clearEntity() { m_sEntity = rtl::OUString(); }
+
+ /// sets the locale so data is gotten for all locales
+ void setAllLocales();
+ /// sets the locale to get data for to the given locale
+ void setLocale(com::sun::star::lang::Locale const & _aLocale) { m_sLocale = _aLocale; }
+ /// sets the locale to get data for to the given locale
+ void setIsoLocale(rtl::OUString const & _sLocale);
+ /// sets a fallback locale, if no locale is set yet
+ void ensureLocaleSet();
+
+ /// marks asyncronous access a enabled or disabled
+ void enableAsync(bool _bEnable = true) { m_bEnableAsync = _bEnable; }
+ /// enforce a refresh to cache
+ void forceRefresh(bool _bEnable = true) { m_bReload = _bEnable; }
+ // comparison/container helpers
+ /// function that defines a weak strict ordering on RequestOptions
+ friend sal_Int32 compareRequestOptions(RequestOptions const& lhs, RequestOptions const& rhs);
+ private:
+ com::sun::star::lang::Locale m_sLocale; /// locale to fetch data for
+ rtl::OUString m_sEntity; /// user/group/role to fetch data for
+ bool m_bEnableAsync; /// true, if data may be
+ bool m_bReload; /// reload into cache from backend
+ };
+
+// ---------------------------------------------------------------------------
+ struct lessRequestOptions
+ {
+ bool operator()(RequestOptions const & lhs, RequestOptions const & rhs) const
+ { return compareRequestOptions(lhs,rhs) < 0; }
+ };
+// ---------------------------------------------------------------------------
+ struct equalRequestOptions
+ {
+ bool operator()(RequestOptions const & lhs, RequestOptions const & rhs) const
+ { return compareRequestOptions(lhs,rhs) == 0; }
+ };
+// ---------------------------------------------------------------------------
+} // namespace
+
+#endif
diff --git a/configmgr/source/inc/requesttypes.hxx b/configmgr/source/inc/requesttypes.hxx
new file mode 100644
index 000000000000..d4a64dd32666
--- /dev/null
+++ b/configmgr/source/inc/requesttypes.hxx
@@ -0,0 +1,237 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: requesttypes.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_REQUESTTYPES_HXX_
+#define CONFIGMGR_BACKEND_REQUESTTYPES_HXX_
+
+#include "sal/config.h"
+
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "valuenode.hxx"
+#include "treechangelist.hxx"
+#include "configpath.hxx"
+
+#ifndef _CONFIGMGR_UTILITY_HXX_
+#include <utility.hxx>
+#endif
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+ namespace backend
+ {
+// ---------------------------------------------------------------------------
+ struct ComponentDataStruct
+ {
+ const std::auto_ptr<ISubtree>& data;
+ rtl::OUString name;
+ ComponentDataStruct (const std::auto_ptr<ISubtree>& _data, rtl::OUString _name)
+ : data(_data), name(_name) {}
+ };
+// ---------------------------------------------------------------------------
+ struct NodeInstance
+ {
+ typedef std::auto_ptr<ISubtree> Data;
+
+ explicit
+ NodeInstance(Data _node, configuration::AbsolutePath const & _rootpath)
+ : m_node(_node)
+ , m_root(_rootpath)
+ {
+ }
+
+ Data const & data() const { return m_node; }
+ configuration::AbsolutePath const & root() const { return m_root; }
+
+ Data & mutableData() { return m_node; }
+ Data extractData() { return m_node; }
+ private:
+ Data m_node;
+ configuration::AbsolutePath m_root;
+ };
+// ---------------------------------------------------------------------------
+ struct TemplateInstance
+ {
+ typedef std::auto_ptr<INode> Data;
+
+ explicit
+ TemplateInstance(Data _node, rtl::OUString const & _name, rtl::OUString const & _component)
+ : m_node(_node)
+ , m_name(_name)
+ , m_component(_component)
+ {
+ }
+
+ Data const & data() const { return m_node; }
+ rtl::OUString const & name() const { return m_name; }
+ rtl::OUString const & component() const { return m_component; }
+
+ Data extractData() { return m_node; }
+ private:
+ Data m_node;
+ rtl::OUString m_name; // if empty, this is a complete set of component templates
+ rtl::OUString m_component;
+ };
+// ---------------------------------------------------------------------------
+ struct ComponentInstance
+ {
+ typedef std::auto_ptr<ISubtree> Data;
+
+ explicit
+ ComponentInstance(Data _node, Data _template, rtl::OUString const & _component)
+ : m_node(_node)
+ , m_template(_template)
+ , m_component(_component)
+ {
+ }
+
+ Data const & data() const { return m_node; }
+ Data const & templateData() const { return m_template; }
+ rtl::OUString const & component() const { return m_component; }
+
+ ComponentDataStruct componentTemplateData () const { return ComponentDataStruct(m_template,m_component);}
+ ComponentDataStruct componentNodeData () const { return ComponentDataStruct(m_node,m_component);}
+ Data & mutableData() { return m_node; }
+ Data extractData() { return m_node; }
+ Data extractTemplateData() { return m_template; }
+ private:
+ Data m_node;
+ Data m_template;
+ rtl::OUString m_component;
+ };
+// ---------------------------------------------------------------------------
+ struct UpdateInstance
+ {
+ typedef SubtreeChange * Data;
+
+ explicit
+ UpdateInstance(Data _update, configuration::AbsolutePath const & _rootpath)
+ : m_update(_update)
+ , m_root(_rootpath)
+ {
+ }
+
+ UpdateInstance(UpdateInstance & _aModifiableOther)
+ : m_update(_aModifiableOther.m_update)
+ , m_root(_aModifiableOther.m_root)
+ {
+ }
+
+ Data data() { return m_update; }
+ SubtreeChange const * data() const { return m_update; }
+ configuration::AbsolutePath const & root() const { return m_root; }
+ private:
+ Data m_update;
+ configuration::AbsolutePath m_root;
+ };
+// ---------------------------------------------------------------------------
+ struct ConstUpdateInstance
+ {
+ typedef SubtreeChange const * Data;
+
+ explicit
+ ConstUpdateInstance(Data _update, configuration::AbsolutePath const & _rootpath)
+ : m_update(_update)
+ , m_root(_rootpath)
+ {
+ }
+
+ // conversion
+ ConstUpdateInstance(UpdateInstance const & _aModifiable)
+ : m_update(_aModifiable.data())
+ , m_root(_aModifiable.root())
+ {
+ }
+
+ Data data() const { return m_update; }
+ configuration::AbsolutePath const & root() const { return m_root; }
+ private:
+ Data m_update;
+ configuration::AbsolutePath m_root;
+ };
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+// Due to the use of auto_ptr, the XxxInstance classes cannot easily be used as return values
+// To return them, they should be wrapped into a ResultHolder
+
+ template <class Instance_>
+ class ResultHolder
+ {
+ struct RCInstance : public salhelper::SimpleReferenceObject
+ {
+ RCInstance(Instance_ & _instance)
+ : instance(_instance) {}
+ Instance_ instance;
+ };
+
+ rtl::Reference< RCInstance > m_xInstance;
+ public:
+ explicit
+ ResultHolder(Instance_ & _rInstance)
+ : m_xInstance( new RCInstance(_rInstance) )
+ {}
+
+ bool isEmpty() const { return !m_xInstance.is(); }
+
+ bool is() const { return m_xInstance.is() && m_xInstance->instance.data().get(); }
+
+ Instance_ const & instance() const { return m_xInstance->instance; }
+
+ Instance_ const & operator *() const { return instance(); }
+ Instance_ const * operator->() const { return &instance(); }
+ Instance_ & mutableInstance() { return m_xInstance->instance; }
+
+ typename Instance_::Data extractDataAndClear()
+ {
+ typename Instance_::Data aData = m_xInstance->instance.extractData();
+ this->clear();
+ return aData;
+ }
+
+ void releaseAndClear()
+ {
+ typename Instance_::Data aData = this->extractDataAndClear();
+ aData.release();
+ }
+
+ void clear() { m_xInstance.clear(); }
+ };
+// ---------------------------------------------------------------------------
+ }
+// ---------------------------------------------------------------------------
+} // namespace
+
+#endif
diff --git a/configmgr/source/inc/roottree.hxx b/configmgr/source/inc/roottree.hxx
new file mode 100644
index 000000000000..51724844a29e
--- /dev/null
+++ b/configmgr/source/inc/roottree.hxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: roottree.hxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_ROOTTREE_HXX_
+#define CONFIGMGR_ROOTTREE_HXX_
+
+#include "sal/config.h"
+
+#include <memory>
+
+#include "boost/utility.hpp"
+#include "rtl/ref.hxx"
+
+#include "utility.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace sharable { union Node; }
+ class SubtreeChange;
+ struct TreeChangeList;
+
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ class Tree;
+ class NodeRef;
+ class NodeChangesInformation;
+ class AbsolutePath;
+ class TemplateProvider;
+
+//-----------------------------------------------------------------------------
+
+ rtl::Reference< Tree > createReadOnlyTree( AbsolutePath const& aRootPath,
+ sharable::Node * _aCacheNode,
+ unsigned int nDepth,
+ TemplateProvider const& aTemplateProvider);
+
+ rtl::Reference< Tree > createUpdatableTree( AbsolutePath const& aRootPath,
+ sharable::Node * _aCacheNode,
+ unsigned int nDepth,
+ TemplateProvider const& aTemplateProvider);
+
+//-----------------------------------------------------------------------------
+ class CommitHelper: private boost::noncopyable
+ {
+ struct Data;
+
+ std::auto_ptr<Data> m_pData;
+ Tree* m_pTree;
+ public:
+ CommitHelper(rtl::Reference< Tree > const& aTree);
+ ~CommitHelper();
+
+ // collect all changes into rChangeList
+ bool prepareCommit(TreeChangeList& rChangeList);
+
+ // finish and clean up the changes in rChangeList after they are integrated
+ void finishCommit(TreeChangeList& rChangeList);
+ // throw away and clean up the changes in rChangeList after a commit failed
+ void failedCommit(TreeChangeList& rChangeList);
+ };
+
+//-----------------------------------------------------------------------------
+ /** adjusts <var>aTree</var> tree to the (externally produced) changes under <var>aExternalChanges</var>
+ and collects the changes this induces locally.
+ @param rLocalChanges
+ a collection that will hold the changes induced by <var>aExternalChanges</var>.
+ @param aExternalChanges
+ a structured change that has already been applied to the master tree.
+ @param aBaseTree
+ the tree that contains (directly) the affected node of <var>aExternalChanges</var>.
+ @param aBaseNode
+ a NodeRef referring to the (directly) affected node of <var>aExternalChanges</var>.
+ @return
+ <TRUE/> if any changes occur in this tree (so rLocalChanges is not empty), <FALSE/> otherwise.
+
+ */
+ bool adjustToChanges( NodeChangesInformation& rLocalChanges,
+ rtl::Reference< Tree > const& aBaseTree, NodeRef const& aBaseNode,
+ SubtreeChange const& aExternalChange) ;
+
+
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_ROOTTREE_HXX_
diff --git a/configmgr/source/inc/sequence.hxx b/configmgr/source/inc/sequence.hxx
new file mode 100644
index 000000000000..d84edc819862
--- /dev/null
+++ b/configmgr/source/inc/sequence.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sequence.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_SHARABLE_SEQUENCE_HXX
+#define INCLUDED_SHARABLE_SEQUENCE_HXX
+
+#include "anydata.hxx"
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace sharable
+ {
+ //-----------------------------------------------------------------------------
+
+ sal_uInt8 * allocSequence(sal_uInt8 _aElementType, ::sal_Sequence const * _pSeqData);
+ void freeSequence(sal_uInt8 _aElementType, sal_uInt8 * _aSeq);
+
+ ::sal_Sequence * readSequence(sal_uInt8 _aElementType, sal_uInt8 * _aSeq);
+ ::com::sun::star::uno::Any readAnySequence(sal_uInt8 _aElementType, sal_uInt8 * _aSeq);
+ //-----------------------------------------------------------------------------
+
+ sal_uInt8 * allocBinary(::com::sun::star::uno::Sequence<sal_Int8> const & _aBinaryValue);
+ void freeBinary(sal_uInt8 * _aSeq);
+
+ ::com::sun::star::uno::Sequence<sal_Int8> readBinary(sal_uInt8 * _aSeq);
+ //-----------------------------------------------------------------------------
+
+ template <class ET>
+ inline
+ sal_uInt8 getElementTypeCode(::com::sun::star::uno::Sequence<ET> const & )
+ {
+ ::com::sun::star::uno::Type aElementType = ::getCppuType( static_cast<ET const *>(NULL) );
+ return getTypeCode(aElementType);
+ }
+
+ template <class ET>
+ sal_uInt8 * allocSequence(::com::sun::star::uno::Sequence<ET> const & _aSeq)
+ {
+ sal_uInt8 aTC = getElementTypeCode(_aSeq);
+ ::sal_Sequence const * pSeqData = _aSeq.get();
+ return allocSequence(aTC, pSeqData);
+ }
+
+ template <class ET>
+ void readSequence(::com::sun::star::uno::Sequence<ET> & _rSeq, sal_uInt8 * _aSeq)
+ {
+ sal_uInt8 aElementType = getElementTypeCode(_rSeq);
+
+ ::sal_Sequence * pNewSequence = readSequence(aElementType, _aSeq);
+
+ if (!pNewSequence) return;
+
+ ::com::sun::star::uno::Sequence<ET> aNewSequence(pNewSequence, SAL_NO_ACQUIRE);
+
+ _rSeq = aNewSequence;
+ }
+
+ template <class ET>
+ bool readSequence(::com::sun::star::uno::Sequence<ET> & _rSeq, sal_uInt8 _aElementType, sal_uInt8 * _aSeq)
+ {
+ if (getElementTypeCode(_rSeq) != _aElementType) return false;
+
+ ::sal_Sequence * pNewSequence = readSequence(_aElementType, _aSeq);
+
+ if (!pNewSequence) return false;
+
+ ::com::sun::star::uno::Sequence<ET> aNewSequence(pNewSequence, SAL_NO_ACQUIRE);
+
+ _rSeq = aNewSequence;
+
+ return true;
+ }
+//-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
+
+#endif // INCLUDED_SHARABLE_SEQUENCE_HXX
diff --git a/configmgr/source/inc/serviceinfohelper.hxx b/configmgr/source/inc/serviceinfohelper.hxx
new file mode 100644
index 000000000000..cc55cbe74a1d
--- /dev/null
+++ b/configmgr/source/inc/serviceinfohelper.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: serviceinfohelper.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_SERVICEINFOHELPER_HXX_
+#define CONFIGMGR_SERVICEINFOHELPER_HXX_
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+// -----------------------------------------------------------------------------
+
+ /// POD struct describing the registration information of a service implementation
+ struct ServiceRegistrationInfo
+ {
+ /// The implementation name of this service implementation
+ sal_Char const * implementationName;
+ /// The services for which this service implementation is registered
+ sal_Char const * const * registeredServiceNames;
+ };
+// -----------------------------------------------------------------------------
+
+ /// POD struct describing the implementation information of a service implementation
+ struct ServiceImplementationInfo
+ {
+ /// The implementation name of this service implementation
+ sal_Char const * implementationName;
+ /// The services for which this service implementation is registered
+ sal_Char const * const * registeredServiceNames;
+ /// Additional services implemented by this service implementation, for which it is not registered
+ sal_Char const * const * additionalServiceNames;
+ };
+// -----------------------------------------------------------------------------
+
+ // ServiceImplementationInfo has a compatible initial sequence with struct ServiceRegistrationInfo
+
+ inline
+ ServiceRegistrationInfo const *
+ getRegistrationInfo(ServiceImplementationInfo const * _info)
+ {
+ return reinterpret_cast<ServiceRegistrationInfo const *>(_info);
+ }
+// -----------------------------------------------------------------------------
+
+ /// POD struct describing the registration information of a singleton
+ struct SingletonRegistrationInfo
+ {
+ /// The name of this singleton
+ sal_Char const * singletonName;
+ /// The implementation, which owns this singleton
+ sal_Char const * implementationName;
+ /// The service, which should be instatiated for this singleton
+ sal_Char const * instantiatedServiceName;
+ /// A name for a pseudo-implementation, which is mapped to this singleton
+ ServiceRegistrationInfo const * mappedImplementation;
+ };
+// -----------------------------------------------------------------------------
+
+ class ServiceRegistrationHelper
+ {
+ ServiceRegistrationInfo const*const m_info;
+
+ public:
+ ServiceRegistrationHelper(ServiceRegistrationInfo const* _info)
+ : m_info(_info)
+ {}
+
+ ServiceRegistrationHelper(ServiceImplementationInfo const* _info)
+ : m_info(getRegistrationInfo(_info))
+ {}
+
+ sal_Int32 countServices() const;
+
+ rtl::OUString getImplementationName( ) const
+ throw(uno::RuntimeException);
+
+ uno::Sequence< rtl::OUString > getRegisteredServiceNames( ) const
+ throw(uno::RuntimeException);
+ };
+// -----------------------------------------------------------------------------
+
+ class ServiceInfoHelper
+ {
+ ServiceImplementationInfo const*const m_info;
+
+ public:
+ ServiceInfoHelper(ServiceImplementationInfo const* _info)
+ : m_info(_info)
+ {}
+
+ sal_Int32 countServices() const;
+
+ rtl::OUString getImplementationName( ) const
+ throw(uno::RuntimeException);
+
+ sal_Bool supportsService( rtl::OUString const & ServiceName ) const
+ throw(uno::RuntimeException);
+
+ uno::Sequence< rtl::OUString > getSupportedServiceNames( ) const
+ throw(uno::RuntimeException);
+ };
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+
+#endif
+
+
diff --git a/configmgr/source/inc/simpleinteractionrequest.hxx b/configmgr/source/inc/simpleinteractionrequest.hxx
new file mode 100644
index 000000000000..efcf0ff95d14
--- /dev/null
+++ b/configmgr/source/inc/simpleinteractionrequest.hxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: simpleinteractionrequest.hxx,v $
+ * $Revision: 1.4.18.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_SIMPLEINTERACTIONREQUEST_HXX
+#define CONFIGMGR_SIMPLEINTERACTIONREQUEST_HXX
+
+#include "interactionrequest.hxx"
+
+// this file was copied and adapted from the corresponding file in module ucbhelper
+
+namespace configmgr {
+namespace apihelper {
+
+ namespace uno = com::sun::star::uno;
+/**
+ This class implements a simple interaction request. The user must not deal
+ with XInteractionContinuations directly, but can use constants that are
+ mapped internally to the according objects. This class encapsulates the
+ standard Interaction Continuations "Abort", "Retry", "Approve" and
+ "Disaprrove". Instances can be passed directly to
+ XInteractionHandler::handle(...).
+
+ @see InteractionRequest
+ @see InteractionAbort
+ @see InteractionRetry
+ @see InteractionApprove
+ @see InteractionDisapprove
+ */
+ class SimpleInteractionRequest : public InteractionRequest
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param rRequest is the exception describing the error.
+ * @param nContinuations contains the possible "answers" for the request.
+ * This can be any of the CONTINUATION_* constants combinations
+ * listed above.
+ */
+ SimpleInteractionRequest( const uno::Any & rRequest,
+ const sal_uInt32 nContinuations );
+
+ /**
+ * After passing this request to XInteractionHandler::handle, this method
+ * returns the continuation that was choosen by the interaction handler.
+ *
+ * @return the continuation choosen by an interaction handler or
+ * CONTINUATION_UNKNOWN, if the request was not (yet) handled.
+ */
+ sal_uInt32 getResponse() const;
+ };
+
+/** These are the constants that can be passed to the constructor of class
+ * SimpleInteractionRequest and that are returned by method
+ * SimpleInteractionRequest::getResponse().
+ */
+
+ /** The request was not (yet) handled by the interaction handler. */
+ const sal_uInt32 CONTINUATION_UNKNOWN = 0;
+
+ /** The interaction handler selected XInteractionAbort. */
+ const sal_uInt32 CONTINUATION_ABORT = 1;
+
+ /** The interaction handler selected XInteractionRetry. */
+ const sal_uInt32 CONTINUATION_RETRY = 2;
+
+ /** The interaction handler selected XInteractionApprove. */
+ const sal_uInt32 CONTINUATION_APPROVE = 4;
+
+ /** The interaction handler selected XInteractionDisapprove. */
+ const sal_uInt32 CONTINUATION_DISAPPROVE = 8;
+
+
+} // namespace apihelper
+} // namespace configmgr
+
+#endif /* !CONFIGMGR_SIMPLEINTERACTIONREQUEST_HXX */
diff --git a/configmgr/source/inc/simpletypehelper.hxx b/configmgr/source/inc/simpletypehelper.hxx
new file mode 100644
index 000000000000..e3df448d454c
--- /dev/null
+++ b/configmgr/source/inc/simpletypehelper.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: simpletypehelper.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_SIMPLETYPEHELPER_HXX
+#define CONFIGMGR_SIMPLETYPEHELPER_HXX
+
+#include <com/sun/star/uno/Type.hxx>
+
+namespace configmgr
+{
+ namespace uno = com::sun::star::uno;
+
+ namespace SimpleTypeHelper
+ {
+ uno::Type getBooleanType();
+
+ uno::Type getShortType();
+ uno::Type getIntType();
+ uno::Type getLongType();
+
+ uno::Type getDoubleType();
+
+ uno::Type getStringType();
+
+ uno::Type getBinaryType();
+ uno::Type getAnyType();
+ }
+}
+#endif
diff --git a/configmgr/source/inc/stack.hxx b/configmgr/source/inc/stack.hxx
new file mode 100644
index 000000000000..f2cec77e9e2c
--- /dev/null
+++ b/configmgr/source/inc/stack.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: stack.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_STACK_HXX_
+#define CONFIGMGR_STACK_HXX_
+
+#ifndef INCLUDED_STACK
+#include <stack>
+#define INCLUDED_STACK
+#endif
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace configmgr
+{
+
+ // simple wrapper for a vector-based stack
+ template <typename T_>
+ struct Stack : public std::stack< T_, std::vector<T_> >
+ {
+ typedef typename std::vector<T_>::const_iterator bottomup_iterator;
+ typedef typename std::vector<T_>::const_reverse_iterator topdown_iterator;
+ bottomup_iterator begin_up() const { return this->c.begin(); }
+ bottomup_iterator end_up() const { return this->c.end(); }
+ topdown_iterator begin_down() const { return this->c.rbegin(); }
+ topdown_iterator end_down() const { return this->c.rend(); }
+ };
+}
+
+#endif // CONFIGMGR_STACK_HXX_
+
+
diff --git a/configmgr/source/inc/strdecl.hxx b/configmgr/source/inc/strdecl.hxx
new file mode 100644
index 000000000000..2c1a7ec468ae
--- /dev/null
+++ b/configmgr/source/inc/strdecl.hxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: strdecl.hxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _CONFIGMGR_STRDECL_HXX_
+#define _CONFIGMGR_STRDECL_HXX_
+
+#include "strings.hxx"
+
+//.........................................................................
+namespace configmgr
+{
+//.........................................................................
+
+// extern declaration for predefined strings
+
+ // simple types names
+ DECLARE_CONSTASCII_USTRING(TYPE_BOOLEAN);
+ DECLARE_CONSTASCII_USTRING(TYPE_SHORT);
+ DECLARE_CONSTASCII_USTRING(TYPE_INT);
+ DECLARE_CONSTASCII_USTRING(TYPE_LONG);
+ DECLARE_CONSTASCII_USTRING(TYPE_DOUBLE);
+ DECLARE_CONSTASCII_USTRING(TYPE_STRING);
+ // Type: Sequence<bytes>
+ DECLARE_CONSTASCII_USTRING(TYPE_BINARY);
+ // Universal type: Any
+ DECLARE_CONSTASCII_USTRING(TYPE_ANY);
+
+ // special template names for native/localized value types
+ DECLARE_CONSTASCII_USTRING(TEMPLATE_MODULE_NATIVE_PREFIX);
+ DECLARE_CONSTASCII_USTRING(TEMPLATE_MODULE_NATIVE_VALUE);
+ DECLARE_CONSTASCII_USTRING(TEMPLATE_MODULE_LOCALIZED_VALUE);
+
+ DECLARE_CONSTASCII_USTRING(TEMPLATE_LIST_SUFFIX);
+
+} // namespace configmgr
+#endif
+
diff --git a/configmgr/source/inc/strings.hxx b/configmgr/source/inc/strings.hxx
new file mode 100644
index 000000000000..29e4ab1df883
--- /dev/null
+++ b/configmgr/source/inc/strings.hxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: strings.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_STRINGS_HXX_
+#define _CONFIGMGR_STRINGS_HXX_
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+
+//.........................................................................
+namespace configmgr
+{
+//.........................................................................
+
+struct UStringDescription
+{
+ const sal_Char* m_pZeroTerminatedName;
+ sal_Int32 m_nLen;
+ rtl_TextEncoding m_encoding;
+
+ UStringDescription(const sal_Char* _pName, sal_Int32 _nLen, rtl_TextEncoding _encoding)
+ : m_pZeroTerminatedName( _pName )
+ , m_nLen( _nLen )
+ , m_encoding(_encoding )
+ , m_aString (_pName, _nLen, _encoding)
+ {
+ }
+
+ sal_Int32 getLength() const { return m_nLen; }
+ operator ::rtl::OUString const&() const { return m_aString; }
+ operator const sal_Char*() const { return m_pZeroTerminatedName; }
+
+private:
+ rtl::OUString m_aString;
+ UStringDescription();
+};
+
+#define DECLARE_CONSTASCII_USTRING(name) \
+ extern ::configmgr::UStringDescription name
+
+#define IMPLEMENT_CONSTASCII_USTRING(name, asciivalue) \
+ ::configmgr::UStringDescription name(RTL_CONSTASCII_USTRINGPARAM(asciivalue))
+
+//.........................................................................
+} // namespace frm
+//.........................................................................
+
+#endif // _CONFIGMGR_STRINGS_HXX_
+
diff --git a/configmgr/source/inc/template.hxx b/configmgr/source/inc/template.hxx
new file mode 100644
index 000000000000..94972febfba2
--- /dev/null
+++ b/configmgr/source/inc/template.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: template.hxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGTEMPLATE_HXX_
+#define CONFIGMGR_CONFIGTEMPLATE_HXX_
+
+#include "configexcept.hxx"
+#include "configpath.hxx"
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#ifndef _CONFIGMGR_UTILITY_HXX_
+#include <utility.hxx>
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ class RequestOptions;
+ class TreeManager;
+ namespace sharable { struct SetNode; }
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+ class AbsolutePath;
+//-----------------------------------------------------------------------------
+
+ struct TemplateProvider_Impl;
+ class TemplateProvider
+ {
+ friend class SetElementFactory;
+ friend class TemplateImplHelper;
+
+ rtl::Reference<TemplateProvider_Impl> m_aImpl;
+ public:
+ TemplateProvider(); // creates an empty (invalid) template instance provider
+ TemplateProvider(rtl::Reference< TreeManager > const & xProvider, RequestOptions const& xOptions);
+ TemplateProvider(TemplateProvider const& aOther);
+ TemplateProvider& operator=(TemplateProvider const& aOther);
+ ~TemplateProvider();
+
+ bool isValid() const { return !!m_aImpl.is(); }
+ };
+//-----------------------------------------------------------------------------
+
+ /// provides information about the elements of a <type>Node</type> that is a Container ("set").
+ class Template : public salhelper::SimpleReferenceObject
+ {
+ rtl::OUString m_aName;
+ rtl::OUString m_aModule;
+ com::sun::star::uno::Type m_aInstanceType;
+ private:
+ explicit Template(rtl::OUString const& aName, rtl::OUString const& aModule,com::sun::star::uno::Type const& aType);
+
+ public:
+ /// checks if the type of an instance of this is known
+ bool isInstanceTypeKnown() const;
+
+ /// checks if this is a 'value' template <p> PRE: the instance type is known </p>
+ bool isInstanceValue() const;
+
+ /// get the UNO type for instances (primarily (only ?) for 'value' templates) <p> PRE: the instance type is known </p>
+ com::sun::star::uno::Type getInstanceType() const;
+
+ /// get the path where the template is located
+ rtl::OUString getPathString() const;
+
+ /// get the local name of the template
+ rtl::OUString getName() const { return m_aName; }
+
+ /// get the package name of the template
+ rtl::OUString getModule() const { return m_aModule; }
+
+ friend class TemplateImplHelper;
+ };
+
+ /// make a template instance that matches the elements of the given set. Ensures that the element type is known
+ rtl::Reference<Template> makeSetElementTemplate(sharable::SetNode * set, TemplateProvider const& _aProvider);
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGTEMPLATE_HXX_
diff --git a/configmgr/source/inc/tracer.hxx b/configmgr/source/inc/tracer.hxx
new file mode 100644
index 000000000000..fb39aed28ebf
--- /dev/null
+++ b/configmgr/source/inc/tracer.hxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tracer.hxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_TRACER_HXX_
+#define _CONFIGMGR_TRACER_HXX_
+
+#if OSL_DEBUG_LEVEL > 0
+#define CFG_ENABLE_TRACING
+#endif
+
+#ifdef CFG_ENABLE_TRACING
+
+#include <sal/types.h>
+#include <rtl/string.hxx>
+#include <osl/mutex.hxx>
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#ifdef WNT
+#include <sys/timeb.h>
+#else
+#include <sys/time.h>
+#endif
+
+#define OUSTRING2ASCII(rtlOUString) ::rtl::OString((rtlOUString).getStr(), (rtlOUString).getLength(), RTL_TEXTENCODING_ASCII_US).getStr()
+
+#define CFG_TRACE_INFO OTraceIndent aIndent; OConfigTracer::traceInfo
+// FIXME: do something more intelligent here
+// the CFG_TRACE_INFO2 macro exists only to have a unique name of aIndent2
+// so it does not hide aIndent in an outer scope (which would produce a
+// a shadowing warning
+#define CFG_TRACE_INFO2 OTraceIndent aIndent2; OConfigTracer::traceInfo
+#define CFG_TRACE_WARNING OTraceIndent aIndent; OConfigTracer::traceWarning
+#define CFG_TRACE_ERROR OTraceIndent aIndent; OConfigTracer::traceError
+#define CFG_TRACE_INFO_NI OConfigTracer::traceInfo
+#define CFG_TRACE_WARNING_NI OConfigTracer::traceWarning
+#define CFG_TRACE_ERROR_NI OConfigTracer::traceError
+
+namespace configmgr
+{
+
+struct OTracerSetup;
+class OConfigTracer
+{
+ friend class OTraceIndent;
+
+protected:
+ static ::osl::Mutex & getMutex();
+ static OTracerSetup* s_pImpl;
+#ifdef WNT
+ static timeb s_aStartTime;
+#else
+ static timeval s_aStartTime;
+#endif
+
+private:
+ OConfigTracer(); // never implemented, no instantiation of this class allowed, only static members
+
+public:
+ static void traceInfo(const sal_Char* _pFormat, ...);
+#if OSL_DEBUG_LEVEL > 0
+ static void traceWarning(const sal_Char* _pFormat, ...);
+ static void traceError(const sal_Char* _pFormat, ...);
+#endif
+protected:
+ static void implTrace(const sal_Char* _pType, const sal_Char* _pFormat, va_list args);
+ static void startGlobalTimer();
+ static sal_uInt32 getGlobalTimer();
+
+ static void inc();
+ static void dec();
+
+ static void indent();
+
+ static void ensureData();
+ static void ensureInitalized();
+};
+
+class OTraceIndent
+{
+public:
+ OTraceIndent() { OConfigTracer::inc(); }
+ ~OTraceIndent() { OConfigTracer::dec(); }
+};
+
+} // namespace configmgr
+
+#else // !CFG_ENABLE_TRACING
+
+#include <stdio.h>
+
+#define OUSTRING2ASCII(rtlOUString) "nothing"
+
+namespace configmgr {
+inline static void dont_trace(const char*,...) {}
+}
+
+#define CFG_TRACE_INFO dont_trace
+#define CFG_TRACE_INFO2 dont_trace
+#define CFG_TRACE_WARNING dont_trace
+#define CFG_TRACE_ERROR dont_trace
+#define CFG_TRACE_INFO_NI dont_trace
+#define CFG_TRACE_WARNING_NI dont_trace
+#define CFG_TRACE_ERROR_NI dont_trace
+#define CFG_TRACE_TO_DEVICE dont_trace
+
+#endif // CFG_ENABLE_TRACING
+
+#endif // _CONFIGMGR_TRACER_HXX_
+
diff --git a/configmgr/source/inc/tree.hxx b/configmgr/source/inc/tree.hxx
new file mode 100644
index 000000000000..f37a0cc2f443
--- /dev/null
+++ b/configmgr/source/inc/tree.hxx
@@ -0,0 +1,668 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile$
+ * $Revision$
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGNODEIMPL_HXX_
+#define CONFIGMGR_CONFIGNODEIMPL_HXX_
+
+#include "change.hxx"
+#include "configpath.hxx"
+#include "template.hxx"
+#include "utility.hxx"
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include <osl/diagnose.h>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+ namespace node { struct Attributes; }
+ namespace sharable { union Node; }
+ namespace view { class ViewStrategy; }
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ class AnyNodeRef;
+ class ElementTree;
+ class GroupNodeImpl;
+ class NodeChange;
+ class NodeChanges;
+ class NodeImpl;
+ class NodeRef;
+ class SetNodeImpl;
+ class TemplateProvider;
+ class Tree;
+ class ValueElementNodeImpl;
+ class ValueMemberNode;
+ class ValueRef;
+//-----------------------------------------------------------------------------
+ // WARNING: a similar item is in noderef.hxx
+ const unsigned int c_TreeDepthAll = ~0u;
+
+//-----------------------------------------------------------------------------
+ inline
+ unsigned int& incDepth(unsigned int& rDepth)
+ {
+ if (rDepth != c_TreeDepthAll) ++rDepth;
+ return rDepth;
+ }
+
+ inline
+ unsigned int& decDepth(unsigned int& rDepth)
+ {
+ OSL_ENSURE(rDepth != 0,"Cannot decrement zero depth");
+ if (rDepth != c_TreeDepthAll && rDepth != 0) --rDepth;
+ return rDepth;
+ }
+
+ inline
+ unsigned int childDepth(unsigned int nDepth)
+ { return decDepth(nDepth); }
+
+ inline
+ unsigned int parentDepth(unsigned int nDepth)
+ { return incDepth(nDepth); }
+
+ inline
+ unsigned int remainingDepth(unsigned int nOuterDepth, unsigned int nRelativeDepth)
+ {
+ OSL_ENSURE(nRelativeDepth != c_TreeDepthAll,"RelativeDepth can't be infinite");
+ OSL_ENSURE(nRelativeDepth <= nOuterDepth,"ERROR: RelativeDepth is larger than enclosing depth");
+
+ unsigned int nInnerDepth = (nOuterDepth == c_TreeDepthAll) ? nOuterDepth :
+ (nRelativeDepth < nOuterDepth) ? nOuterDepth-nRelativeDepth :
+ 0;
+ return nInnerDepth;
+ }
+ //-------------------------------------------------------------------------
+
+ /// interface for a class that can be used to do some operation on a set of <type>NodeRef</type>s and <type>ValueRef</type>s.
+ struct NodeVisitor
+ {
+ /// returned from <method>handle</method> to indicate whether the operation is complete or should continue
+ enum Result { DONE, CONTINUE };
+ /// do the operation on <var>aNode</var>. needs to be implemented by concrete visitor classes
+ virtual Result handle(rtl::Reference< Tree > const& aTree, NodeRef const& aNode) = 0;
+ /// do the operation on <var>aValue</var>. needs to be implemented by concrete visitor classes
+ virtual Result handle(rtl::Reference< Tree > const& aTree, ValueRef const& aValue) = 0;
+ protected:
+ virtual ~NodeVisitor() {}
+ };
+//-----------------------------------------------------------------------------
+
+// class Node Impl
+//-----------------------------------------------------------------------------
+
+ /** is the Implementation class for class <type>Node</type>, held inside a <type>Tree</type>.
+ <p> Implements some functionality common to all node types.
+ </p>
+ <p> Otherwise it provides (not really typesafe) access to a
+ <type scope='configmgr::configuration::NodeType>NodeImpl</type> which implements
+ functionality for a node of a given type
+ (as given by a <type scope='configmgr::configuration::NodeType>Enum</type> value).
+ </p>
+ */
+ class NodeData
+ {
+ rtl::Reference<NodeImpl> m_pSpecificNode;
+ rtl::OUString m_aName_; // cached for better performance
+ unsigned int m_nParent;
+ public:
+ NodeData(rtl::Reference<NodeImpl> const& aSpecificNodeImpl, rtl::OUString const& aName, unsigned int nParent);
+
+ void rebuild(rtl::Reference<view::ViewStrategy> const& _xNewStrategy, sharable::Node * _aNewData);
+ // COMMON: information
+ rtl::OUString getName() const { return m_aName_; }
+ unsigned int getParent() const { return m_nParent; }
+
+ // change management
+ public:
+ // BASIC NODE: access to common attributes
+ NodeImpl & nodeImpl() { return implGetNodeImpl(); }
+ NodeImpl const & nodeImpl() const { return implGetNodeImpl(); }
+
+ // SET: access to child elements
+ bool isSetNode() const;
+ SetNodeImpl& setImpl() { return implGetSetImpl(); }
+ SetNodeImpl const& setImpl() const { return implGetSetImpl(); }
+
+ // VALUES: access to data
+ bool isValueElementNode() const;
+ ValueElementNodeImpl& valueElementImpl() { return implGetValueImpl(); }
+ ValueElementNodeImpl const& valueElementImpl() const { return implGetValueImpl(); }
+
+ // GROUP: access to children
+ bool isGroupNode() const;
+ GroupNodeImpl& groupImpl() { return implGetGroupImpl(); }
+ GroupNodeImpl const&groupImpl() const { return implGetGroupImpl(); }
+
+ // access helper
+ public:
+ sharable::Node * getOriginalNodeAccess() const;
+
+ private:
+ NodeImpl& implGetNodeImpl() const;
+ SetNodeImpl& implGetSetImpl() const;
+ GroupNodeImpl& implGetGroupImpl() const ;
+ ValueElementNodeImpl& implGetValueImpl() const ;
+ };
+//-----------------------------------------------------------------------------
+ /** represents a hierarchy of config entries (identified by <type>NodeRef</type>s and <type>ValueRef</type>s)
+
+ <p>Examples for trees include</p>
+ <ulist>
+ <li>A module tree (for a specific set of parameters).</li>
+ <li>An updating tree (for a part of the whole).</li>
+ <li>A set element (updating or not), which could be detached.</li>
+ <ulist>
+ <p> Holds a list of <type>Node</type> which it allows to access by
+ <type>unsigned int</type> (which is basically a one-based index).
+ </p>
+ <p> Also provides for navigation to the context this tree is located in
+ </p>
+ */
+ class Tree : public salhelper::SimpleReferenceObject
+ {
+ friend class view::ViewStrategy;
+ protected:
+ // Construction
+ /// creates a Tree for a detached, virgin tree
+ Tree( );
+
+ /// creates a Tree with a parent tree
+ Tree(Tree& rParentTree, unsigned int nParentNode);
+
+ virtual ~Tree() = 0;
+
+ /// fills this Tree starting from _aRootNode, using the given factory and the tree's template provider
+ void build(rtl::Reference<view::ViewStrategy> const& _xStrategy, sharable::Node * _aRootNode, unsigned int nDepth, TemplateProvider const& aTemplateProvider);
+
+ void rebuild(rtl::Reference<view::ViewStrategy> const& _xNewStrategy, sharable::Node * _aNewData);
+
+ public:
+ // realeses the data this refers to
+ virtual void disposeData();
+
+ // Context Access
+ /// gets the path to the root node of this tree
+ AbsolutePath getRootPath() const;
+ /// gets the tree of parent node of this tree
+ Tree* getContextTree() { return m_pParentTree; }
+ /// gets the tree of parent node of this tree
+ Tree const *getContextTree() const { return m_pParentTree; }
+ /// gets the offset of parent node of this tree within its tree
+ unsigned int getContextNode() const { return m_nParentNode; }
+
+ // Node Collection information
+ /// checks whether <var>nNode</var> is a valid node offset in this tree
+ bool isValidNode(unsigned int nNode) const;
+
+ bool isRootNode(NodeRef const & node) const;
+
+ NodeRef getRootNode() const;
+
+ NodeRef getContextNodeRef() const;
+
+ bool isValidValueNode(ValueRef const & value);
+
+#if OSL_DEBUG_LEVEL > 0
+ bool isValidAnyNode(AnyNodeRef const & node);
+#endif
+
+ /// checks whether the node has any element nodes (of its own)
+ bool hasElements(NodeRef const & node);
+
+ bool hasElement(NodeRef const & node, rtl::OUString const & name);
+
+ bool hasElement(NodeRef const & node, Path::Component const & name);
+
+ /** gets the element with the given name of the given node
+ <p>PRE: <code>hasElement(node, name)</code></p>
+ <p>If there is no such element, may return an empty node or
+ raise an exception (?)</p>
+
+ @throws InvalidName
+ if name is not a valid child name for this node
+ */
+ rtl::Reference< ElementTree > getElement(
+ NodeRef const & node, rtl::OUString const & name);
+
+ /** gets the element with the given name of the given node, if it is
+ available
+ <p>PRE: <code>hasElement(node, name)</code></p>
+ <p>If there is no such element, may return an empty node or
+ raise an exception (?)</p>
+ <p>Caution: May miss existing children unless hasChild/getChild
+ has been called before.</p>
+
+ @throws InvalidName
+ if name is not a valid child name for this node
+ */
+ rtl::Reference< ElementTree > getAvailableElement(
+ NodeRef const & node, rtl::OUString const & name);
+
+ /// checks whether the node has any child nodes (in this tree)
+ bool hasChildren(NodeRef const & node);
+
+ bool hasChildValue(
+ NodeRef const & node, rtl::OUString const & name);
+
+ bool hasChildNode(NodeRef const & node, rtl::OUString const & name);
+
+ bool hasChild(NodeRef const & node, rtl::OUString const & name);
+
+ /** gets the child value (in this tree) with the given name of the
+ given node
+ <p>PRE: <code>hasChildValue(node, name)</code></p>
+ <P>If there is no such node, may return an empty node or raise
+ an exception (?)</p>
+
+ @throws InvalidName
+ if <var>aName</var> is not a valid child name for this node
+ */
+ ValueRef getChildValue(
+ NodeRef const & node, rtl::OUString const & name);
+
+ NodeRef getChildNode(
+ NodeRef const & node, rtl::OUString const & name);
+
+ AnyNodeRef getAnyChild(
+ NodeRef const& node, rtl::OUString const & name);
+
+ node::Attributes getAttributes(NodeRef const & node);
+
+ node::Attributes getAttributes(AnyNodeRef const & node);
+
+ node::Attributes getAttributes(ValueRef const & value);
+
+ com::sun::star::uno::Type getUnoType(ValueRef const & value);
+
+ /// return the parent of the given node (or an empty node, if it is
+ /// the tree root)
+ NodeRef getParent(NodeRef const & node);
+
+ /// return the parent of the given value (or an empty node, if it is
+ /// the tree root)
+ NodeRef getParent(ValueRef const & value);
+
+ AbsolutePath getAbsolutePath(NodeRef const & node);
+
+ /// retrieves the current value for the given node, provided there
+ /// is one and it is available (only works for value nodes)
+ com::sun::star::uno::Any getNodeValue(ValueRef const & value);
+
+ /// checks whether the given node has a default value (only works
+ /// for value nodes)
+ bool hasNodeDefault(ValueRef const & value);
+
+ /// checks whether the given node assumes its default value (only
+ /// works for value nodes)
+ bool isNodeDefault(ValueRef const & value);
+
+ /// checks whether the given node has a default state
+ bool hasNodeDefault(NodeRef const & node);
+
+ /// checks whether the given node assumes its default state
+ bool isNodeDefault(NodeRef const & node);
+
+ /// checks whether the given node has a default state
+ bool hasNodeDefault(AnyNodeRef const & node);
+
+ /// checks whether the given node assumes its default state
+ bool isNodeDefault(AnyNodeRef const & node);
+
+ /// checks whether the default values are available for the children
+ /// of the given node (if applicable)
+ bool areValueDefaultsAvailable(NodeRef const & node);
+
+ /// retrieves the default value for the given node, provided there
+ /// is one and it is available (only works for value nodes)
+ com::sun::star::uno::Any getNodeDefaultValue(
+ ValueRef const & value);
+
+ bool hasChanges();
+
+ /// lists any pending changes on this tree
+ bool collectChanges(NodeChanges & changes);
+
+ void integrate(
+ NodeChange & change, NodeRef const & node, bool local);
+
+ void integrate(
+ NodeChanges & changes, NodeRef const & node, bool local);
+
+ NodeVisitor::Result visit(
+ NodeRef const & node, NodeVisitor & visitor)
+ { return visitor.handle(this, node); }
+
+ NodeVisitor::Result visit(
+ ValueRef const & value, NodeVisitor & visitor)
+ { return visitor.handle(this, value); }
+
+ /** lets the given visitor visit the child nodes of the given node
+
+ The order in which nodes are visited is repeatable (but
+ currently unspecified). Visits nodes until NodeVisitor::DONE is
+ returned, then returns NodeVisitor::DONE. If all visits return
+ NodeVisitor::CONTINUE, returns NodeVisitor::CONTINUE. If no
+ children are present, returns NodeVisitor::CONTINUE.
+ */
+ NodeVisitor::Result dispatchToChildren(
+ NodeRef const & node, NodeVisitor & visitor);
+
+ NodeRef getNode(unsigned int offset) const;
+
+ rtl::Reference< Template > extractElementInfo(NodeRef const & node);
+
+ /// gets the depth that is available in this tree (due to the original request)
+ unsigned int getAvailableDepth() const { return m_nDepth; }
+
+ /// gets the depth that is available in this tree within the given node
+ unsigned int getRemainingDepth(unsigned int nNode) const
+ { return remainingDepth(getAvailableDepth(),depthTo(nNode)); }
+
+ // Node Collection navigation
+ /** gets the simple name of the node <var>nNode</var>
+ <p>PRE: <code>isValidNode(nNode)</code>
+ </p>
+ */
+ rtl::OUString getSimpleNodeName(unsigned int nNode) const;
+
+ /** gets the simple name of the root node (i.e. of the tree as a whole)
+ */
+ virtual rtl::OUString getSimpleRootName() const;
+
+ /** gets the full name of the root node
+ */
+ Path::Component getExtendedRootName() const;
+
+ /** gets the number of hierarchy levels from the root node to node <var>nNode</var>
+ in this tree
+ <p>In particular <code>depthTo(N) == 0</code> if <code>N == root()</code>
+ </p>
+ <p>PRE: <code>isValidNode(nNode)</code>
+ </p>
+ */
+ unsigned int depthTo(unsigned int nNode) const;
+
+ /// append the local path (relative to root) to a node to a collection of names
+ void prependLocalPathTo(unsigned int nNode, Path::Rep& rNames);
+
+ // check whether defaults are available
+ bool hasDefaults(unsigned int _nNode) const;
+ public:
+ enum { ROOT = 1 }; /// base of <type>unsigned int</type>s used in this class
+
+ /** gets the <type>unsigned int</type> of the parent node <var>nNode</var> in this tree
+ or 0 (zero) if it is the root node
+ <p>PRE: <code>isValidNode(nNode)</code>
+ </p>
+ */
+ unsigned int parent_(unsigned int nNode) const;
+
+ // Node iteration and access
+ /** gets the <type>unsigned int</type> of the first child node
+ of node <var>nParent</var> in this tree (in list order)
+ or 0 (zero) if it has no children in this tree
+ <p>PRE: <code>isValidNode(nParent)</code>
+ </p>
+ */
+ unsigned int firstChild_ (unsigned int nParent) const;
+
+ /** gets the <type>unsigned int</type> of the first child node
+ of node <var>nParent</var> that is after
+ node <var>nNode</var> in this tree (in list order)
+ or 0 (zero) if there is no such node
+ <p>if <code>nStartAfter == 0</code> searching starts at the beginning
+ </p>
+ <p>PRE: <code>isValidNode(nParent)</code>
+ </p>
+ <p>PRE: <code>isValidNode(nStartAfter) || nStartAfter == 0</code>
+ </p>
+ */
+ unsigned int findNextChild_(unsigned int nParent, unsigned int nStartAfter) const;
+
+ /** gets the <type>unsigned int</type> of the first (and only) child node
+ of node <var>nParent</var> in this tree (in list order)
+ where the name of the node is <var>aName</var>,
+ or 0 (zero) if there is no such node
+ <p>PRE: <code>isValidNode(nParent)</code>
+ </p>
+ */
+ unsigned int findChild_(unsigned int nParent, rtl::OUString const& aName) const;
+
+ // Node Collection access
+ /// get the number of nodes in this tree
+ unsigned int nodeCount() const;
+
+ /// get the <type>NodeData</type> for node <var>nNode</var> in this tree
+ NodeData* nodeData(unsigned int nNode);
+ /// get the <type>NodeData</type> for node <var>nNode</var> in this tree
+ NodeData const* nodeData(unsigned int nNode) const;
+ /// get the <type>NodeData</type> for node <var>nNode</var> in this tree
+ NodeImpl& nodeImpl(unsigned int nNode) { return nodeData(nNode)->nodeImpl(); }
+ /// get the <type>NodeData</type> for node <var>nNode</var> in this tree
+ NodeImpl const& nodeImpl(unsigned int nNode) const { return nodeData(nNode)->nodeImpl(); }
+
+ unsigned int nodeOffset(NodeData const & rNodeData) const;
+
+ // Behavior
+ rtl::Reference< view::ViewStrategy > getViewBehavior() const;
+ protected:
+ // immediate commit
+/* // implementation of commit protocol
+ void commitDirect();
+
+ void implCommitDirectFrom(unsigned int nNode);
+*/
+ void implRebuild(unsigned int nNode, sharable::Node * _aNewData);
+
+ protected:
+ /// set a new parent context for this tree
+ void setContext(Tree* pParentTree, unsigned int nParentNode);
+ /// set no-parent context for this tree
+ void clearContext();
+
+ inline // is protected and should be used only in the implementation
+ rtl::OUString implGetOriginalName(unsigned int nNode) const;
+
+ private:
+ /// get the full name of the root of this tree
+ virtual Path::Component doGetRootName() const = 0;
+
+ /// prepend the absolute path to the root of this tree (no context use)
+ virtual void doFinishRootPath(Path::Rep& rPath) const = 0;
+
+ ValueMemberNode getMemberNode(ValueRef const & value);
+
+ rtl::Reference<view::ViewStrategy> m_xStrategy;
+ std::vector<NodeData> m_aNodes;
+ Tree* m_pParentTree;
+ unsigned int m_nParentNode;
+ unsigned int m_nDepth;
+
+ /// prepend the absolute path to the root of this tree (using context if present)
+ void implPrependRootPath(Path::Rep& rPath) const;
+
+ friend class TreeImplBuilder;
+ };
+
+ /// checks, if tree represents a real tree
+ bool isEmpty(Tree * tree);
+//-----------------------------------------------------------------------------
+
+ class ElementTree : public Tree
+ {
+ public:
+
+ /// creates a Tree for a detached, virgin instance of <var>aTemplate</var> (always will be direct)
+ ElementTree(rtl::Reference< data::TreeSegment > const& _aElementData, rtl::Reference<Template> aTemplate, TemplateProvider const& aTemplateProvider );
+
+ /** creates a Tree with a parent tree, that (supposedly)
+ is an instance of <var>aTemplateInfo</var>
+ */
+ ElementTree(rtl::Reference<view::ViewStrategy> const& _xStrategy,
+ Tree& rParentTree, unsigned int nParentNode,
+ sharable::TreeFragment * dataTree, unsigned int nDepth,
+ rtl::Reference<Template> aTemplateInfo,
+ TemplateProvider const& aTemplateProvider );
+
+ /** creates a Tree with no parent node, that (supposedly)
+ is an instance of <var>aTemplateInfo</var>
+ */
+ ElementTree(rtl::Reference<view::ViewStrategy> const& _xStrategy,
+ sharable::TreeFragment * dataTree, unsigned int nDepth,
+ rtl::Reference<Template> aTemplateInfo,
+ TemplateProvider const& aTemplateProvider );
+
+ ~ElementTree();
+
+ // realeses the data this refers to
+ virtual void disposeData();
+
+ // rebuilding
+ using Tree::rebuild;
+ void rebuild(rtl::Reference<view::ViewStrategy> const& _xNewStrategy, sharable::TreeFragment * newData);
+
+ // data access
+ sharable::TreeFragment * getOriginalTreeAccess() const { return m_aDataAddress; }
+
+ // Tree information
+ virtual rtl::OUString getSimpleRootName() const;
+ /// checks whether this is an instance of a known template
+ bool isTemplateInstance() const { return !!m_aInstanceInfo.is(); }
+ /// checks whether this is an instance of the given template
+ bool isInstanceOf(rtl::Reference<Template> const& aTemplateInfo) const
+ { return m_aInstanceInfo == aTemplateInfo && aTemplateInfo.is(); }
+ /// retrieves the template that this is an instance of
+ rtl::Reference<Template> getTemplate() const { return m_aInstanceInfo; }
+ /// makes a complete name from a simple name and template information
+ Path::Component makeExtendedName(rtl::OUString const& aSimpleName) const;
+
+ // node control operation
+ /// check if this is a free-floating tree
+ bool isFree() const { return m_aOwnData.is(); }
+ /// transfer ownership to the given set
+ void attachTo(sharable::SetNode * updatableSetNode, rtl::OUString const& aElementName);
+ /// tranfer ownership from the given set
+ void detachFrom(sharable::SetNode * updatableSetNode, rtl::OUString const& aElementName);
+
+ /// take ownership of the given tree (which must not already be the one in use)
+ void takeTreeAndRebuild(rtl::Reference< data::TreeSegment > const& _aElementData);
+ /// take ownership of the given tree (which must already be the one in use)
+ void takeTreeBack(rtl::Reference< data::TreeSegment > const& _aElementData);
+
+ /// release ownership
+ rtl::Reference< data::TreeSegment > releaseOwnedTree();
+
+ // context operation
+ /// set a new root name
+ void renameTree(rtl::OUString const& aNewName);
+ /// set a new parent context for this tree
+ void moveTree(Tree* pParentTree, unsigned int nParentNode);
+ /// set no-parent context for this tree
+ void detachTree();
+
+ private:
+ static bool isUpdatableSegment(Tree& _rTree);
+
+ virtual Path::Component doGetRootName() const;
+
+ virtual void doFinishRootPath(Path::Rep& rPath) const;
+ private:
+ rtl::Reference<Template> const m_aInstanceInfo;
+ rtl::OUString m_aElementName;
+ sharable::TreeFragment * m_aDataAddress;
+ rtl::Reference< data::TreeSegment > m_aOwnData;
+ };
+//-----------------------------------------------------------------------------
+ inline
+ bool Tree::isValidNode(unsigned int nNode) const
+ {
+ return ROOT <= nNode && nNode < nodeCount() + ROOT;
+ }
+ //---------------------------------------------------------------------
+ inline
+ unsigned int Tree::nodeCount() const
+ {
+ return m_aNodes.size();
+ }
+ //---------------------------------------------------------------------
+ inline
+ NodeData* Tree::nodeData(unsigned int nNode)
+ {
+ if (nNode == 0) return NULL;
+ OSL_ASSERT(isValidNode(nNode));
+ return &m_aNodes[nNode - ROOT];
+ }
+ //---------------------------------------------------------------------
+ inline
+ NodeData const* Tree::nodeData(unsigned int nNode) const
+ {
+ if (nNode == 0) return NULL;
+ OSL_ASSERT(isValidNode(nNode));
+ return &m_aNodes[nNode - ROOT];
+ }
+ //---------------------------------------------------------------------
+ inline
+ unsigned int Tree::nodeOffset(NodeData const & rNode) const
+ {
+ unsigned int nOffset = ROOT + (&rNode - &m_aNodes[0]);
+ OSL_ASSERT(isValidNode(nOffset));
+ return nOffset;
+ }
+
+//-----------------------------------------------------------------------------
+// helper for other impl classes
+//-----------------------------------------------------------------------------
+#if OSL_DEBUG_LEVEL > 0
+ struct ElementHelper
+ {
+ static
+ com::sun::star::uno::Type getUnoType(rtl::Reference< ElementTree > const& aElement);
+ };
+#endif
+//-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
+#endif // CONFIGMGR_CONFIGNODEIMPL_HXX_
diff --git a/configmgr/source/inc/treeactions.hxx b/configmgr/source/inc/treeactions.hxx
new file mode 100644
index 000000000000..e67c4eb33bba
--- /dev/null
+++ b/configmgr/source/inc/treeactions.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treeactions.hxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_TREEACTIONS_HXX_
+#define _CONFIGMGR_TREEACTIONS_HXX_
+
+#include "change.hxx"
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+//..........................................................................
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+
+//==========================================================================
+//= OChangeActionCounter
+//==========================================================================
+/** collects meta data about a changes tree
+*/
+struct OChangeActionCounter : public ChangeTreeAction
+{
+ sal_Int32 nValues, nAdds, nRemoves;
+
+ OChangeActionCounter() :nValues(0), nAdds(0), nRemoves(0) {}
+
+ virtual void handle(ValueChange const& aValueNode);
+ virtual void handle(AddNode const& aAddNode);
+ virtual void handle(RemoveNode const& aRemoveNode);
+ virtual void handle(SubtreeChange const& aSubtree);
+
+ sal_Bool hasChanges() const {return nValues || nAdds || nRemoves;}
+};
+
+// ===================================================================
+// = CollectNames
+// ===================================================================
+class CollectNames : public NodeAction
+{
+public:
+ std::vector<rtl::OUString> const& list() const { return aList; }
+
+ CollectNames() : aList() {}
+
+ void handle(ValueNode const& aValue) { add(aValue); }
+ void handle(ISubtree const& m_aSubtree) { add(m_aSubtree); }
+
+ void add(INode const& aNode)
+ {
+ aList.push_back(aNode.getName());
+ }
+private:
+ std::vector<rtl::OUString> aList;
+};
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+#endif // _CONFIGMGR_TREEACTIONS_HXX_
+
+
diff --git a/configmgr/source/inc/treechangefactory.hxx b/configmgr/source/inc/treechangefactory.hxx
new file mode 100644
index 000000000000..eb51f650bb2f
--- /dev/null
+++ b/configmgr/source/inc/treechangefactory.hxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treechangefactory.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_TREE_CHANGEFACTORY_HXX
+#define CONFIGMGR_TREE_CHANGEFACTORY_HXX
+
+#include "change.hxx"
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+
+namespace configmgr
+{
+
+ namespace uno = ::com::sun::star::uno;
+
+ //==========================================================================
+
+ class OTreeChangeFactory
+ {
+ public:
+ //-----------------------------------------------
+ std::auto_ptr<SubtreeChange> createSetNodeChange(
+ rtl::OUString const& _aName,
+ rtl::OUString const& _aTemplateName,
+ rtl::OUString const& _aTemplateModule,
+ node::Attributes _aAttrs,
+ bool _bToDefault = false);
+ //-----------------------------------------------
+
+ //= Set Changes ============================================================
+ std::auto_ptr<AddNode> createAddNodeChange(
+ rtl::Reference< data::TreeSegment > const & _aNewTree,
+ rtl::OUString const& _aName,
+ bool _bToDefault = false);
+
+ //-----------------------------------------------
+ std::auto_ptr<RemoveNode> createRemoveNodeChange(
+ rtl::OUString const& _aName,
+ bool _bToDefault = false);
+
+ //= special case: Dummy ISubtree ============================================================
+ static std::auto_ptr<SubtreeChange> createDummyChange(
+ rtl::OUString const& _aName,
+ rtl::OUString const& _aElementTypeName);
+
+ //-----------------------------------------------
+ };
+
+ OTreeChangeFactory& getDefaultTreeChangeFactory();
+ //==========================================================================
+ inline
+ std::auto_ptr<Change> base_ptr(std::auto_ptr<SubtreeChange> pChange)
+ { return std::auto_ptr<Change>(pChange.release()); }
+ //==========================================================================
+ inline
+ std::auto_ptr<Change> base_ptr(std::auto_ptr<ValueChange> pChange)
+ { return std::auto_ptr<Change>(pChange.release()); }
+ //==========================================================================
+ inline
+ std::auto_ptr<Change> base_ptr(std::auto_ptr<AddNode> pChange)
+ { return std::auto_ptr<Change>(pChange.release()); }
+ //==========================================================================
+ inline
+ std::auto_ptr<Change> base_ptr(std::auto_ptr<RemoveNode> pChange)
+ { return std::auto_ptr<Change>(pChange.release()); }
+ //==========================================================================
+
+ bool isGenericSetElementType(rtl::OUString const& _aElementType);
+ bool isDummySetElementModule(rtl::OUString const& _aElementModule);
+ rtl::OUString getGenericSetElementType();
+ rtl::OUString getDummySetElementModule();
+ //==========================================================================
+
+} // namespace configmgr
+
+#endif
diff --git a/configmgr/source/inc/treechangelist.hxx b/configmgr/source/inc/treechangelist.hxx
new file mode 100644
index 000000000000..56245c3a70aa
--- /dev/null
+++ b/configmgr/source/inc/treechangelist.hxx
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treechangelist.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */
+
+
+#ifndef CONFIGMGR_TREECHANGELIST_HXX
+#define CONFIGMGR_TREECHANGELIST_HXX
+
+#include "change.hxx"
+#include "attributes.hxx"
+#include "configpath.hxx"
+#include "requestoptions.hxx"
+
+namespace configmgr
+{
+
+////////////////////////////////////////////////////////////////////////////////
+
+ //==========================================================================
+ //= TreeChangeList
+ //==========================================================================
+ struct TreeChangeList
+ {
+ TreeChangeList(const RequestOptions& _aOptions,
+ const configuration::AbsolutePath& _rRootPath,
+ const SubtreeChange& _aSubtree,
+ treeop::DeepChildCopy _doDeepCopy)
+ : root(_aSubtree,_doDeepCopy)
+ , m_aLocation(_rRootPath)
+ , m_aOptions(_aOptions)
+ {}
+
+ /** ctor
+ @param _rRootPath path to the root of the whole to-be-updated subtree
+ */
+ TreeChangeList( const RequestOptions& _aOptions,
+ const configuration::AbsolutePath& _rRootPath,
+ const node::Attributes& _rAttr = node::Attributes())
+ : root(_rRootPath.getLocalName().getName(), _rAttr)
+ , m_aLocation(_rRootPath)
+ , m_aOptions(_aOptions)
+ {}
+
+ /** ctor
+ @param _rLocalName relative path within the to-be-updated subtree
+ */
+ TreeChangeList( const RequestOptions& _aOptions,
+ const configuration::AbsolutePath& _rRootPath,
+ rtl::OUString const & _rChildTemplateName,
+ rtl::OUString const & _rChildTemplateModule,
+ const node::Attributes& _rAttr = node::Attributes())
+ : root(_rRootPath.getLocalName().getName(), _rChildTemplateName, _rChildTemplateModule, _rAttr)
+ , m_aLocation(_rRootPath)
+ , m_aOptions(_aOptions)
+ {}
+
+ /** ctor
+ @param _rTreeList list to initialize the path, no childs are copied
+ */
+ TreeChangeList( const TreeChangeList& _rTree, treeop::NoChildCopy _rNoCopy)
+ : root(_rTree.root, _rNoCopy)
+ , m_aLocation(_rTree.m_aLocation)
+ , m_aOptions(_rTree.m_aOptions)
+ {}
+
+ /// is root a change for the module root
+ bool isModuleRootChange() const { return m_aLocation.getDepth() <= 1; }
+
+ /// get the module these changes belong to
+ rtl::OUString getModuleName() const { return m_aLocation.getModuleName(); }
+
+ /// get the full path to the root (location + root-name)
+ void setRootPath(const configuration::AbsolutePath& _rRootPath)
+ { m_aLocation = _rRootPath; }
+
+ /// get the full path to the root (location + root-name)
+ configuration::AbsolutePath const& getRootNodePath() const { return m_aLocation; }
+
+ /// get the full path to the root (location)
+ configuration::AbsolutePath getRootContextPath() const { return m_aLocation.getParentPath(); }
+
+ RequestOptions const & getOptions() const { return m_aOptions; }
+
+ public:
+ SubtreeChange root; // the root of the whole tree of updates
+ private:
+ configuration::AbsolutePath m_aLocation; // absolute path to the parent of the node corresponding to this->root
+ RequestOptions m_aOptions; // options for the tree that is concerned by these changes
+ };
+//----------------------------------------------------------------------------
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/inc/treefragment.hxx b/configmgr/source/inc/treefragment.hxx
new file mode 100644
index 000000000000..4810970d6fb8
--- /dev/null
+++ b/configmgr/source/inc/treefragment.hxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treefragment.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_SHARABLE_TREEFRAGMENT_HXX
+#define INCLUDED_SHARABLE_TREEFRAGMENT_HXX
+
+#include "flags.hxx"
+#include "node.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace sharable
+ {
+ //-----------------------------------------------------------------------------
+ /* a TreeFragment header is interpreted differently, depending on the kind of TreeFragment
+
+ - for a set element
+ name points to the element name (the name in the root node is the template name)
+ parent points to the SetNode that is the parent. The containing treefragment can
+ be recovered from this with some care
+ next points to the next element of the same set. It is null for the last element.
+ state is fully used here
+
+ - for a template tree
+ name points to the template name (same as the name in the root node)
+ component points to the home component name of the template
+ (often the same as 'component' in the component tree)
+ next points to another template TreeFragment. It is null for the last template.
+ state must be 'replaced' here (rarely it might be marked as mandatory)
+
+ - for a component tree
+ name points to the component name (same as the name in the root node)
+ component is equal to name (or NULL ?)
+ next points to another template TreeFragment. It is null if there is no template.
+ state must be either 'defaulted' or 'merged'
+ (it should be marked as mandatory although that is not used yet)
+ */
+ struct TreeFragmentHeader
+ {
+ struct TreeFragment *next; // next sibling set element or template
+ rtl_uString * name; // element-name/template name
+ union // context
+ {
+ union Node *parent; // parent node
+ rtl_uString * component; // component name
+ };
+ sal_uInt16 count; // number of contained nodes
+ sal_uInt8 state;
+ sal_uInt8 reserved;
+ };
+ //-----------------------------------------------------------------------------
+ /* a tree fragment is stored as a variable-sized struct
+ containing a header and a fixed sequence of nodes
+
+ R - - A - - A1
+ | |
+ | - A2
+ |
+ - B
+ |
+ - C - - C1 - - C11
+ | | |
+ | | - C12
+ | |
+ | - C2 - - C21
+ |
+ - D
+
+ is stored as
+
+ H(count = 12) : [R;A;A1;A2;B;C;C1;C11;C12;C2;C21;D]
+ */
+ //-----------------------------------------------------------------------------
+ /* tree fragments are used for: Component trees, Template trees, Set elements
+
+ They are only fragments, as for a TreeFragment a Set is considered a leaf node.
+ Set elements are maintained as a singly linked list that is accessible from the set node
+
+ A cache component has the Root (component tree) TreeFragment at a well-known location.
+ The 'next' element of the component tree points to the list of template TreeFragments
+ used in the component.
+ */
+ struct TreeFragment
+ {
+ TreeFragmentHeader header; // really variable-sized:
+ Node nodes[1]; // nodes[header.count]
+
+ // header info access
+ bool hasDefaultsAvailable() const;
+
+ bool isDefault() const;
+ bool isNew() const;
+
+ bool isNamed(rtl::OUString const & _aName) const;
+
+ rtl::OUString getName() const;
+
+ void setName(rtl::OUString const & name);
+
+ configmgr::node::Attributes getAttributes()const;
+
+ Node * getRootNode() { return nodes; }
+
+ static TreeFragment *allocate(sal_uInt32 nFragments);
+ static void free_shallow( TreeFragment *pFragment );
+ };
+ //-----------------------------------------------------------------------------
+
+ }
+//-----------------------------------------------------------------------------
+}
+
+#endif // INCLUDED_SHARABLE_TREEFRAGMENT_HXX
diff --git a/configmgr/source/inc/treemanager.hxx b/configmgr/source/inc/treemanager.hxx
new file mode 100644
index 000000000000..e37a710ad07a
--- /dev/null
+++ b/configmgr/source/inc/treemanager.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treemanager.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_TREEMANAGER_HXX_
+#define CONFIGMGR_TREEMANAGER_HXX_
+
+#include <memory>
+
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "defaultprovider.hxx"
+#include "confevents.hxx"
+#include "options.hxx"
+#include "autoreferencemap.hxx"
+#include "autoobject.hxx"
+
+namespace configmgr
+{
+ namespace uno = ::com::sun::star::uno;
+
+ namespace backend {
+ class CacheController;
+ class ComponentRequest;
+ class UpdateRequest;
+ }
+ namespace sharable {
+ struct TreeFragment;
+ union Node;
+ }
+
+ //==========================================================================
+ //= TreeManager
+ //==========================================================================
+ class CacheClientAccess;
+ class CacheData;
+ class ConfigChangeBroadcastHelper;
+ class ISubtree;
+ //==========================================================================
+ class TreeManager: public salhelper::SimpleReferenceObject {
+ typedef AutoReferenceMap< RequestOptions, CacheClientAccess, lessRequestOptions> CacheList;
+
+ osl::Mutex m_aCacheControllerMutex;
+ rtl::Reference< backend::CacheController > m_xCacheController;
+
+ rtl::Reference< backend::CacheController > maybeGetBackendCache() SAL_THROW(());
+ rtl::Reference< backend::CacheController > getCacheLoader() SAL_THROW((com::sun::star::uno::RuntimeException));
+ void disposeBackendCache() SAL_THROW(());
+
+ CacheList m_aCacheList; // Map
+ AutoObject< CacheData > m_aTemplates;
+ sal_Bool m_bEnableAsync;
+
+ virtual ~TreeManager();
+
+ public:
+ /** ctor
+ */
+ explicit
+ TreeManager(rtl::Reference< backend::CacheController > const & _xBackend);
+
+ // disposing the cache before destroying
+ void dispose();
+
+ /** requests a node given by it's path. Basicly, this means
+ that the node is fetch from the cache when it contains it else it ask the server
+ system into it's cache.
+ @param _rSubtreePath the path to the node in URI notation.
+ @param _nMinLevels indicates how many tree levels under the node determined by <arg>_rSubtreePath</arg>
+ should be loaded
+ */
+ sharable::Node * requestSubtree(configuration::AbsolutePath const& _rSubtreePath,
+ RequestOptions const& _aOptions
+ ) SAL_THROW((com::sun::star::uno::Exception));
+
+ void updateTree(TreeChangeList& aChanges) SAL_THROW((com::sun::star::uno::Exception));
+
+ void saveAndNotifyUpdate(TreeChangeList const& aChanges) SAL_THROW((com::sun::star::uno::Exception));
+
+ void releaseSubtree(configuration::AbsolutePath const& aSubtreePath,
+ RequestOptions const& _aOptions ) SAL_THROW(());
+
+ void fetchSubtree( configuration::AbsolutePath const& aSubtreePath,
+ RequestOptions const& _xOptions
+ ) SAL_THROW(());
+
+ void refreshAll() SAL_THROW((com::sun::star::uno::Exception));
+ void flushAll() SAL_THROW(());
+ void enableAsync(const sal_Bool& bEnableAsync) SAL_THROW(()) ;
+
+ sal_Bool fetchDefaultData( configuration::AbsolutePath const& aSubtreePath,
+ RequestOptions const& _aOptions
+ ) SAL_THROW((com::sun::star::uno::Exception));
+
+ std::auto_ptr<ISubtree> requestDefaultData(configuration::AbsolutePath const& aSubtreePath,
+ const RequestOptions& _aOptions
+ ) SAL_THROW((com::sun::star::uno::Exception));
+
+ sharable::TreeFragment * requestTemplate( rtl::OUString const& aName, rtl::OUString const& aModule
+ ) SAL_THROW((com::sun::star::uno::Exception));
+
+ // implementation interfaces
+ void refreshSubtree(const configuration::AbsolutePath &_aAbsoluteSubtreePath,
+ const RequestOptions& _aOptions) SAL_THROW((com::sun::star::uno::Exception));
+
+ void addListener(configuration::AbsolutePath const& aName, const RequestOptions& _aOptions, rtl::Reference<INodeListener> const& pListener);
+ void removeListener(const RequestOptions& _aOptions, rtl::Reference<INodeListener> const& pListener);
+
+ void componentCreated(backend::ComponentRequest const & _aComponent) SAL_THROW(());
+ void componentChanged(backend::UpdateRequest const & _anUpdate) SAL_THROW(());
+
+ private:
+ CacheData & getTemplates() { return * m_aTemplates.get(); }
+
+ configuration::AbsolutePath encodeTemplateLocation(rtl::OUString const & _rLogicalTemplateName, rtl::OUString const &_rModule);
+
+ private:
+ rtl::Reference<CacheClientAccess> getCacheAlways(RequestOptions const & _aOptions);
+
+ // disposing
+ void disposeAll();
+
+ void fireChanges(TreeChangeList const& _aChanges, sal_Bool _bError);
+ ConfigChangeBroadcastHelper* getBroadcastHelper(RequestOptions const& _aOptions, bool bCreate);
+ void disposeBroadcastHelper(ConfigChangeBroadcastHelper* pHelper);
+
+ void nodeUpdated(TreeChangeList& _rChanges);
+ };
+
+}
+
+
+#endif
+
diff --git a/configmgr/source/inc/treenodefactory.hxx b/configmgr/source/inc/treenodefactory.hxx
new file mode 100644
index 000000000000..51c41a150820
--- /dev/null
+++ b/configmgr/source/inc/treenodefactory.hxx
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treenodefactory.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_TREE_NODEFACTORY_HXX
+#define CONFIGMGR_TREE_NODEFACTORY_HXX
+
+#include "valuenode.hxx"
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#pragma warning(disable : 4350)
+#endif
+namespace configmgr
+{
+
+ namespace uno = ::com::sun::star::uno;
+
+ //==========================================================================
+
+ class OTreeNodeFactory
+ {
+ public:
+ //= ValueNodes ============================================================
+ std::auto_ptr<ValueNode> createValueNode(
+ rtl::OUString const& aName,
+ uno::Any const& aValue,
+ node::Attributes _aAttrs);
+
+ //-----------------------------------------------
+ std::auto_ptr<ValueNode> createValueNode(
+ rtl::OUString const& aName,
+ uno::Any const& aValue,
+ uno::Any const& aDefault,
+ node::Attributes _aAttrs);
+
+ //-----------------------------------------------
+ std::auto_ptr<ValueNode> createNullValueNode(
+ rtl::OUString const& aName,
+ uno::Type const& aType,
+ node::Attributes _aAttrs);
+
+ //= ISubtree ============================================================
+ std::auto_ptr<ISubtree> createGroupNode(
+ rtl::OUString const& aName,
+ node::Attributes _aAttrs);
+
+ //-----------------------------------------------
+ std::auto_ptr<ISubtree> createSetNode(
+ rtl::OUString const& aName,
+ rtl::OUString const& _rTemplateName,
+ rtl::OUString const& _rTemplateModule,
+ node::Attributes _aAttrs);
+ };
+
+ OTreeNodeFactory& getDefaultTreeNodeFactory();
+ //==========================================================================
+ inline
+ std::auto_ptr<INode> base_ptr(std::auto_ptr<ISubtree> pNode)
+ { return std::auto_ptr<INode>(pNode.release()); }
+ //==========================================================================
+ inline
+ std::auto_ptr<INode> base_ptr(std::auto_ptr<ValueNode> pNode)
+ { return std::auto_ptr<INode>(pNode.release()); }
+ //==========================================================================
+
+
+} // namespace configmgr
+
+#endif
diff --git a/configmgr/source/inc/treesegment.hxx b/configmgr/source/inc/treesegment.hxx
new file mode 100644
index 000000000000..ca8769c82ac8
--- /dev/null
+++ b/configmgr/source/inc/treesegment.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treesegment.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_CONFIGMGR_SOURCE_INC_TREESEGMENT_HXX
+#define INCLUDED_CONFIGMGR_SOURCE_INC_TREESEGMENT_HXX
+
+#include "sal/config.h"
+
+#include <memory>
+
+#include "rtl/ref.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+
+namespace rtl { class OUString; }
+
+namespace configmgr {
+ class INode;
+ namespace sharable { struct TreeFragment; }
+
+ namespace data {
+ // rtl::Reference< TreeSegment > is a reference counted
+ // sharable::TreeFragment *. A null reference is always modeled as an
+ // empty rtl::Reference< TreeSegment >, never as a null fragment.
+ class TreeSegment: public salhelper::SimpleReferenceObject {
+ public:
+ static rtl::Reference< TreeSegment > create(
+ std::auto_ptr< INode > tree, rtl::OUString const & type);
+
+ static rtl::Reference< TreeSegment > create(
+ rtl::OUString const & name, std::auto_ptr< INode > tree);
+
+ static rtl::Reference< TreeSegment > create(
+ sharable::TreeFragment * tree);
+
+ static rtl::Reference< TreeSegment > create(
+ rtl::Reference< TreeSegment > const & tree)
+ { return create(tree.is() ? tree->fragment : 0); }
+
+ sharable::TreeFragment * const fragment; // non-null
+
+ private:
+ TreeSegment(sharable::TreeFragment * tree);
+
+ virtual ~TreeSegment();
+ };
+ }
+}
+
+#endif
diff --git a/configmgr/source/inc/typeconverter.hxx b/configmgr/source/inc/typeconverter.hxx
new file mode 100644
index 000000000000..78150c53a78a
--- /dev/null
+++ b/configmgr/source/inc/typeconverter.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: typeconverter.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_TYPECONVERTER_HXX
+#define CONFIGMGR_TYPECONVERTER_HXX
+
+#include "utility.hxx"
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace configmgr
+{
+ namespace uno = ::com::sun::star::uno;
+ namespace script = ::com::sun::star::script;
+
+ // UNO Type handling
+ uno::Type getSequenceElementType(uno::Type const& rSequenceType);
+
+ uno::Type getBasicType(uno::Type const& rType, bool& bSequence);
+ inline
+ uno::Type getBasicType(uno::Type const& rType)
+ { bool dummy; return getBasicType(rType,dummy); }
+
+ // Any Conversion - uses TypeConverter
+ uno::Any toAny( const uno::Reference< script::XTypeConverter >& xTypeConverter,
+ const ::rtl::OUString& _rValue,
+ const uno::TypeClass& _rTypeClass)
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException));
+
+ rtl::OUString toString(const uno::Reference< script::XTypeConverter >& xTypeConverter, const uno::Any& rValue)
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException));
+
+ // Type conversion
+ ::rtl::OUString toTypeName(const uno::TypeClass& _rTypeClass);
+
+ uno::Type toType(const ::rtl::OUString& _rsType);
+ uno::Type toListType(const ::rtl::OUString& _rsElementType);
+ ::rtl::OUString toTypeName(const uno::Type& _rType);
+
+ inline
+ uno::Type toType(const ::rtl::OUString& _rsSimpleType, bool isList)
+ {
+ return isList ? toListType(_rsSimpleType) : toType(_rsSimpleType);
+ }
+
+ // template names
+ ::rtl::OUString toTemplateName(const uno::Type& _rType);
+ ::rtl::OUString toTemplateName(const uno::TypeClass& _rBasicType, bool bList = false);
+ ::rtl::OUString toTemplateName(const ::rtl::OUString& _rBasicTypeName, bool bList = false);
+
+ uno::Type parseTemplateName(::rtl::OUString const& sTypeName);
+ bool parseTemplateName(::rtl::OUString const& sTypeName, ::rtl::OUString& _rBasicName, bool& bList);
+
+} // namespace configmgr
+
+#endif /* CONFIGMGR_TYPECONVERTER_HXX */
diff --git a/configmgr/source/inc/updatehelper.hxx b/configmgr/source/inc/updatehelper.hxx
new file mode 100644
index 000000000000..87e87ec01609
--- /dev/null
+++ b/configmgr/source/inc/updatehelper.hxx
@@ -0,0 +1,49 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updatehelper.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_UPDATEHELPER_HXX
+#define CONFIGMGR_UPDATEHELPER_HXX
+
+#include "change.hxx"
+
+namespace configmgr {
+ namespace sharable { union Node; }
+
+// apply a already matching set of changes to the target tree
+ void applyUpdateToTree(SubtreeChange& _anUpdateTree, sharable::Node * _aRootNode);
+
+// apply a set of changes to the target tree
+ void applyUpdateWithAdjustmentToTree(SubtreeChange& _anUpdateTree, sharable::Node * _aRootNode);
+
+// apply a set of changes to the target tree, return true, if there are changes found
+ bool createUpdateFromDifference(SubtreeChange& _rResultingUpdateTree, sharable::Node * existingData, ISubtree const & _aNewData);
+}
+
+#endif
diff --git a/configmgr/source/inc/utility.hxx b/configmgr/source/inc/utility.hxx
new file mode 100644
index 000000000000..854974704075
--- /dev/null
+++ b/configmgr/source/inc/utility.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: utility.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_CONFIGMGR_SOURCE_INC_UTILITY_HXX
+#define INCLUDED_CONFIGMGR_SOURCE_INC_UTILITY_HXX
+
+#include "sal/config.h"
+
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+
+#if defined _MSC_VER && _MSC_VER >= 1400
+#pragma warning(disable: 4350)
+ // behavior change: 'member1' called instead of 'member2'
+#endif
+
+namespace configmgr {
+
+ inline rtl_uString * acquireString(rtl::OUString const & string) {
+ rtl_uString_acquire(string.pData);
+ return string.pData;
+ }
+
+}
+
+#endif
diff --git a/configmgr/source/inc/valuenode.hxx b/configmgr/source/inc/valuenode.hxx
new file mode 100644
index 000000000000..6ab8cb96f2d6
--- /dev/null
+++ b/configmgr/source/inc/valuenode.hxx
@@ -0,0 +1,296 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valuenode.hxx,v $
+ * $Revision: 1.32 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_TREE_VALUENODE_HXX
+#define _CONFIGMGR_TREE_VALUENODE_HXX
+
+#include "attributes.hxx"
+#include "anypair.hxx"
+#include <com/sun/star/uno/Any.h>
+#include <rtl/ustring.hxx>
+
+#include <string.h>
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+
+ namespace css = com::sun::star;
+ namespace uno = css::uno;
+
+ class INode;
+ class ISubtree;
+ class ValueNode;
+
+ // helper (tag) class
+ namespace treeop { struct NoChildCopy {}; struct DeepChildCopy {}; enum { ALL_LEVELS = -1 }; }
+ //==========================================================================
+ //= Visitors
+ //==========================================================================
+ struct NodeAction
+ {
+ virtual void handle(ValueNode const&) = 0;
+ virtual void handle(ISubtree const&) = 0;
+
+ void applyToNode(INode const&);
+ void applyToChildren(ISubtree const&);
+ protected:
+ virtual ~NodeAction() {}
+ };
+
+ struct NodeModification
+ {
+ virtual void handle(ValueNode&) = 0;
+ virtual void handle(ISubtree&) = 0;
+
+ void applyToNode(INode&);
+ void applyToChildren(ISubtree&);
+ protected:
+ virtual ~NodeModification() {}
+ };
+
+ class INode
+ {
+ rtl::OUString m_aName;
+ node::Attributes m_aAttributes;
+
+ protected:
+ INode(){}
+
+ void markAsDefault(bool _bDefault = true)
+ {
+ m_aAttributes.markAsDefault(_bDefault);
+ }
+ public:
+ explicit
+ INode(rtl::OUString const& aName, node::Attributes);
+
+ virtual ~INode();
+
+ virtual std::auto_ptr<INode> clone() const = 0;
+ public:
+
+ const rtl::OUString& getName() const { return m_aName; }
+ node::Attributes getAttributes() const { return m_aAttributes; }
+
+ bool isDefault() const { return m_aAttributes.isDefault(); }
+ bool isLocalized() const { return m_aAttributes.isLocalized(); }
+
+ void modifyState(node::State _eNewState);
+ void modifyAccess(node::Access _aAccessLevel);
+ void markMandatory();
+ void markRemovable();
+ void promoteAccessToDefault();
+
+ // to be used with caution. If the node is referenced from somewhere else under it's old name,
+ // you may have problems with this inconsistence
+ void setName(const rtl::OUString& _rNewName) { m_aName = _rNewName; }
+
+ virtual ValueNode* asValueNode();
+ virtual ValueNode const* asValueNode() const;
+ virtual ISubtree* asISubtree();
+ virtual ISubtree const* asISubtree() const;
+
+ // double dispatch support
+ virtual void dispatch(NodeAction&) const = 0;
+ virtual void dispatch(NodeModification&) = 0;
+ };
+
+// -----------------------------------------------------------------------------
+
+ //==========================================================================
+ //= ISubtree
+ //==========================================================================
+ class ISubtree : public INode
+ {
+ sal_Int16 m_nLevel; /// determines if everything is read
+ sal_Int16 m_nDefaultLevels; /// determines if defaults are read
+ rtl::OUString m_sId;
+ rtl::OUString m_sTemplateName; /// path of the template for child instantiation
+ rtl::OUString m_sTemplateModule; /// module of the template for child instantiation
+
+ virtual INode* doGetChild(rtl::OUString const& name) const = 0;
+
+ protected:
+ ISubtree():m_nLevel(0){}
+
+ ISubtree(ISubtree const& other)
+ :INode(other)
+ ,m_nLevel(other.m_nLevel)
+ ,m_nDefaultLevels(other.m_nDefaultLevels)
+ ,m_sId() // do not copy ID while cloning !
+ ,m_sTemplateName(other.m_sTemplateName)
+ ,m_sTemplateModule(other.m_sTemplateModule)
+ {}
+
+ public:
+ // Ctor for group trees
+ ISubtree(const rtl::OUString& aName, const node::Attributes& _rAttrs)
+ :INode(aName, _rAttrs)
+ ,m_nLevel(0)
+ ,m_nDefaultLevels(0)
+ {}
+
+ // Ctor for set trees
+ ISubtree(const rtl::OUString& aName,
+ const rtl::OUString& _rTemplateName,
+ const rtl::OUString& _rTemplateModule,
+ const node::Attributes& _rAttrs)
+ :INode(aName, _rAttrs)
+ ,m_nLevel(0)
+ ,m_nDefaultLevels(0)
+ ,m_sTemplateName(_rTemplateName)
+ ,m_sTemplateModule(_rTemplateModule){}
+
+ INode* getChild(rtl::OUString const& name) { return doGetChild(name); }
+ INode const* getChild(rtl::OUString const& name) const { return doGetChild(name); }
+
+ ISubtree* asISubtree();
+ ISubtree const* asISubtree() const;
+
+ using INode::markAsDefault;
+
+ sal_Int16 getLevel() const { return m_nLevel; }
+
+ void setLevels(sal_Int16 _nLevel,sal_Int16 _nDefaultsLevel);
+
+ bool isSetNode() const { return m_sTemplateName.getLength() != 0; }
+
+ void makeSetNode(rtl::OUString const& _sTemplateName, rtl::OUString const& _sTemplateModule)
+ { m_sTemplateName = _sTemplateName; m_sTemplateModule = _sTemplateModule; }
+
+ rtl::OUString const& getElementTemplateName() const { return m_sTemplateName; }
+ rtl::OUString const& getElementTemplateModule() const { return m_sTemplateModule; }
+
+ virtual INode* addChild(std::auto_ptr<INode> node) =0; // takes ownership
+ virtual ::std::auto_ptr<INode> removeChild(rtl::OUString const& name) =0; // releases ownership
+
+ // Iteration support, stop if (action returns true)
+ virtual void forEachChild(NodeAction& anAction) const = 0;
+ virtual void forEachChild(NodeModification& anAction) = 0;
+
+ // double dispatch support
+ virtual void dispatch(NodeAction& anAction) const { anAction.handle(*this); }
+ virtual void dispatch(NodeModification& anAction) { anAction.handle(*this); }
+ };
+
+ //==========================================================================
+ //= ValueNode
+ //==========================================================================
+ class ValueNode : public INode
+ {
+ AnyPair m_aValuePair;
+ // uno::Type m_aType;
+ // uno::Any m_aValue;
+ // uno::Any m_aDefaultValue;
+
+ public:
+ //ValueNode(){}
+
+ //explicit ValueNode(node::Attributes _aAttrs):INode(_aAttrs){}
+
+ /*
+ ValueNode(rtl::OUString const& aName, node::Attributes _aAttrs)
+ : INode(aName, _aAttrs)
+ , m_aValuePair()
+ {}
+ */
+ ValueNode(rtl::OUString const& aName,uno::Type const& aType, node::Attributes _aAttrs)
+ : INode(aName, _aAttrs)
+ , m_aValuePair(aType)
+ {
+ }
+ ValueNode(rtl::OUString const& aName,uno::Any const& anAny, node::Attributes _aAttrs)
+ : INode(aName, _aAttrs)
+ , m_aValuePair(anAny, selectMember(_aAttrs.isDefault()))
+ {
+ }
+ ValueNode(rtl::OUString const& aName,uno::Any const& anAny,uno::Any const& aDefault, node::Attributes _aAttrs)
+ : INode(aName, _aAttrs)
+ , m_aValuePair(anAny, aDefault)
+ {
+ }
+
+ bool isEmpty() const {return m_aValuePair.isEmpty();}
+ bool isValid() const {return !m_aValuePair.isEmpty();}
+
+ bool isNull() const {return m_aValuePair.isNull();}
+ bool hasUsableDefault() const {return getAttributes().isNullable() || m_aValuePair.hasSecond();}
+
+ uno::Type getValueType() const {return m_aValuePair.getValueType();}
+ uno::Any getValue() const {return m_aValuePair.getValue( selectMember(this->isDefault()) );}
+ uno::Any getUserValue() const {return m_aValuePair.getFirst();}
+ uno::Any getDefault() const {return m_aValuePair.getSecond();}
+
+ bool setValueType(uno::Type const& _aType);
+ bool setValue(uno::Any const& _aValue);
+ void setDefault();
+
+ bool changeDefault(uno::Any const& _aValue);
+ void promoteToDefault();
+
+ virtual std::auto_ptr<INode> clone() const;
+
+ ValueNode* asValueNode();
+ ValueNode const* asValueNode() const;
+ // double dispatch support
+ virtual void dispatch(NodeAction& anAction) const { anAction.handle(*this); }
+ virtual void dispatch(NodeModification& anAction) { anAction.handle(*this); }
+
+ private:
+ static AnyPair::SelectMember selectValue() { return AnyPair::SELECT_FIRST; }
+ static AnyPair::SelectMember selectDeflt() { return AnyPair::SELECT_SECOND; }
+ static AnyPair::SelectMember selectMember(bool bDeflt)
+ { return bDeflt ? AnyPair::SELECT_SECOND : AnyPair::SELECT_FIRST; }
+ };
+ //==========================================================================
+
+ extern bool isLocalizedValueSet(ISubtree const& _aSubtree);
+
+ //==========================================================================
+ //= inlines
+ //==========================================================================
+ inline void NodeAction::applyToNode(INode const& aNode)
+ { aNode.dispatch(*this); }
+ inline void NodeAction::applyToChildren(ISubtree const& aSubtree)
+ { aSubtree.forEachChild(*this); }
+
+ inline void NodeModification::applyToNode(INode& aNode)
+ { aNode.dispatch(*this); }
+ inline void NodeModification::applyToChildren(ISubtree& aSubtree)
+ { aSubtree.forEachChild(*this); }
+
+
+} // namespace configmgr
+
+#endif
diff --git a/configmgr/source/inc/valueref.hxx b/configmgr/source/inc/valueref.hxx
new file mode 100644
index 000000000000..2f2110a0ff3a
--- /dev/null
+++ b/configmgr/source/inc/valueref.hxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valueref.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGVALUEREF_HXX_
+#define CONFIGMGR_CONFIGVALUEREF_HXX_
+
+#include "noderef.hxx"
+
+namespace configmgr
+{
+ namespace node { struct Attributes; }
+
+ namespace configuration
+ {
+ //-------------------------------------------------------------------------
+ class Tree;
+ //-------------------------------------------------------------------------
+
+ /// represents a value node in some tree
+ class ValueRef
+ {
+ public:
+ /// constructs an empty (invalid) node
+ ValueRef();
+
+ ValueRef(rtl::OUString const& aName, unsigned int nParentPos);
+
+ /// copy a node (with reference semantics)
+ ValueRef(ValueRef const& rOther);
+ /// copy a node (with reference semantics)
+ ValueRef& operator=(ValueRef const& rOther);
+
+ void swap(ValueRef& rOther);
+
+ ~ValueRef();
+
+ /// checks, if this represents an existing node
+ inline bool isValid() const;
+
+ bool checkValidState() const;
+
+ rtl::OUString m_sNodeName;
+ unsigned int m_nParentPos;
+ };
+ //-------------------------------------------------------------------------
+
+ /** extract the value from a plain value
+ */
+ inline
+ com::sun::star::uno::Any getSimpleValue(rtl::Reference< Tree > const& aTree, ValueRef const& aNode)
+ { return aTree->getNodeValue( aNode ); }
+
+ //-------------------------------------------------------------------------
+ inline bool ValueRef::isValid() const
+ {
+ OSL_ASSERT( m_nParentPos == 0 || checkValidState() );
+ return m_nParentPos != 0;
+ }
+
+ //-------------------------------------------------------------------------
+
+ class SubNodeID
+ {
+ public:
+ static SubNodeID createEmpty() { return SubNodeID(); }
+ SubNodeID(rtl::Reference< Tree > const& rTree, NodeRef const& rParentNode, rtl::OUString const& aName);
+ SubNodeID(NodeID const& rParentNodeID, rtl::OUString const& aName);
+
+ // comparison
+ // equality
+ friend bool operator==(SubNodeID const& lhs, SubNodeID const& rhs)
+ { return lhs.m_aParentID == rhs.m_aParentID && lhs.m_sNodeName == rhs.m_sNodeName; }
+ // ordering
+ friend bool operator < (SubNodeID const& lhs, SubNodeID const& rhs);
+ // checking
+ bool isValidNode() const;
+ // hashing
+ size_t hashCode() const { return m_aParentID.hashCode() + 5*m_sNodeName.hashCode(); }
+ // containing node this
+ NodeID getParentID() const { return m_aParentID; }
+ // containing node this
+ rtl::OUString getNodeName() const { return m_sNodeName; }
+ private:
+ SubNodeID(); // create an empty one
+ rtl::OUString m_sNodeName;
+ NodeID m_aParentID;
+ };
+ //-------------------------------------------------------------------------
+
+ void getAllChildrenHelper(NodeID const& aNode, std::vector<SubNodeID>& aList);
+
+ //-------------------------------------------------------------------------
+ inline bool operator!=(SubNodeID const& lhs, SubNodeID const& rhs)
+ { return !(lhs == rhs); }
+ //---------------------------------------------------------------------
+
+ inline bool operator>=(SubNodeID const& lhs, SubNodeID const& rhs)
+ { return !(lhs < rhs); }
+ //---------------------------------------------------------------------
+ inline bool operator > (SubNodeID const& lhs, SubNodeID const& rhs)
+ { return (rhs < lhs); }
+ inline bool operator<=(SubNodeID const& lhs, SubNodeID const& rhs)
+ { return !(rhs < lhs); }
+ //-------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGVALUENODE_HXX_
diff --git a/configmgr/source/inc/valuetypeconverter.hxx b/configmgr/source/inc/valuetypeconverter.hxx
new file mode 100644
index 000000000000..d5571550787b
--- /dev/null
+++ b/configmgr/source/inc/valuetypeconverter.hxx
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valuetypeconverter.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_VALUECONVERTER_HXX
+#define CONFIGMGR_VALUECONVERTER_HXX
+
+#include "utility.hxx"
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Type.hxx>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace configmgr
+{
+ namespace uno = ::com::sun::star::uno;
+ namespace script = ::com::sun::star::script;
+
+// -----------------------------------------------------------------------------
+ class ValueConverter
+ {
+ /// TypeConverter is used for converting type from string values
+ uno::Reference< script::XTypeConverter > m_xTypeConverter;
+ /// Value info
+ uno::Type m_aType;
+ rtl::OUString m_sSeparator;
+ bool m_bNull;
+ public:
+ /// construct a value converter with no initial type info
+ ValueConverter(const uno::Reference< script::XTypeConverter > & _xTC)
+ : m_xTypeConverter(_xTC)
+ , m_aType()
+ {
+ implReset();
+ }
+
+ /// construct a value converter with a type
+ ValueConverter(uno::Type const& _aType, const uno::Reference< script::XTypeConverter > & _xTC)
+ : m_xTypeConverter(_xTC)
+ , m_aType(_aType)
+ {
+ implReset();
+ }
+
+ /// provide access to the TypeConverter that is used for converting string format
+ uno::Reference< script::XTypeConverter > const& getTypeConverter() const SAL_THROW(())
+ {
+ return m_xTypeConverter;
+ }
+
+ /// (re)start the converter with the current type
+ void restart()
+ {
+ implReset();
+ }
+
+ /// (re)start the converter with a new type info (or none)
+ void reset(uno::Type const & _aType = uno::Type())
+ {
+ m_aType = _aType;
+ implReset();
+ }
+
+ /// set the NULL state of this converter
+ void setIsNull(bool bNull = true)
+ {
+ m_bNull = bNull;
+ }
+
+ /// set the separator of this converter
+ void setSeparator(rtl::OUString const & _aSeparator)
+ {
+ m_sSeparator = _aSeparator;
+ }
+
+ /// get the (UNO) type
+ bool isTypeSet() const { return m_aType.getTypeClass() != uno::TypeClass_VOID; }
+
+ /// get the (UNO) type
+ uno::Type getType() const { return m_aType; }
+
+ /// is this marked null
+ bool isNull() const { return m_bNull; }
+
+ /// does this have a list type
+ bool isList() const;
+
+ /// does this have a separator set
+ bool hasSeparator() const { return m_sSeparator.getLength() != 0; }
+
+ /// converting a value
+ uno::Any convertToAny(rtl::OUString const& aContent) const
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException));
+
+ /// converting a list
+ uno::Any convertListToAny(uno::Sequence< rtl::OUString > const& aContentList) const
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException));
+
+ /// converting a binary value
+ uno::Sequence<sal_Int8> parseBinary(rtl::OUString const& aBinaryString) const
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException));
+
+ /// splits a string list
+ uno::Sequence< rtl::OUString > splitStringList(rtl::OUString const& aContent) const;
+ private:
+ /// converting a list
+ bool convertListToAny(std::vector< rtl::OUString > const& aContentList, uno::Any& rValue) const
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException));
+
+ /// converting a scalar value
+ bool convertScalarToAny(rtl::OUString const& aContent, uno::Any& rValue) const
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException));
+
+ /// splitting a string list
+ void splitListData(rtl::OUString const& aContent, std::vector< rtl::OUString >& rContentList) const
+ SAL_THROW(());
+ private:
+ void implReset() SAL_THROW(())
+ {
+ m_sSeparator = rtl::OUString();
+ m_bNull = false;
+ }
+ };
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+} // namespace
+
+#endif
diff --git a/configmgr/source/inc/wrapexception.hxx b/configmgr/source/inc/wrapexception.hxx
new file mode 100644
index 000000000000..0a75f626f8ac
--- /dev/null
+++ b/configmgr/source/inc/wrapexception.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: wrapexception.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_WRAPEXCEPTION_HXX
+#define CONFIGMGR_WRAPEXCEPTION_HXX
+
+#include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InstallationIncompleteException.hpp>
+#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/AuthenticationFailedException.hpp>
+#include <com/sun/star/configuration/backend/InvalidAuthenticationMechanismException.hpp>
+#include <com/sun/star/configuration/backend/CannotConnectException.hpp>
+#include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
+
+#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
+#include <com/sun/star/configuration/backend/ConnectionLostException.hpp>
+#include <com/sun/star/configuration/backend/MalformedDataException.hpp>
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/xml/sax/SAXException.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+
+#define WRAP_EXCEPTION( ETyp, Raise ) \
+ catch (ETyp & _e_) { Raise( uno::makeAny(_e_) ); }
+
+#define WRAP_EXCEPTION1( ETyp, Raise, Arg ) \
+ catch (ETyp & _e_) { Raise( uno::makeAny(_e_), (Arg) ); }
+
+#define PASS_EXCEPTION( ETyp ) \
+ catch (ETyp & ) { throw; }
+
+#define WRAP_CONFIGBACKEND_CREATION_EXCEPTIONS( Raise ) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::InsufficientAccessRightsException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::AuthenticationFailedException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::InvalidAuthenticationMechanismException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::CannotConnectException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::BackendSetupException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::BackendAccessException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::MissingBootstrapFileException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::InvalidBootstrapFileException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::InstallationIncompleteException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::CannotLoadConfigurationException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::lang::WrappedTargetException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::lang::WrappedTargetRuntimeException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::lang::DisposedException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::uno::RuntimeException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::uno::Exception, Raise)
+
+#define WRAP_CONFIGBACKEND_EXCEPTIONS( Raise ) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::InsufficientAccessRightsException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::ConnectionLostException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::BackendAccessException, Raise) \
+
+#define WRAP_CONFIGDATA_EXCEPTIONS( Raise ) \
+ WRAP_EXCEPTION(::com::sun::star::configuration::backend::MalformedDataException, Raise) \
+ WRAP_CONFIGBACKEND_EXCEPTIONS( Raise ) \
+ WRAP_EXCEPTION(::com::sun::star::lang::WrappedTargetException, Raise) \
+
+#define WRAP_SAX_EXCEPTIONS( Raise ) \
+ WRAP_EXCEPTION(::com::sun::star::xml::sax::SAXParseException, Raise) \
+ WRAP_EXCEPTION(::com::sun::star::xml::sax::SAXException, Raise) \
+
+#define WRAP_OTHER_EXCEPTIONS( Raise ) \
+ WRAP_EXCEPTION(::com::sun::star::uno::Exception, Raise)
+
+#define WRAP_CONFIGBACKEND_CREATION_EXCEPTIONS1( Raise, Arg ) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::InsufficientAccessRightsException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::AuthenticationFailedException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::InvalidAuthenticationMechanismException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::CannotConnectException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::BackendSetupException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::BackendAccessException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::MissingBootstrapFileException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::InvalidBootstrapFileException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::InstallationIncompleteException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::CannotLoadConfigurationException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::lang::WrappedTargetException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::lang::WrappedTargetRuntimeException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::lang::DisposedException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::uno::RuntimeException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::uno::Exception, Raise, Arg)
+
+#define WRAP_CONFIGBACKEND_EXCEPTIONS1( Raise, Arg ) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::InsufficientAccessRightsException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::ConnectionLostException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::BackendAccessException, Raise, Arg) \
+
+#define WRAP_CONFIGDATA_EXCEPTIONS1( Raise, Arg ) \
+ WRAP_EXCEPTION1(::com::sun::star::configuration::backend::MalformedDataException, Raise, Arg) \
+ WRAP_CONFIGBACKEND_EXCEPTIONS1( Raise, Arg ) \
+ WRAP_EXCEPTION1(::com::sun::star::lang::WrappedTargetException, Raise, Arg) \
+
+#define WRAP_SAX_EXCEPTIONS1( Raise, Arg ) \
+ WRAP_EXCEPTION1(::com::sun::star::xml::sax::SAXParseException, Raise, Arg) \
+ WRAP_EXCEPTION1(::com::sun::star::xml::sax::SAXException, Raise, Arg) \
+
+#define WRAP_OTHER_EXCEPTIONS1( Raise, Arg ) \
+ WRAP_EXCEPTION1(::com::sun::star::uno::Exception, Raise, Arg)
+
+#endif // CONFIGMGR_WRAPEXCEPTION_HXX
diff --git a/configmgr/source/localbe/localdataimportsvc.cxx b/configmgr/source/localbe/localdataimportsvc.cxx
new file mode 100644
index 000000000000..2c207b11fc1a
--- /dev/null
+++ b/configmgr/source/localbe/localdataimportsvc.cxx
@@ -0,0 +1,360 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localdataimportsvc.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "localdataimportsvc.hxx"
+#include "localsinglebackend.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/configuration/backend/XLayerImporter.hpp>
+
+// -----------------------------------------------------------------------------
+#define OUSTRING( constascii ) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(constascii))
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace localbe
+ {
+// -----------------------------------------------------------------------------
+ namespace backend = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+sal_Char const * const aLocalDataImportServices[] =
+{
+ "com.sun.star.configuration.backend.LocalDataImporter",
+ 0,
+ "com.sun.star.configuration.backend.DataImporter",
+ 0
+};
+const ServiceImplementationInfo aLocalDataImportSI =
+{
+ "com.sun.star.comp.configuration.backend.LocalDataImporter",
+ aLocalDataImportServices,
+ aLocalDataImportServices + 3
+};
+// -----------------------------------------------------------------------------
+
+const ServiceRegistrationInfo* getLocalDataImportServiceInfo()
+{ return getRegistrationInfo(& aLocalDataImportSI); }
+// -----------------------------------------------------------------------------
+
+inline
+ServiceInfoHelper LocalDataImportService::getServiceInfo()
+{
+ return & aLocalDataImportSI;
+}
+// -----------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > SAL_CALL instantiateLocalDataImporter
+( uno::Reference< uno::XComponentContext > const& xContext )
+{
+ return * new LocalDataImportService( xContext );
+}
+// -----------------------------------------------------------------------------
+
+LocalDataImportService::LocalDataImportService(uno::Reference< uno::XComponentContext > const & _xContext)
+: m_xServiceFactory(_xContext->getServiceManager(), uno::UNO_QUERY)
+{
+ if (!m_xServiceFactory.is())
+ {
+ rtl::OUString sMessage = OUSTRING("Configuration Importer: Context has no service manager (or interface is missing)");
+ throw lang::NullPointerException(sMessage,NULL);
+ }
+}
+// -----------------------------------------------------------------------------
+
+LocalDataImportService::~LocalDataImportService()
+{}
+// -----------------------------------------------------------------------------
+
+namespace
+{
+// -----------------------------------------------------------------------------
+ struct JobDesc
+ {
+ explicit JobDesc(task::XJob * pJob, const uno::Sequence< beans::NamedValue >& aArguments);
+
+ rtl::OUString aLayerDataUrl;
+ rtl::OUString aImporterService;
+
+ rtl::OUString aComponent;
+ rtl::OUString aEntity;
+
+ uno::Reference< backend::XLayer > xLayerFilter;
+
+ sal_Bool overwrite;
+ sal_Bool truncate;
+
+ sal_Bool use_component;
+ sal_Bool use_entity;
+ sal_Bool use_overwrite;
+ sal_Bool use_truncate;
+ };
+ // -----------------------------------------------------------------------------
+
+ JobDesc::JobDesc(task::XJob * pJob, const uno::Sequence< beans::NamedValue >& aArguments)
+ : aLayerDataUrl()
+ , aImporterService()
+ , aComponent()
+ , aEntity()
+ , xLayerFilter()
+ , overwrite(true)
+ , truncate(false)
+ , use_component(false)
+ , use_entity(false)
+ , use_overwrite(false)
+ , use_truncate(false)
+ {
+ sal_Int16 const nCount = static_cast<sal_Int16>(aArguments.getLength());
+
+ if (sal_Int32(nCount) != aArguments.getLength())
+ {
+ rtl::OUString sMessage = OUSTRING("Too many arguments for LocalDataImporter Job");
+ throw lang::IllegalArgumentException(sMessage,pJob,0);
+ }
+
+ for (sal_Int16 i=0; i < nCount; ++i)
+ {
+ sal_Bool bKnown = false;
+ sal_Bool bGood = false;
+
+ if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("LayerDataUrl")))
+ {
+ bKnown = true;
+ bGood = (aArguments[i].Value >>= aLayerDataUrl);
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ImporterService")))
+ {
+ bKnown = true;
+ bGood = (aArguments[i].Value >>= aImporterService);
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Component")))
+ {
+ bKnown = true;
+ bGood = (aArguments[i].Value >>= aComponent);
+ use_component = bGood && (aComponent.getLength() != 0);
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Entity")))
+ {
+ bKnown = true;
+ bGood = (aArguments[i].Value >>= aEntity);
+ use_entity = bGood && (aEntity.getLength() != 0);
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("LayerFilter")))
+ {
+ bKnown = true;
+ bGood = (aArguments[i].Value >>= xLayerFilter);
+ if (xLayerFilter.is() && !uno::Reference<lang::XInitialization>::query(xLayerFilter).is())
+ bGood = false;
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("OverwriteExisting")))
+ {
+ bKnown = true;
+ bGood = (aArguments[i].Value >>= overwrite);
+ use_overwrite = bGood;
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("TruncateExisting")))
+ {
+ bKnown = true;
+ bGood = (aArguments[i].Value >>= truncate);
+ use_truncate = bGood;
+ }
+
+ if (!bGood)
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("LocalDataImportService - Illegal argument: ");
+ if (bKnown)
+ sMsg.appendAscii("Wrong value type for argument '");
+ else
+ sMsg.appendAscii("Unknown argument '");
+
+ sMsg.append(aArguments[i].Name).appendAscii("'.");
+
+ throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),pJob,i+1);
+ }
+ }
+ if (aLayerDataUrl.getLength() == 0)
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("LocalDataImportService - Missing argument: ");
+ sMsg.appendAscii("No data URL available");
+ throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),pJob,0);
+ }
+ if (aImporterService.getLength() == 0)
+ {
+ if ( (use_truncate && truncate) || (use_overwrite && !overwrite) )
+ aImporterService = OUSTRING("com.sun.star.configuration.backend.CopyImporter");
+ else
+ aImporterService = OUSTRING("com.sun.star.configuration.backend.MergeImporter");
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ static
+ inline
+ uno::Type getOverwriteFailedExceptionType()
+ {
+ lang::IllegalAccessException const * const selected = 0;
+ return ::getCppuType(selected);
+ }
+// -----------------------------------------------------------------------------
+}
+// -----------------------------------------------------------------------------
+// XJob
+
+uno::Any SAL_CALL
+ LocalDataImportService::execute( const uno::Sequence< beans::NamedValue >& Arguments )
+ throw (lang::IllegalArgumentException, uno::Exception, uno::RuntimeException)
+{
+ JobDesc const aJob(this,Arguments);
+
+ uno::Reference< lang::XMultiServiceFactory > aFactory = this->getServiceFactory();
+
+ uno::Reference< backend::XLayer > xLayer = aJob.use_component ?
+ LocalSingleBackend::createSimpleLayer(aFactory,aJob.aLayerDataUrl, aJob.aComponent ):
+ LocalSingleBackend::createSimpleLayer(aFactory,aJob.aLayerDataUrl) ;
+
+ if (!xLayer.is())
+ {
+ rtl::OUString sMessage = OUSTRING("LocalDataImportService - Cannot create layer to import from");
+ throw lang::NullPointerException(sMessage,*this);
+ }
+
+ uno::Reference< lang::XInitialization > xFilterInit(aJob.xLayerFilter,uno::UNO_QUERY);
+ if (xFilterInit.is())
+ {
+ beans::NamedValue argvalue(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Source") ),
+ uno::makeAny( xLayer) );
+
+ uno::Sequence< uno::Any > args(1);
+ args[0] <<= argvalue;
+
+ xFilterInit->initialize(args);
+
+ xLayer = aJob.xLayerFilter;
+ }
+
+ uno::Reference< backend::XLayerImporter > xImporter;
+
+ int nArgCount = 0;
+ if (aJob.use_overwrite) ++nArgCount;
+ if (aJob.use_truncate) ++nArgCount;
+
+ if (nArgCount)
+ {
+ uno::Sequence< uno::Any > aArgs(nArgCount);
+
+ int n = 0;
+ if (aJob.use_overwrite)
+ aArgs[n++] <<= beans::NamedValue(OUSTRING("Overwrite"), uno::makeAny(aJob.overwrite));
+
+ if (aJob.use_truncate)
+ aArgs[n++] <<= beans::NamedValue(OUSTRING("Truncate"), uno::makeAny(aJob.truncate));
+
+ OSL_ASSERT(n == nArgCount);
+
+ xImporter.set( aFactory->createInstanceWithArguments(aJob.aImporterService,aArgs), uno::UNO_QUERY);
+ }
+ else
+ xImporter.set( aFactory->createInstance(aJob.aImporterService), uno::UNO_QUERY);
+
+ if (!xImporter.is())
+ {
+ rtl::OUString sMessage = OUSTRING("LocalDataImportService - Cannot create importer service: ") + aJob.aImporterService;
+ throw lang::NullPointerException(sMessage,*this);
+ }
+
+ try
+ {
+ if (aJob.use_entity)
+ xImporter->importLayerForEntity(xLayer,aJob.aEntity);
+
+ else
+ xImporter->importLayer(xLayer);
+ }
+ catch (lang::WrappedTargetException & e)
+ {
+ if (aJob.overwrite || !e.TargetException.isExtractableTo(getOverwriteFailedExceptionType())) throw;
+ return e.TargetException;
+ }
+ catch (lang::WrappedTargetRuntimeException & e)
+ {
+ if (aJob.overwrite || !e.TargetException.isExtractableTo(getOverwriteFailedExceptionType())) throw;
+ return e.TargetException;
+ }
+
+ return uno::Any();
+}
+// -----------------------------------------------------------------------------
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL
+ LocalDataImportService::getImplementationName( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getImplementationName( );
+}
+// -----------------------------------------------------------------------------
+
+
+sal_Bool SAL_CALL
+ LocalDataImportService::supportsService( const rtl::OUString& ServiceName )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().supportsService( ServiceName );
+}
+// -----------------------------------------------------------------------------
+
+
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ LocalDataImportService::getSupportedServiceNames( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getSupportedServiceNames( );
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/localbe/localdataimportsvc.hxx b/configmgr/source/localbe/localdataimportsvc.hxx
new file mode 100644
index 000000000000..e1ede1d60071
--- /dev/null
+++ b/configmgr/source/localbe/localdataimportsvc.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localdataimportsvc.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_IMPORTSVC_HXX
+#define CONFIGMGR_LOCALBE_IMPORTSVC_HXX
+
+#include "serviceinfohelper.hxx"
+#include <cppuhelper/implbase2.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/task/XJob.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace localbe
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace task = ::com::sun::star::task;
+ namespace beans = ::com::sun::star::beans;
+// -----------------------------------------------------------------------------
+
+ class LocalDataImportService : public ::cppu::WeakImplHelper2<
+ task::XJob,
+ lang::XServiceInfo
+ >
+ {
+ public:
+ explicit
+ LocalDataImportService(uno::Reference< uno::XComponentContext > const & _xContext);
+ ~LocalDataImportService();
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& ServiceName )
+ throw (uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException);
+
+ // XJob
+ virtual uno::Any SAL_CALL
+ execute( const uno::Sequence< beans::NamedValue >& Arguments )
+ throw (lang::IllegalArgumentException, uno::Exception, uno::RuntimeException);
+
+ protected:
+ uno::Reference< lang::XMultiServiceFactory > getServiceFactory() const
+ { return m_xServiceFactory; }
+
+ private:
+ uno::Reference< lang::XMultiServiceFactory > m_xServiceFactory;
+
+ static ServiceInfoHelper getServiceInfo();
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/localbe/localfilehelper.cxx b/configmgr/source/localbe/localfilehelper.cxx
new file mode 100644
index 000000000000..8b9ecc41198c
--- /dev/null
+++ b/configmgr/source/localbe/localfilehelper.cxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localfilehelper.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "localfilehelper.hxx"
+#include "filehelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include "tools/getprocessworkingdir.hxx"
+#include <vector>
+
+namespace configmgr
+{
+ namespace localbe
+ {
+ //------------------------------------------------------------------------------
+ bool isValidFileURL (rtl::OUString const& _sFileURL)
+ {
+ rtl::OUString sSystemPath;
+ return _sFileURL.getLength() && (osl::File::E_None == osl::File::getSystemPathFromFileURL(_sFileURL, sSystemPath));
+ }
+ //------------------------------------------------------------------------------
+ void validateFileURL(const rtl::OUString& _sFileURL, const uno::Reference<uno::XInterface>& pContext)
+ throw(css::configuration::InvalidBootstrapFileException)
+ {
+ if (!isValidFileURL( _sFileURL))
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii(" Not a Valid File URL: \"");
+ sMsg.append(_sFileURL);
+ sMsg.appendAscii("\"");
+ throw com::sun::star::configuration::InvalidBootstrapFileException(
+ sMsg.makeStringAndClear(),pContext, rtl::OUString() ) ;
+ }
+ }
+ //------------------------------------------------------------------------------
+ void checkFileExists(const rtl::OUString& _sFileURL,const uno::Reference<uno::XInterface>& pContext)
+ throw (backend::CannotConnectException)
+ {
+ if (!FileHelper::fileExists(_sFileURL))
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii(" No Such File or Directory: \"");
+ sMsg.append(_sFileURL);
+ sMsg.appendAscii("\"");
+
+ throw backend::CannotConnectException(sMsg.makeStringAndClear(), pContext, uno::Any()) ;
+ }
+ }
+ //------------------------------------------------------------------------------
+ void checkIfDirectory(const rtl::OUString& _sFileURL, const uno::Reference<uno::XInterface>& pContext)
+ throw (backend::BackendSetupException)
+ {
+ if (!FileHelper::dirExists(_sFileURL))
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii(" File:\"");
+ sMsg.append(_sFileURL);
+ sMsg.appendAscii("\" Must be a Directory\"");
+
+ throw backend::BackendSetupException(sMsg.makeStringAndClear(),pContext, uno::Any()) ;
+ }
+ }
+
+ // ---------------------------------------------------------------------------------------
+ bool implEnsureAbsoluteURL(rtl::OUString & _rsURL) // also strips embedded dots etc.
+ {
+ rtl::OUString sBasePath;
+ OSL_VERIFY(tools::getProcessWorkingDir(&sBasePath));
+
+ rtl::OUString sAbsolute;
+ if ( osl::File::E_None == osl::File::getAbsoluteFileURL(sBasePath, _rsURL, sAbsolute))
+ {
+ _rsURL = sAbsolute;
+ return true;
+ }
+ else
+ {
+ OSL_ENSURE(false, "Could not get absolute file URL for valid URL");
+ return false;
+ }
+ }
+ // ---------------------------------------------------------------------------------------
+ osl::DirectoryItem::RC implNormalizeURL(rtl::OUString & _sURL, osl::DirectoryItem& aDirItem)
+ {
+ OSL_PRECOND(aDirItem.is(), "Opened DirItem required");
+
+ static const sal_uInt32 cFileStatusMask = FileStatusMask_FileURL;
+
+ osl::FileStatus aFileStatus(cFileStatusMask);
+
+ osl::DirectoryItem::RC rc = aDirItem.getFileStatus(aFileStatus);
+
+ if (rc == osl::DirectoryItem::E_None)
+ {
+ rtl::OUString aNormalizedURL = aFileStatus.getFileURL();
+
+ if (aNormalizedURL.getLength() != 0)
+ _sURL = aNormalizedURL;
+ else
+ rc = osl::DirectoryItem::E_INVAL;
+ }
+ return rc;
+ }
+
+ // ---------------------------------------------------------------------------------------
+
+ bool normalizeURL(rtl::OUString & _sURL, const uno::Reference<uno::XInterface>& pContext, bool bNothrow )
+ throw (backend::InsufficientAccessRightsException, backend::BackendAccessException)
+ {
+ if (_sURL.getLength() == 0)
+ return false;
+
+ osl::DirectoryItem aDirItem;
+
+ osl::DirectoryItem::RC rc = osl::DirectoryItem::get(_sURL, aDirItem);
+
+ if (rc == osl::DirectoryItem::E_None)
+ rc = implNormalizeURL(_sURL,aDirItem);
+
+ switch (rc)
+ {
+ case osl::DirectoryItem::E_None: return true;
+
+ case osl::DirectoryItem::E_NOENT: return true;
+
+ case osl::DirectoryItem::E_ACCES:
+ if (!bNothrow)
+ {
+ rtl::OUStringBuffer msg;
+ msg.appendAscii("LocalBackend: Cannot normalize URL \"" );
+ msg.append(_sURL);
+ msg.appendAscii("\" - InsufficientAccess");
+ throw backend::InsufficientAccessRightsException(msg.makeStringAndClear(),pContext,uno::Any());
+ }
+ return false;
+
+ default:
+ if (!bNothrow)
+ {
+ rtl::OUStringBuffer msg;
+ msg.appendAscii("LocalBackend: Cannot normalize URL \"" );
+ msg.append(_sURL);
+ msg.appendAscii("\" - ").append(FileHelper::createOSLErrorString(rc));
+ throw backend::BackendAccessException(msg.makeStringAndClear(),pContext,uno::Any());
+ }
+ return false;
+
+ }
+ }
+
+ // ---------------------------------------------------------------------------------------
+ static const sal_Unicode kComponentSeparator = '.' ;
+ static const sal_Unicode kPathSeparator = '/' ;
+
+ rtl::OUString componentToPath(const rtl::OUString& aComponent)
+ {
+ rtl::OUStringBuffer retCode ;
+
+ retCode.append(kPathSeparator) ;
+ retCode.append(aComponent.replace(kComponentSeparator, kPathSeparator)) ;
+ return retCode.makeStringAndClear() ;
+ }
+ //------------------------------------------------------------------------------
+ rtl::OUString layeridToPath(const rtl::OUString& aLayerId)
+ {
+ sal_Int32 const nSplit = aLayerId.indexOf(k_cLayerIdSeparator);
+ if (nSplit < 0)
+ return componentToPath(aLayerId);
+
+ rtl::OUString const aComponent= aLayerId.copy(0,nSplit);
+ rtl::OUString const aSubid = aLayerId.copy(nSplit+1);
+
+ rtl::OUStringBuffer retCode ;
+
+ retCode.append(kPathSeparator) ;
+ retCode.append(aComponent.replace(kComponentSeparator, kPathSeparator)) ;
+ retCode.append(kPathSeparator) ;
+ retCode.append(aSubid) ;
+ return retCode.makeStringAndClear() ;
+ }
+ //------------------------------------------------------------------------------
+ bool checkOptionalArg(rtl::OUString& aArg)
+ {
+ if (aArg.getLength() && aArg[0] == sal_Unicode('?'))
+ {
+ aArg = aArg.copy(1);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ //------------------------------------------------------------------------------
+ void fillFromBlankSeparated(const rtl::OUString& aList,
+ uno::Sequence<rtl::OUString>& aTarget)
+ {
+ std::vector<rtl::OUString> tokens ;
+ sal_Int32 nextToken = 0 ;
+
+ do {
+ tokens.push_back(aList.getToken(0, ' ', nextToken)) ;
+ } while (nextToken >= 0) ;
+ if (tokens.size() > 0) {
+ aTarget.realloc(tokens.size()) ;
+ std::vector<rtl::OUString>::const_iterator token ;
+ sal_Int32 i = 0 ;
+
+ for (token = tokens.begin() ; token != tokens.end() ; ++ token) {
+ aTarget [i ++] = *token ;
+ }
+ }
+ }
+ //------------------------------------------------------------------------------
+ }
+} // namespace configmgr
diff --git a/configmgr/source/localbe/localfilehelper.hxx b/configmgr/source/localbe/localfilehelper.hxx
new file mode 100644
index 000000000000..56610a9e73e6
--- /dev/null
+++ b/configmgr/source/localbe/localfilehelper.hxx
@@ -0,0 +1,124 @@
+#ifndef CONFIGMGR_LOCALBE_LOCALFILEHELPER_HXX_
+#define CONFIGMGR_LOCALBE_LOCALFILEHELPER_HXX_
+
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/backend/CannotConnectException.hpp>
+#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
+#include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <osl/file.hxx>
+
+
+namespace configmgr
+{
+
+ namespace localbe
+ {
+ namespace css = com::sun::star ;
+ namespace uno = css::uno ;
+ namespace backend = css::configuration::backend ;
+
+ /**
+ Validates a file URL
+
+ @param _sFileURL URL of the file to validate
+ @return bool true if URL valid, false if URL invalid
+ */
+
+ bool isValidFileURL (rtl::OUString const& _sFileURL);
+ /**
+ Ensures Absolute URL
+ @param _sFileURL URL of the file to validate
+ @return bool true if URL is absolute URL,
+ false if URL is not absolute URL
+ */
+
+ bool implEnsureAbsoluteURL(rtl::OUString & _sFileURL);
+ /**
+ Normalize URL
+ @param _sFileURL URL of the file to validate
+ @param aDirItem Directory Item
+ @return RC error code
+ */
+
+ osl::DirectoryItem::RC implNormalizeURL(rtl::OUString & _sFileURL, osl::DirectoryItem& aDirItem);
+ /**
+ Normalize URL
+ @param _sFileURL URL of the file to validate
+ @param pContext pointer to context class
+ @param bNothrow param indicating that exception should not be thrown
+ @return bool true if URL is normalized URL
+ false if URL is not normalized URL
+ */
+
+
+ bool normalizeURL(rtl::OUString & _sFileURL,
+ const uno::Reference<uno::XInterface>& pContext,
+ bool bNothrow = false )
+ throw (backend::InsufficientAccessRightsException,
+ backend::BackendAccessException);
+
+ /**
+ Validates a file URL
+
+ @param _sFileURL URL of the file to validate
+ @param pContext pointer to context class
+ @throws css::configuration::InvalidBootstrapFileException
+ */
+ void validateFileURL(const rtl::OUString& _sFileURL,
+ const uno::Reference<uno::XInterface>& pContext)
+ throw(css::configuration::InvalidBootstrapFileException);
+ /**
+ Checks if a Directory exist for a given file URL
+
+ @param _sFileURL URL of the file to validate
+ @param pContext pointer to context class
+ @throws backend::BackendSetupException
+ */
+ void checkIfDirectory(const rtl::OUString& _sFileURL,
+ const uno::Reference<uno::XInterface>& pContext )
+ throw (backend::BackendSetupException);
+ /**
+ Checks if a File exist for a given file URL
+ @param pContext pointer to context class
+ @param _sFileURL URL of the file to validate
+ @throws backend::CannotConnectException
+ */
+ void checkFileExists(const rtl::OUString& _sFileURL,
+ const uno::Reference<uno::XInterface>& pContext)
+ throw (backend::CannotConnectException);
+
+ /**
+ Convert Component name to Path name
+ @param aComponent Component name
+ */
+ rtl::OUString componentToPath(const rtl::OUString& aComponent);
+
+ /// character that can be used to delimit a sub-id within a layerid
+ const sal_Unicode k_cLayerIdSeparator = ':';
+ /**
+ Convert layer id to Path name
+ Format of layer id is <component> [:<sub-id>]
+ @param aLayerId layer id
+ */
+ rtl::OUString layeridToPath(const rtl::OUString& aLayerId);
+
+
+ /**
+ Checks if Arguement is Optional
+ @param aArg Argument
+ @return bool returns true is Argument is Optional, false otherwise
+ */
+ bool checkOptionalArg(rtl::OUString& aArg);
+
+ /*
+ parses sequence of strings from blank separated list
+ @param aList blank separated list
+ @param aTarget sequence of parsed strings
+ */
+ void fillFromBlankSeparated(const rtl::OUString& aList,
+ uno::Sequence<rtl::OUString>& aTarget);
+
+ }
+}
+#endif
diff --git a/configmgr/source/localbe/localfilelayer.cxx b/configmgr/source/localbe/localfilelayer.cxx
new file mode 100644
index 000000000000..b4f1e5b4611b
--- /dev/null
+++ b/configmgr/source/localbe/localfilelayer.cxx
@@ -0,0 +1,611 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localfilelayer.cxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "localfilelayer.hxx"
+#include "localoutputstream.hxx"
+#include "oslstream.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+namespace configmgr { namespace localbe {
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+
+BasicLocalFileLayer::BasicLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aComponentFile)
+: mFactory(xFactory)
+, mFileUrl(aComponentFile)
+{
+ static const rtl::OUString kXMLLayerParser(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.backend.xml.LayerParser")) ;
+
+ mLayerReader = uno::Reference<backend::XLayer>::query(
+ mFactory->createInstance(kXMLLayerParser)) ;
+
+}
+//------------------------------------------------------------------------------
+
+SimpleLocalFileLayer::SimpleLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aComponentFile)
+: BasicLocalFileLayer(xFactory,aComponentFile)
+{
+}
+//------------------------------------------------------------------------------
+
+SimpleLocalFileLayer::SimpleLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent)
+: BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
+{
+}
+//------------------------------------------------------------------------------
+
+FlatLocalFileLayer::FlatLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent)
+: BasicLocalFileLayer(xFactory,aBaseDir + aComponent)
+, mLayerWriter( createLayerWriter() )
+{
+}
+//------------------------------------------------------------------------------
+
+BasicCompositeLocalFileLayer::BasicCompositeLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aComponentFile)
+: BasicLocalFileLayer(xFactory,aComponentFile)
+{
+}
+//------------------------------------------------------------------------------
+
+CompositeLocalFileLayer::CompositeLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aComponent,
+ const std::vector<rtl::OUString>& aSublayerDirectories)
+: BasicCompositeLocalFileLayer(xFactory,rtl::OUString())
+{
+ fillSubLayerLists(aSublayerDirectories, aComponent) ;
+}
+//------------------------------------------------------------------------------
+
+FullCompositeLocalFileLayer::FullCompositeLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent,
+ const std::vector<rtl::OUString>& aSublayerDirectories)
+: BasicCompositeLocalFileLayer(xFactory,aBaseDir + aComponent)
+, mLayerWriter( createLayerWriter() )
+{
+ fillSubLayerLists(aSublayerDirectories, aComponent) ;
+}
+//------------------------------------------------------------------------------
+
+BasicLocalFileLayer::~BasicLocalFileLayer() {}
+//------------------------------------------------------------------------------
+
+SimpleLocalFileLayer::~SimpleLocalFileLayer() {}
+//------------------------------------------------------------------------------
+
+FlatLocalFileLayer::~FlatLocalFileLayer() {}
+//------------------------------------------------------------------------------
+
+CompositeLocalFileLayer::~CompositeLocalFileLayer() {}
+//------------------------------------------------------------------------------
+
+FullCompositeLocalFileLayer::~FullCompositeLocalFileLayer() {}
+//------------------------------------------------------------------------------
+
+uno::Reference<backend::XLayerHandler> BasicLocalFileLayer::createLayerWriter()
+{
+ static const rtl::OUString kXMLLayerWriter(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.backend.xml.LayerWriter")) ;
+
+ uno::Reference< uno::XInterface > xWriter = mFactory->createInstance(kXMLLayerWriter);
+
+ return uno::Reference<backend::XLayerHandler>(xWriter,uno::UNO_REF_QUERY_THROW) ;
+}
+//------------------------------------------------------------------------------
+
+static inline void readEmptyLayer(const uno::Reference<backend::XLayerHandler>& xHandler)
+{
+ OSL_ASSERT(xHandler.is());
+ xHandler->startLayer();
+ xHandler->endLayer();
+}
+//------------------------------------------------------------------------------
+
+void BasicLocalFileLayer::readData(
+ backend::XLayer * pContext,
+ const uno::Reference<backend::XLayerHandler>& xHandler,
+ const rtl::OUString& aFileUrl)
+ throw ( backend::MalformedDataException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if (!xHandler.is())
+ {
+ rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalFileLayer - Cannot readData: Handler is NULL."));
+
+ throw lang::NullPointerException(sMessage,pContext);
+ }
+
+ osl::File blobFile(aFileUrl) ;
+ osl::File::RC errorCode = blobFile.open(OpenFlag_Read) ;
+
+ switch (errorCode)
+ {
+ case osl::File::E_None: // got it
+ {
+ uno::Reference<io::XActiveDataSink> xAS(mLayerReader, uno::UNO_QUERY_THROW);
+
+ uno::Reference<io::XInputStream> xStream( new OSLInputStreamWrapper(blobFile) );
+
+ xAS->setInputStream(xStream);
+
+ mLayerReader->readData(xHandler) ;
+ }
+ break;
+
+ case osl::File::E_NOENT: // no layer => empty layer
+ readEmptyLayer(xHandler);
+ break;
+
+ default:
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("LocalFile Layer: Cannot open input file \"");
+ sMsg.append(aFileUrl);
+ sMsg.appendAscii("\" : ");
+ sMsg.append(FileHelper::createOSLErrorString(errorCode));
+
+ io::IOException ioe(sMsg.makeStringAndClear(),pContext);
+
+ sMsg.appendAscii("LocalFileLayer - Cannot readData: ").append(ioe.Message);
+ throw backend::BackendAccessException(sMsg.makeStringAndClear(),pContext,uno::makeAny(ioe));
+ }
+ }
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL SimpleLocalFileLayer::readData(
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+ throw ( backend::MalformedDataException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ BasicLocalFileLayer::readData(this,xHandler, getFileUrl()) ;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL FlatLocalFileLayer::readData(
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+ throw ( backend::MalformedDataException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ BasicLocalFileLayer::readData(this,xHandler, getFileUrl() ) ;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL CompositeLocalFileLayer::readData(
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+ throw ( backend::MalformedDataException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if (!xHandler.is())
+ {
+ rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalFileLayer - Cannot readData: Handler is NULL."));
+
+ throw lang::NullPointerException(sMessage,*this);
+ }
+
+ readEmptyLayer(xHandler) ;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL FullCompositeLocalFileLayer::readData(
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+ throw ( backend::MalformedDataException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ BasicLocalFileLayer::readData(static_cast<backend::XCompositeLayer*>(this),xHandler, getFileUrl() ) ;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL BasicCompositeLocalFileLayer::readSubLayerData(
+ backend::XCompositeLayer * pContext,
+ const uno::Reference<backend::XLayerHandler>& xHandler,
+ const rtl::OUString& aSubLayerId)
+ throw ( backend::MalformedDataException,
+ lang::IllegalArgumentException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if (!xHandler.is())
+ {
+ rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
+ "CompositeLocalFileLayer - Cannot readSubLayerData: Handler is NULL."));
+
+ throw lang::NullPointerException(sMessage,pContext);
+ }
+
+ sal_Int32 i ;
+
+ for (i = 0 ; i < mSubLayers.getLength() ; ++ i) {
+ if (mSubLayers [i].equals(aSubLayerId)) { break ; }
+ }
+ if (i == mSubLayers.getLength())
+ {
+ rtl::OUStringBuffer message ;
+
+ message.appendAscii("Sublayer Id '").append(aSubLayerId) ;
+ message.appendAscii("' is unknown") ;
+ throw lang::IllegalArgumentException(message.makeStringAndClear(),
+ pContext, 2) ;
+ }
+ if (mSubLayerFiles[i].getLength() != 0)
+ BasicLocalFileLayer::readData(pContext,xHandler, mSubLayerFiles [i]) ;
+ else
+ readEmptyLayer(xHandler);
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL CompositeLocalFileLayer::readSubLayerData(
+ const uno::Reference<backend::XLayerHandler>& xHandler,
+ const rtl::OUString& aSubLayerId)
+ throw ( backend::MalformedDataException,
+ lang::IllegalArgumentException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ return BasicCompositeLocalFileLayer::readSubLayerData(this,xHandler,aSubLayerId);
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL FullCompositeLocalFileLayer::readSubLayerData(
+ const uno::Reference<backend::XLayerHandler>& xHandler,
+ const rtl::OUString& aSubLayerId)
+ throw ( backend::MalformedDataException,
+ lang::IllegalArgumentException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ return BasicCompositeLocalFileLayer::readSubLayerData(this,xHandler,aSubLayerId);
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL FlatLocalFileLayer::replaceWith(
+ const uno::Reference<backend::XLayer>& aNewLayer)
+ throw ( backend::MalformedDataException,
+ lang::NullPointerException,
+ lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ if (!aNewLayer.is())
+ {
+ rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalFileLayer - Cannot replaceWith: Replacement layer is NULL."));
+
+ throw lang::NullPointerException(sMessage,*this);
+ }
+ OSL_ENSURE( !uno::Reference<backend::XCompositeLayer>::query(aNewLayer).is(),
+ "Warning: correct updates with composite layers are not implemented");
+
+ uno::Reference<io::XActiveDataSource> xAS(mLayerWriter, uno::UNO_QUERY_THROW);
+
+ LocalOutputStream * pStream = new LocalOutputStream(getFileUrl());
+ uno::Reference<io::XOutputStream> xStream( pStream );
+
+ xAS->setOutputStream(xStream);
+
+ aNewLayer->readData(mLayerWriter) ;
+
+ pStream->finishOutput();
+
+ // clear the output stream
+ xStream.clear();
+ xAS->setOutputStream(xStream);
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL FullCompositeLocalFileLayer::replaceWith(
+ const uno::Reference<backend::XLayer>& aNewLayer)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException)
+{
+ if (!aNewLayer.is())
+ {
+ rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalFileLayer - Cannot replaceWith: Replacement layer is NULL."));
+
+ throw lang::NullPointerException(sMessage,*this);
+ }
+ OSL_ENSURE( !uno::Reference<backend::XCompositeLayer>::query(aNewLayer).is(),
+ "Warning: correct updates with composite layers are not implemented");
+
+ uno::Reference<io::XActiveDataSource> xAS(mLayerWriter, uno::UNO_QUERY_THROW);
+
+ LocalOutputStream * pStream = new LocalOutputStream(getFileUrl());
+ uno::Reference<io::XOutputStream> xStream( pStream );
+
+ xAS->setOutputStream(xStream);
+
+ aNewLayer->readData(mLayerWriter) ;
+
+ pStream->finishOutput();
+
+ // clear the output stream
+ xStream.clear();
+ xAS->setOutputStream(xStream);
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString BasicLocalFileLayer::getTimestamp(const rtl::OUString& aFileUrl)
+{
+ TimeValue timevalue = {0,0};
+ sal_uInt64 aSize = FileHelper::getModifyStatus(aFileUrl,timevalue) ;
+ oslDateTime fileStamp ;
+ rtl::OUString retCode ;
+
+ if (osl_getDateTimeFromTimeValue(&timevalue, &fileStamp))
+ {
+ // truncate to 32 bits
+ unsigned long aLongSize = static_cast<sal_Int32>(aSize);
+
+ sal_Char asciiStamp [50] ;
+
+ sprintf(asciiStamp, "%04u%02u%02u%02u%02u%02uZ%010lu",
+ unsigned(fileStamp.Year), unsigned(fileStamp.Month), unsigned(fileStamp.Day),
+ unsigned(fileStamp.Hours), unsigned(fileStamp.Minutes), unsigned(fileStamp.Seconds),
+ aLongSize) ;
+ retCode = rtl::OUString::createFromAscii(asciiStamp) ;
+ }
+ return retCode ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SimpleLocalFileLayer::getTimestamp()
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sStamp = BasicLocalFileLayer::getTimestamp(getFileUrl());
+
+ return sStamp;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString FlatLocalFileLayer::getTimestamp()
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sStamp = BasicLocalFileLayer::getTimestamp(getFileUrl());
+
+ return sStamp;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString FullCompositeLocalFileLayer::getTimestamp()
+ throw (uno::RuntimeException)
+{
+ rtl::OUString sStamp = BasicLocalFileLayer::getTimestamp(getFileUrl());
+#if 0 // thus far composite layers are only manipulated via the main layer
+ for (std::vector<rtl::OUString>::const_iterator it = mSubLayerFiles.begin();
+ it != mSubLayerFiles.end();
+ ++it)
+ {
+ rtl::OUString sSublayerTime = BasicLocalFileLayer::getTimestamp(*it);
+ if (sStamp < sSublayerTime)
+ sStamp = sSublayerTime;
+ }
+#endif
+ return sStamp;
+}
+//------------------------------------------------------------------------------
+
+void BasicCompositeLocalFileLayer::fillSubLayerLists( const std::vector<rtl::OUString>& aSublayerDirectories,
+ const rtl::OUString& aComponent)
+{
+ std::vector<rtl::OUString>::size_type const nSublayerCount = aSublayerDirectories.size();
+ mSubLayers.realloc(nSublayerCount);
+ mSubLayerFiles.resize(nSublayerCount);
+
+ for (std::vector<rtl::OUString>::size_type i = 0; i < nSublayerCount; ++i)
+ {
+ mSubLayers[i] = FileHelper::getFileName(aSublayerDirectories[i]);
+
+ // Let's check whether the sublayer exists for the
+ // particular component.
+ rtl::OUString subLayerFile(aSublayerDirectories[i] + aComponent) ;
+ if (FileHelper::fileExists(subLayerFile))
+ {
+ mSubLayerFiles[i] = subLayerFile;
+ }
+ else
+ OSL_ASSERT(mSubLayerFiles[i].getLength() == 0);
+ }
+}
+//------------------------------------------------------------------------------
+
+static bool findSubLayers(const rtl::OUString& aResDir,
+ std::vector<rtl::OUString>& aSublayerDirectories)
+{
+ if (aResDir.getLength() == 0) return false;
+
+ // Extract the directory where the file is located
+ osl::Directory directory(aResDir) ;
+ if (directory.open() != osl::Directory::E_None) return false;
+
+ osl::DirectoryItem item ;
+ osl::FileStatus status(osl_FileStatus_Mask_Type |
+ osl_FileStatus_Mask_FileURL) ;
+
+ while (directory.getNextItem(item) == osl::Directory::E_None)
+ {
+ if (item.getFileStatus(status) == osl::Directory::E_None)
+ {
+ if (status.getFileType() == osl::FileStatus::Directory)
+ {
+ aSublayerDirectories.push_back(status.getFileURL()) ;
+ }
+ }
+ }
+ return !aSublayerDirectories.empty();
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backend::XLayer> createReadonlyLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent,
+ const rtl::OUString& aResDir)
+{
+ uno::Reference<backend::XLayer> xResult;
+
+ std::vector<rtl::OUString> aSublayers;
+ if (aBaseDir.getLength() == 0)
+ {
+ findSubLayers(aResDir,aSublayers);
+ xResult.set( new CompositeLocalFileLayer(xFactory,aComponent,aSublayers) );
+ }
+ else if (findSubLayers(aResDir,aSublayers))
+ {
+ // there is no readonly full composite layer - take the updatable one
+ backend::XCompositeLayer * pNewLayer =
+ new FullCompositeLocalFileLayer(xFactory,aBaseDir,aComponent,aSublayers);
+ xResult.set( pNewLayer );
+ }
+ else
+ {
+ xResult.set( new SimpleLocalFileLayer(xFactory,aBaseDir,aComponent) );
+ }
+ return xResult;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backend::XUpdatableLayer> createUpdatableLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent,
+ const rtl::OUString& aResDir)
+{
+ uno::Reference<backend::XUpdatableLayer> xResult;
+
+ std::vector<rtl::OUString> aSublayers;
+ if (findSubLayers(aResDir,aSublayers))
+ {
+ xResult.set( new FullCompositeLocalFileLayer(xFactory,aBaseDir,aComponent,aSublayers) );
+ }
+ else if (aBaseDir.getLength() != 0)
+ {
+ xResult.set( new FlatLocalFileLayer(xFactory,aBaseDir,aComponent) );
+ }
+ else
+ OSL_ENSURE(false,"WARNING: Trying to create an updatable ressource-only layer");
+
+ return xResult;
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+enum
+{
+ LAYER_PROPERTY_URL = 1
+};
+
+#define PROPNAME( name ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( name ) )
+#define PROPTYPE( type ) getCppuType( static_cast< type const *>( 0 ) )
+
+// cppu::OPropertySetHelper
+cppu::IPropertyArrayHelper * SAL_CALL LayerPropertyHelper::newInfoHelper()
+{
+ com::sun::star::beans::Property properties[] =
+ {
+ com::sun::star::beans::Property(PROPNAME("URL"), LAYER_PROPERTY_URL, PROPTYPE(rtl::OUString), com::sun::star::beans::PropertyAttribute::READONLY)
+ };
+
+ return new cppu::OPropertyArrayHelper(properties, sizeof(properties)/sizeof(properties[0]));
+}
+
+#define MESSAGE( text ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ERROR: Layer Properties: " text ) )
+
+void SAL_CALL LayerPropertyHelper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& /*rValue*/ )
+ throw (uno::Exception)
+{
+ namespace beans = com::sun::star::beans;
+
+ switch (nHandle)
+ {
+ case LAYER_PROPERTY_URL:
+ OSL_ENSURE(false, "Error: trying to set a READONLY property");
+ throw beans::PropertyVetoException(MESSAGE("Property 'URL' is read-only"),*this);
+
+ default:
+ OSL_ENSURE(false, "Error: trying to set an UNKNOWN property");
+ throw beans::UnknownPropertyException(MESSAGE("Trying to set an unknown property"),*this);
+ }
+}
+
+void SAL_CALL LayerPropertyHelper::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const
+{
+ switch (nHandle)
+ {
+ case LAYER_PROPERTY_URL:
+ rValue = uno::makeAny( this->getLayerUrl() );
+ break;
+
+ default:
+ OSL_ENSURE(false, "Error: trying to get an UNKNOWN property");
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+} } // configmgr.localbe
+
diff --git a/configmgr/source/localbe/localfilelayer.hxx b/configmgr/source/localbe/localfilelayer.hxx
new file mode 100644
index 000000000000..796582d314e5
--- /dev/null
+++ b/configmgr/source/localbe/localfilelayer.hxx
@@ -0,0 +1,495 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localfilelayer.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_LOCALFILELAYER_HXX_
+#define CONFIGMGR_LOCALBE_LOCALFILELAYER_HXX_
+
+#include "propertysethelper.hxx"
+#include <com/sun/star/configuration/backend/XUpdatableLayer.hpp>
+#include <com/sun/star/configuration/backend/XCompositeLayer.hpp>
+#include <com/sun/star/util/XTimeStamped.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+#ifndef VECTOR_INCLUDED_
+#define VECTOR_INCLUDED_
+#include <vector>
+#endif // VECTOR_INCLUDED_
+
+namespace configmgr { namespace localbe {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace util = css::util ;
+namespace backend = css::configuration::backend ;
+
+/**
+ Basic Implementation of the readonly XLayer interfaces for a local file access.
+ The read data is accessible through a canned implementation of an XML parser.
+ The layer is defined by the URL of the file containing its contents.
+ */
+class BasicLocalFileLayer
+{
+protected :
+ /**
+ Constructor providing the base directory and the
+ file subpath describing the file to access.
+ An optional resource directory provides the location
+ of sublayers of the component.
+
+ @param xFactory service factory used to access canned services
+ @param aComponentFile path describing the component file
+ */
+ BasicLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aComponentFile) ;
+ /** Destructor */
+ ~BasicLocalFileLayer() ;
+
+protected :
+ /**
+ Describes the contents of a particular file to a handler.
+
+ @param xHandler handler to describe the data to
+ @param aFileUrl URL of the file
+ @throws com::sun::star::configuration::backend::MalformedDataException
+ if the file contains invalid data.
+ @throws com::sun::star::lang::NullPointerException
+ if pContext is NULL.
+ @throws com::sun::star::lang::WrappedTargetException
+ if an error occurs while accessing the data.
+ */
+ void readData(backend::XLayer * pContext,
+ const uno::Reference<backend::XLayerHandler>& xHandler,
+ const rtl::OUString& aFileUrl)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ /**
+ Returns an object that can be used to write a layer.
+ */
+ uno::Reference<backend::XLayerHandler> createLayerWriter();
+
+public:
+ /**
+ Returns a timestamp associated to a file defined by its URL.
+
+ @param aFileUrl URL of the file
+ @return timestamp
+ */
+ static rtl::OUString getTimestamp(const rtl::OUString& aFileUrl) ;
+
+ rtl::OUString const & getFileUrl() const { return mFileUrl; };
+
+private :
+ /** Service factory */
+ uno::Reference<lang::XMultiServiceFactory> const mFactory ;
+ /** URL of the file being accessed */
+ rtl::OUString const mFileUrl ;
+ /** XLayer implementation used for readData */
+ uno::Reference<backend::XLayer> mLayerReader ;
+
+} ;
+
+// provides properties for file layers
+class LayerPropertyHelper : public apihelper::PropertySetHelper
+{
+protected:
+ LayerPropertyHelper(){};
+ virtual ~LayerPropertyHelper(){};
+
+protected:
+ virtual rtl::OUString const & getLayerUrl() const = 0;
+
+protected:
+ // cppu::OPropertySetHelper
+ virtual cppu::IPropertyArrayHelper * SAL_CALL newInfoHelper();
+
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue )
+ throw (uno::Exception);
+
+ using PropertySetHelper::getFastPropertyValue;
+ virtual void SAL_CALL getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const;
+
+};
+
+/**
+ Implementation of the readonly XLayer interfaces for a local file access.
+ The read data is accessible through a canned implementation of
+ an XML parser.
+ The layer is defined by the URL of the file containing its
+ contents.
+ */
+class SimpleLocalFileLayer : public BasicLocalFileLayer
+ , public cppu::ImplInheritanceHelper2< LayerPropertyHelper,
+ backend::XLayer,
+ util::XTimeStamped>
+{
+public :
+ /**
+ Constructor providing the base directory and the
+ file subpath describing the file to access.
+ An optional resource directory provides the location
+ of sublayers of the component.
+
+ @param xFactory service factory used to access canned services
+ @param aComponentFile URL describing the component file
+ */
+ SimpleLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aComponentFile) ;
+ /**
+ Constructor providing the base directory and the
+ file subpath describing the file to access.
+ An optional resource directory provides the location
+ of sublayers of the component.
+
+ @param xFactory service factory used to access canned services
+ @param aBaseDir base directory
+ @param aComponent subpath describing the component file
+ */
+ SimpleLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent) ;
+
+ /** Destructor */
+ ~SimpleLocalFileLayer() ;
+
+ // XLayer
+ using BasicLocalFileLayer::readData;
+ virtual void SAL_CALL readData(
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XTimeStamped
+ virtual rtl::OUString SAL_CALL getTimestamp()
+ throw (uno::RuntimeException);
+
+protected:
+ virtual rtl::OUString const & getLayerUrl() const
+ { return getFileUrl(); }
+} ;
+
+/**
+ Implementation of the XUpdatableLayer
+ interface for a local file access.
+ The read data is accessible through a canned implementation of
+ an XML parser, and the write data is defined through a canned
+ implementation of an XML writer.
+ The layer is defined by the URL of the file containing its
+ contents, and that file will be either read or updated by
+ the access to the handlers.
+ The timestamp is refreshed on each read operation only.
+ */
+class FlatLocalFileLayer : public BasicLocalFileLayer
+ , public cppu::ImplInheritanceHelper2< LayerPropertyHelper,
+ backend::XUpdatableLayer,
+ util::XTimeStamped>
+{
+public :
+ /**
+ Constructor providing the base directory and the
+ file subpath describing the file to access.
+
+ @param xFactory service factory used to access canned services
+ @param aBaseDir base directory
+ @param aComponent subpath describing the component file
+ */
+ FlatLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent) ;
+ /** Destructor */
+ ~FlatLocalFileLayer(void) ;
+
+ // XLayer
+ using BasicLocalFileLayer::readData;
+ virtual void SAL_CALL readData(
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XUpdatableLayer
+ virtual void SAL_CALL replaceWith(
+ const uno::Reference<backend::XLayer>& aNewLayer)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XTimeStamped
+ virtual rtl::OUString SAL_CALL getTimestamp()
+ throw (uno::RuntimeException);
+
+protected:
+ virtual rtl::OUString const & getLayerUrl() const
+ { return getFileUrl(); }
+
+private :
+ /** XLayerHandler implementation for getWriteHandler */
+ uno::Reference<backend::XLayerHandler> mLayerWriter ;
+
+} ;
+
+/**
+ Implementation of the XCompositeLayer
+ interface for a local file access.
+ The read data is accessible through a canned implementation of
+ an XML parser.
+ The layer is defined by the URL of the file containing its
+ contents, and that file will be either read or updated by
+ the access to the handlers.
+ The timestamp is refreshed on each read operation only.
+ */
+class BasicCompositeLocalFileLayer : public BasicLocalFileLayer
+{
+protected:
+ /**
+ Constructor providing the base directory and the
+ file subpath describing the file to access.
+ An resource directory provides the location
+ of sublayers of the component.
+
+ @param xFactory service factory used to access canned services
+ @param aComponent path describing the component file
+ */
+ BasicCompositeLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aComponent) ;
+
+ // XCompositeLayer helpers
+ uno::Sequence<rtl::OUString> SAL_CALL listSubLayerIds()
+ throw (lang::WrappedTargetException, uno::RuntimeException)
+ { return mSubLayers ; }
+
+ void SAL_CALL readSubLayerData(
+ backend::XCompositeLayer * context,
+ const uno::Reference<backend::XLayerHandler>& xHandler,
+ const rtl::OUString& aSubLayerId)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, lang::IllegalArgumentException,
+ uno::RuntimeException);
+
+ /**
+ Fills the list of available sublayers.
+
+ @param aResDir resource directory containing potential sublayers
+ @param aComponent component subpath
+ */
+ void fillSubLayerLists(const std::vector<rtl::OUString>& aSublayerDirectories,
+ const rtl::OUString& aComponent) ;
+private :
+ /** List of available sublayers... */
+ uno::Sequence<rtl::OUString> mSubLayers ;
+ /** .. and the corresponding file URLs. */
+ std::vector<rtl::OUString> mSubLayerFiles ;
+
+};
+
+/**
+ Implementation of the XCompositeLayer
+ interface for a local file access.
+ The read data is accessible through a canned implementation of
+ an XML parser.
+ The layer is defined by the URL of the file containing its
+ contents, and that file will be either read or updated by
+ the access to the handlers.
+ The timestamp is refreshed on each read operation only.
+ */
+class CompositeLocalFileLayer : public BasicCompositeLocalFileLayer
+ , public cppu::WeakImplHelper1< backend::XCompositeLayer>
+{
+public :
+ /**
+ Constructor providing the base directory and the
+ file subpath describing the file to access.
+ An resource directory provides the location
+ of sublayers of the component.
+
+ @param xFactory service factory used to access canned services
+ @param aBaseDir base directory
+ @param aComponent subpath describing the component file
+ @param aResDir resource directory, if empty it is
+ assumed the layer does not have sublayers.
+ */
+ CompositeLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aComponent,
+ const std::vector<rtl::OUString>& aSublayerDirectories) ;
+ /** Destructor */
+ ~CompositeLocalFileLayer(void) ;
+ // XLayer
+ using BasicCompositeLocalFileLayer::readData;
+ virtual void SAL_CALL readData(
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XCompositeLayer
+ virtual uno::Sequence<rtl::OUString> SAL_CALL listSubLayerIds()
+ throw (lang::WrappedTargetException, uno::RuntimeException)
+ { return BasicCompositeLocalFileLayer::listSubLayerIds() ; }
+
+ using BasicCompositeLocalFileLayer::readSubLayerData;
+ virtual void SAL_CALL readSubLayerData(
+ const uno::Reference<backend::XLayerHandler>& xHandler,
+ const rtl::OUString& aSubLayerId)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, lang::IllegalArgumentException,
+ uno::RuntimeException);
+
+private :
+ // not implemented: warn of attempts to use this here
+ void getFileUrl() const;
+} ;
+/**
+ Implementation of the XUpdatableLayer and XCompositeLayer
+ interfaces for a local file access.
+ The read data is accessible through a canned implementation of
+ an XML parser, and the write data is defined through a canned
+ implementation of an XML writer.
+ The layer is defined by the URL of the file containing its
+ contents, and that file will be either read or updated by
+ the access to the handlers.
+ The timestamp is refreshed on each read operation only.
+ */
+class FullCompositeLocalFileLayer : public BasicCompositeLocalFileLayer
+ , public cppu::ImplInheritanceHelper3<
+ LayerPropertyHelper,
+ backend::XUpdatableLayer,
+ backend::XCompositeLayer,
+ util::XTimeStamped>
+{
+public :
+ /**
+ Constructor providing the base directory and the
+ file subpath describing the file to access.
+ An resource directory provides the location
+ of sublayers of the component.
+
+ @param xFactory service factory used to access canned services
+ @param aBaseDir base directory
+ @param aComponent subpath describing the component file
+ @param aResDir resource directory, if empty it is
+ assumed the layer does not have sublayers.
+ */
+ FullCompositeLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent,
+ const std::vector<rtl::OUString>& aSublayerDirectories) ;
+ /** Destructor */
+ ~FullCompositeLocalFileLayer(void) ;
+ // XLayer
+ using BasicCompositeLocalFileLayer::readData;
+ virtual void SAL_CALL readData(
+ const uno::Reference<backend::XLayerHandler>& xHandler)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XUpdatableLayer
+ virtual void SAL_CALL replaceWith(
+ const uno::Reference<backend::XLayer>& aNewLayer)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, uno::RuntimeException);
+
+ // XCompositeLayer
+ virtual uno::Sequence<rtl::OUString> SAL_CALL listSubLayerIds()
+ throw (lang::WrappedTargetException, uno::RuntimeException)
+ { return BasicCompositeLocalFileLayer::listSubLayerIds() ; }
+
+ using BasicCompositeLocalFileLayer::readSubLayerData;
+ virtual void SAL_CALL readSubLayerData(
+ const uno::Reference<backend::XLayerHandler>& xHandler,
+ const rtl::OUString& aSubLayerId)
+ throw (backend::MalformedDataException, lang::NullPointerException,
+ lang::WrappedTargetException, lang::IllegalArgumentException,
+ uno::RuntimeException);
+
+ // XTimeStamped
+ virtual rtl::OUString SAL_CALL getTimestamp()
+ throw (uno::RuntimeException);
+
+protected:
+ virtual rtl::OUString const & getLayerUrl() const
+ { return getFileUrl(); }
+
+private :
+ /** XLayerHandler implementation for getWriteHandler */
+ uno::Reference<backend::XLayerHandler> mLayerWriter ;
+} ;
+/**
+ Factory function to create the appropriate Flat- or Composite-
+ LocalFileLayer for a set of parameters.
+
+ Arguments provide the base directory and the
+ file subpath describing the file to access.
+ An optional resource directory provides the location
+ of sublayers of the component.
+
+ @param xFactory service factory used to access canned services
+ @param aBaseDir base directory
+ @param aComponent subpath describing the component file
+ @param aResDir resource directory, if empty it is
+ assumed the layer does not have sublayers.
+ */
+uno::Reference<backend::XLayer> createReadonlyLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent,
+ const rtl::OUString& aResDir) ;
+
+/**
+ Factory function to create the appropriate Flat- or Composite-
+ LocalFileLayer for a set of parameters.
+
+ Arguments provide the base directory and the
+ file subpath describing the file to access.
+ An optional resource directory provides the location
+ of sublayers of the component.
+
+ @param xFactory service factory used to access canned services
+ @param aBaseDir base directory
+ @param aComponent subpath describing the component file
+ @param aResDir resource directory, if empty it is
+ assumed the layer does not have sublayers.
+ */
+uno::Reference<backend::XUpdatableLayer> createUpdatableLocalFileLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ const rtl::OUString& aBaseDir,
+ const rtl::OUString& aComponent,
+ const rtl::OUString& aResDir) ;
+
+} } // configmgr.localbe
+
+#endif // CONFIGMGR_LOCALBE_LOCALFILELAYER_HXX_
diff --git a/configmgr/source/localbe/localhierarchybrowsersvc.cxx b/configmgr/source/localbe/localhierarchybrowsersvc.cxx
new file mode 100644
index 000000000000..2a6196e87fd5
--- /dev/null
+++ b/configmgr/source/localbe/localhierarchybrowsersvc.cxx
@@ -0,0 +1,536 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localhierarchybrowsersvc.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "localhierarchybrowsersvc.hxx"
+#include "localsinglebackend.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <rtl/ustrbuf.hxx>
+
+#include <algorithm>
+// -----------------------------------------------------------------------------
+
+#define OUSTRING( constascii ) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(constascii))
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace localbe
+ {
+// -----------------------------------------------------------------------------
+
+sal_Char const * const aLocalHierarchyBrowserServices[] =
+{
+ "com.sun.star.configuration.backend.LocalHierarchyBrowser",
+ 0,
+ "com.sun.star.configuration.backend.HierarchyBrowser",
+ 0
+};
+const ServiceImplementationInfo aLocalHierarchyBrowserSI =
+{
+ "com.sun.star.comp.configuration.backend.LocalHierarchyBrowser",
+ aLocalHierarchyBrowserServices,
+ aLocalHierarchyBrowserServices + 3
+};
+// -----------------------------------------------------------------------------
+
+const ServiceRegistrationInfo* getLocalHierarchyBrowserServiceInfo()
+{ return getRegistrationInfo(& aLocalHierarchyBrowserSI); }
+// -----------------------------------------------------------------------------
+
+inline
+ServiceInfoHelper LocalHierarchyBrowserService::getServiceInfo()
+{
+ return & aLocalHierarchyBrowserSI;
+}
+// -----------------------------------------------------------------------------
+
+uno::Reference< uno::XInterface > SAL_CALL instantiateLocalHierarchyBrowser
+( uno::Reference< uno::XComponentContext > const& rServiceManager )
+{
+ return * new LocalHierarchyBrowserService( rServiceManager );
+}
+// -----------------------------------------------------------------------------
+
+LocalHierarchyBrowserService::LocalHierarchyBrowserService(uno::Reference< uno::XComponentContext > const & _xContext)
+: m_xServiceFactory(_xContext->getServiceManager(), uno::UNO_QUERY)
+{
+ if (!m_xServiceFactory.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration Importer: Unexpected NULL context"));
+ throw lang::NullPointerException(sMessage,NULL);
+ }
+}
+// -----------------------------------------------------------------------------
+
+LocalHierarchyBrowserService::~LocalHierarchyBrowserService()
+{}
+// -----------------------------------------------------------------------------
+
+namespace
+{
+ struct JobDesc
+ {
+ explicit JobDesc(task::XJob * pJob, const uno::Sequence< beans::NamedValue >& aArguments);
+
+ enum Mode { findNone, findSchemas, findLayers };
+ enum Result { getDefault,getUrls, getNames };
+
+ rtl::OUString aBaseDataUrl;
+ uno::Sequence< rtl::OUString > aExcludeList;
+ Mode mode;
+ Result result_type;
+ };
+
+ JobDesc::JobDesc(task::XJob * pJob, const uno::Sequence< beans::NamedValue >& aArguments)
+ : aBaseDataUrl()
+ , aExcludeList()
+ , mode(findNone)
+ , result_type(getDefault)
+ {
+ sal_Int16 const nCount = static_cast<sal_Int16>(aArguments.getLength());
+
+ if (sal_Int32(nCount) != aArguments.getLength())
+ {
+ rtl::OUString sMessage = OUSTRING("Too many arguments for LocalHierarchyBrowser Job");
+ throw lang::IllegalArgumentException(sMessage,pJob,0);
+ }
+
+ for (sal_Int16 i=0; i < nCount; ++i)
+ {
+ sal_Bool bKnown = false;
+ sal_Bool bGood = false;
+
+ if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SchemaDataUrl")))
+ {
+ bKnown = true;
+ bGood = (aArguments[i].Value >>= aBaseDataUrl);
+ mode = (bGood && aBaseDataUrl.getLength()) ? findSchemas : findNone;
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("LayerDataUrl")))
+ {
+ bKnown = true;
+
+ rtl::OUString aLayerBaseUrl;
+ bGood = (aArguments[i].Value >>= aLayerBaseUrl);
+
+ if (aLayerBaseUrl.getLength())
+ {
+ rtl::OUString aLocalizedSubDir;
+ LocalSingleBackend::getLayerSubDirectories(aLayerBaseUrl,this->aBaseDataUrl,aLocalizedSubDir);
+
+ mode = findLayers;
+ }
+ else
+ {
+ mode = findNone;
+ }
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ExcludeComponents")))
+ {
+ bKnown = true;
+
+ sal_Int32 const nNextIndex = aExcludeList.getLength();
+
+ switch (aArguments[i].Value.getValueTypeClass())
+ {
+ case uno::TypeClass_STRING:
+ {
+ rtl::OUString aComponent;
+ bGood = (aArguments[i].Value >>= aComponent);
+
+ OSL_ASSERT(bGood);
+
+ aExcludeList.realloc(nNextIndex + 1);
+ aExcludeList[nNextIndex] = aComponent;
+ }
+ break;
+
+ case uno::TypeClass_SEQUENCE:
+ {
+ uno::Sequence<rtl::OUString> aComponentList;
+ bGood = (aArguments[i].Value >>= aComponentList);
+
+ if (bGood)
+ {
+ sal_Int32 const nCompListCount = aComponentList.getLength();
+ aExcludeList.realloc(nNextIndex + nCompListCount);
+
+ rtl::OUString const * pSrc = aComponentList.getConstArray();
+ std::copy(pSrc,pSrc+nCompListCount,aExcludeList.getArray());
+ }
+ }
+ break;
+
+ default:
+ OSL_ASSERT(!bGood);
+ break;
+ }
+ }
+ else if (aArguments[i].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("FetchComponentNames")))
+ {
+ sal_Bool bComponents = sal_False;
+
+ bKnown = true;
+ if (aArguments[i].Value.hasValue())
+ {
+ bGood = (aArguments[i].Value >>= bComponents);
+ if (bGood) result_type = bComponents ? getNames : getUrls;
+ }
+ else
+ {
+ bGood = true;
+ result_type = getDefault;
+ }
+ }
+
+ if (!bGood)
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("LocalHierarchyBrowser - Illegal argument: ");
+ if (bKnown)
+ sMsg.appendAscii("Wrong value type for argument '");
+ else
+ sMsg.appendAscii("Unknown argument '");
+
+ sMsg.append(aArguments[i].Name).appendAscii("'.");
+
+ throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),pJob,i+1);
+ }
+ }
+ if (findNone == mode)
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("LocalHierarchyBrowser - Missing argument: ");
+ sMsg.appendAscii("No data URL available");
+ throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),pJob,0);
+ }
+ if (getDefault == result_type)
+ result_type = (mode == findSchemas) ? getNames : getUrls;
+
+ }
+
+ static
+ inline
+ rtl::OUString getDataFileExtension(JobDesc::Mode mode)
+ {
+ switch (mode)
+ {
+ case JobDesc::findSchemas: return OUSTRING(".xcs");
+ case JobDesc::findLayers: return OUSTRING(".xcu");
+ default: OSL_ASSERT(false); return rtl::OUString();
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+// XJob
+
+uno::Any SAL_CALL
+ LocalHierarchyBrowserService::execute( const uno::Sequence< beans::NamedValue >& Arguments )
+ throw (lang::IllegalArgumentException, uno::Exception, uno::RuntimeException)
+{
+ JobDesc const aJob(this,Arguments);
+
+ OSL_ASSERT(JobDesc::getUrls == aJob.result_type || JobDesc::getNames == aJob.result_type);
+
+ uno::Sequence< rtl::OUString > (LocalHierarchyBrowserService::* const find)( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList) = (JobDesc::getUrls == aJob.result_type) ?
+ &LocalHierarchyBrowserService::findLocalComponentUrls :
+ &LocalHierarchyBrowserService::findLocalComponentNames;
+
+ uno::Sequence< rtl::OUString > aComponents = (this->*find)(aJob.aBaseDataUrl,getDataFileExtension(aJob.mode), aJob.aExcludeList);
+
+ return uno::makeAny(aComponents);
+}
+// -----------------------------------------------------------------------------
+
+// XServiceInfo
+
+rtl::OUString SAL_CALL
+ LocalHierarchyBrowserService::getImplementationName( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getImplementationName( );
+}
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL
+ LocalHierarchyBrowserService::supportsService( const rtl::OUString& ServiceName )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().supportsService( ServiceName );
+}
+// -----------------------------------------------------------------------------
+
+
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ LocalHierarchyBrowserService::getSupportedServiceNames( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getSupportedServiceNames( );
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+#include "filehelper.hxx"
+#include <osl/file.hxx>
+#include "tools/getprocessworkingdir.hxx"
+#include <vector>
+// -----------------------------------------------------------------------------
+
+ namespace uno = com::sun::star::uno;
+ // -----------------------------------------------------------------------------
+
+ #define OSL_VERIFY_RC( expr ) OSL_VERIFY( (expr) == osl::FileBase::E_None )
+ //------------------------------------------------------------------------------
+ static
+ inline
+ bool matchesExtension( rtl::OUString const & aFileName, rtl::OUString const & aExt )
+ {
+ sal_Int32 const nExtStart = aFileName.getLength() - aExt.getLength();
+ return nExtStart > 0 && !!aFileName.copy(nExtStart).equalsIgnoreAsciiCase(aExt);
+ }
+ //------------------------------------------------------------------------------
+ static
+ inline
+ rtl::OUString stripExtension( rtl::OUString const & aFileName, rtl::OUString const & aExt )
+ {
+ OSL_PRECOND( matchesExtension(aFileName,aExt), "File name doesn't have expected extension");
+
+ sal_Int32 const nExtStart = aFileName.getLength() - aExt.getLength();
+ return aFileName.copy(0,nExtStart);
+ }
+//------------------------------------------------------------------------------
+ static
+ inline
+ bool matchesExtension( osl::FileStatus const & aFileDescriptor, rtl::OUString const & aExt )
+ {
+ OSL_PRECOND( aFileDescriptor.isValid(FileStatusMask_Type | FileStatusMask_FileName),
+ "Not all required file-status fields available for filter" );
+
+ if (aFileDescriptor.getFileType() != osl::FileStatus::Regular)
+ return false;
+
+ return matchesExtension(aFileDescriptor.getFileName(),aExt);
+ }
+//------------------------------------------------------------------------------
+
+ static
+ bool makeAbsoluteURL(rtl::OUString & rURL )
+ {
+ rtl::OUString aBaseDir; tools::getProcessWorkingDir(&aBaseDir);
+
+ osl::File::RC errcode = osl::File::getAbsoluteFileURL(aBaseDir,rURL,rURL);
+
+ return osl::File::E_None == errcode;
+ }
+//------------------------------------------------------------------------------
+ static
+ inline
+ bool getNextDirectoryItem(osl::Directory & aDirectory, osl::DirectoryItem & aItem, osl::Directory::RC & errcode)
+ {
+ switch (errcode = aDirectory.getNextItem(aItem))
+ {
+ case osl::Directory::E_None:
+ return true;
+
+ case osl::Directory::E_NOENT:
+ errcode = osl::Directory::E_None;
+ return false;
+
+ default:
+ return false;
+ }
+ }
+//------------------------------------------------------------------------------
+ static inline bool isExcluded(rtl::OUString const & aName, uno::Sequence< rtl::OUString > const & aExcludeList)
+ {
+ for (sal_Int32 i = 0; i<aExcludeList.getLength(); ++i)
+ {
+ if (aExcludeList[i].equals(aName)) return true;
+ }
+ return false;
+ }
+//------------------------------------------------------------------------------
+ static
+ osl::FileBase::RC findComponents( std::vector<rtl::OUString> * componentNames, std::vector<rtl::OUString> * componentUrls,
+ rtl::OUString const& aDirectoryPath, rtl::OUString const& aComponentExtension,
+ rtl::OUString const& aPackagePrefix, rtl::OUString const & aComponentSeparator,
+ uno::Sequence< rtl::OUString > const & aExcludeList)
+ {
+ static sal_Unicode const chDirSep = '/';
+ static rtl::OUString const sDirectorySeparator(&chDirSep,1);
+
+ osl::Directory aDirectory(aDirectoryPath);
+
+ osl::Directory::RC errcode = aDirectory.open();
+
+ if (errcode == osl::Directory::E_None)
+ {
+ sal_uInt32 n_STATUS_FIELDS = FileStatusMask_Type | FileStatusMask_FileName;
+ if (componentUrls) n_STATUS_FIELDS |= FileStatusMask_FileURL;
+
+ osl::DirectoryItem aItem;
+ while( getNextDirectoryItem(aDirectory,aItem,errcode) )
+ {
+
+ osl::FileStatus aItemDescriptor( n_STATUS_FIELDS );
+ errcode = aItem.getFileStatus(aItemDescriptor);
+
+ if ( errcode != osl::DirectoryItem::E_None )
+ {
+ OSL_TRACE("Locating Configuration Components - Error (%u) getting status of directory item - skipping\n", unsigned(errcode));
+ continue;
+ }
+
+ OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_Type), "Could not get type of directory item");
+
+ if (aItemDescriptor.getFileType() == osl::FileStatus::Directory)
+ {
+ OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileName), "Could not get name of subdirectory");
+
+ rtl::OUString const aSubdirName = aItemDescriptor.getFileName();
+ rtl::OUString const aSubdirPath = aDirectoryPath + sDirectorySeparator + aSubdirName;
+ rtl::OUString const aSubpackagePrefix = aPackagePrefix + aSubdirName + aComponentSeparator;
+ // recurse
+ if (!isExcluded(aSubpackagePrefix,aExcludeList))
+ OSL_VERIFY_RC( findComponents( componentNames, componentUrls,
+ aSubdirPath, aComponentExtension,
+ aSubpackagePrefix, aComponentSeparator,
+ aExcludeList) );
+ }
+ else if (matchesExtension(aItemDescriptor,aComponentExtension))
+ {
+ OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileName), "Could not get name of component found");
+
+ rtl::OUString const aComponentName = stripExtension( aItemDescriptor.getFileName(), aComponentExtension );
+ rtl::OUString const aFullComponentName = aPackagePrefix + aComponentName;
+
+ if (!isExcluded(aFullComponentName,aExcludeList))
+ {
+ if (componentNames)
+ {
+ componentNames->push_back(aFullComponentName);
+ }
+
+ if (componentUrls)
+ {
+ OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileURL), "Could not get URL of component found");
+
+ componentUrls->push_back(aItemDescriptor.getFileURL());
+ }
+ }
+ }
+ }
+ aDirectory.close();
+ }
+ return errcode;
+ }
+// -----------------------------------------------------------------------------
+
+ uno::Sequence< rtl::OUString > configmgr::localbe::LocalHierarchyBrowserService::findLocalComponentNames( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList)
+ {
+ rtl::OUString aBaseDirectory(_aBaseDirectory);
+ OSL_VERIFY( makeAbsoluteURL(aBaseDirectory) );
+
+ static const sal_Unicode chPkgSep = '.';
+
+ std::vector< rtl::OUString > components;
+
+ osl::Directory::RC errcode = findComponents(&components, NULL,
+ aBaseDirectory, _aComponentFileExtension,
+ rtl::OUString(), rtl::OUString(&chPkgSep,1),
+ aExcludeList );
+
+ if (errcode != osl::Directory::E_None)
+ {
+ OSL_TRACE("Locating Configuration Components failed - Error (%u) trying to locate files\n", unsigned(errcode));
+
+ if (errcode != osl::Directory::E_NOENT)
+ {
+ rtl::OUString sMsg = OUSTRING("LocalHierarchyBrowser - IO Error while scanning for components: ") +
+ FileHelper::createOSLErrorString(errcode);
+
+ throw com::sun::star::io::IOException(sMsg,*this);
+ }
+ }
+
+ return uno::Sequence< rtl::OUString >(&components.front(),components.size());
+ }
+// -----------------------------------------------------------------------------
+
+ uno::Sequence< rtl::OUString > configmgr::localbe::LocalHierarchyBrowserService::findLocalComponentUrls( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList)
+ {
+ rtl::OUString aBaseDirectory(_aBaseDirectory);
+ OSL_VERIFY( makeAbsoluteURL(aBaseDirectory) );
+
+ static const sal_Unicode chPkgSep = '.';
+
+ std::vector< rtl::OUString > components;
+
+ osl::Directory::RC errcode = findComponents(NULL, &components,
+ aBaseDirectory, _aComponentFileExtension,
+ rtl::OUString(), rtl::OUString(&chPkgSep,1),
+ aExcludeList );
+
+ if (errcode != osl::Directory::E_None)
+ {
+ OSL_TRACE("Locating Configuration Components failed - Error (%u) trying to locate files\n", unsigned(errcode));
+
+ if (errcode != osl::Directory::E_NOENT)
+ {
+ rtl::OUString sMsg = OUSTRING("LocalHierarchyBrowser - IO Error while scanning for component files: ") +
+ FileHelper::createOSLErrorString(errcode);
+
+ throw com::sun::star::io::IOException(sMsg,*this);
+ }
+ }
+
+ return uno::Sequence< rtl::OUString >(&components.front(),components.size());
+ }
+//------------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
diff --git a/configmgr/source/localbe/localhierarchybrowsersvc.hxx b/configmgr/source/localbe/localhierarchybrowsersvc.hxx
new file mode 100644
index 000000000000..11c486f0aca1
--- /dev/null
+++ b/configmgr/source/localbe/localhierarchybrowsersvc.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localhierarchybrowsersvc.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_BROWSERSVC_HXX
+#define CONFIGMGR_LOCALBE_BROWSERSVC_HXX
+
+#include "serviceinfohelper.hxx"
+#include <cppuhelper/implbase2.hxx>
+#include <osl/mutex.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/task/XJob.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace localbe
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace task = ::com::sun::star::task;
+ namespace beans = ::com::sun::star::beans;
+// -----------------------------------------------------------------------------
+
+ class LocalHierarchyBrowserService : public ::cppu::WeakImplHelper2<
+ task::XJob,
+ lang::XServiceInfo
+ >
+ {
+ public:
+ explicit
+ LocalHierarchyBrowserService(uno::Reference< uno::XComponentContext > const & _xContext);
+ ~LocalHierarchyBrowserService();
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& ServiceName )
+ throw (uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException);
+
+ // XJob
+ virtual uno::Any SAL_CALL
+ execute( const uno::Sequence< beans::NamedValue >& Arguments )
+ throw (lang::IllegalArgumentException, uno::Exception, uno::RuntimeException);
+
+ private:
+ uno::Reference< lang::XMultiServiceFactory > getServiceFactory() const
+ { return m_xServiceFactory; }
+
+ uno::Sequence< rtl::OUString > findLocalComponentNames( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList);
+ uno::Sequence< rtl::OUString > findLocalComponentUrls( rtl::OUString const & _aBaseDirectory, rtl::OUString const & _aComponentFileExtension, uno::Sequence< rtl::OUString > const & aExcludeList);
+ private:
+ uno::Reference< lang::XMultiServiceFactory > m_xServiceFactory;
+
+ static ServiceInfoHelper getServiceInfo();
+ };
+// -----------------------------------------------------------------------------
+ } // namespace localbe
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/localbe/localmultistratum.cxx b/configmgr/source/localbe/localmultistratum.cxx
new file mode 100644
index 000000000000..65c71a727391
--- /dev/null
+++ b/configmgr/source/localbe/localmultistratum.cxx
@@ -0,0 +1,250 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localmultistratum.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "localmultistratum.hxx"
+#include "localfilehelper.hxx"
+#include "filehelper.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif // CONFIGMGR_API_FACTORY_HXX_
+#include "serviceinfohelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
+#include <osl/file.hxx>
+
+namespace configmgr { namespace localbe {
+
+//==============================================================================
+
+static inline
+rtl::OUString const & impl_getLayerDataDirectory(rtl::OUString const & aLayerBaseUrl)
+{ return aLayerBaseUrl; }
+//------------------------------------------------------------------------------
+static //inline
+rtl::OUString makeLayerId(rtl::OUString const & aComponent,rtl::OUString const & aParticleFile)
+{
+ OSL_ASSERT(aParticleFile.endsWithIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(kLocalDataSuffix)));
+ const sal_Int32 kExtLength = RTL_CONSTASCII_LENGTH(kLocalDataSuffix);
+ rtl::OUString const aParticleName = aParticleFile.copy(0,aParticleFile.getLength() - kExtLength);
+
+ rtl::OUStringBuffer aLayerId(aComponent);
+ aLayerId.append(k_cLayerIdSeparator);
+ aLayerId.append(aParticleName);
+
+ return aLayerId.makeStringAndClear();
+}
+
+LocalMultiStratum::LocalMultiStratum(const uno::Reference<uno::XComponentContext>& xContext)
+: cppu::ImplInheritanceHelper1< LocalStratumBase, backend::XMultiLayerStratum >(xContext)
+{
+}
+//------------------------------------------------------------------------------
+
+LocalMultiStratum::~LocalMultiStratum() {}
+
+//------------------------------------------------------------------------------
+uno::Sequence< rtl::OUString > SAL_CALL
+ LocalMultiStratum::listLayerIds( const rtl::OUString& aComponent,
+ const rtl::OUString& /*aEntity*/ )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException)
+{
+ rtl::OUString const aLayerUrl = impl_getLayerDataDirectory(getBaseUrl());
+ rtl::OUString const aComponentUrl = aLayerUrl + componentToPath(aComponent);
+
+ const sal_uInt32 k_STATUS_FIELDS = FileStatusMask_Type | FileStatusMask_FileName;
+ osl::Directory aComponentDirectory(aComponentUrl);
+ osl::DirectoryItem aItem;
+ std::vector< rtl::OUString > aResult;
+
+ osl::Directory::RC errcode = aComponentDirectory.open();
+ switch (errcode)
+ {
+ case osl::Directory::E_NOENT:
+ return uno::Sequence< rtl::OUString >();
+
+ case osl::Directory::E_None:
+ while (osl::Directory::E_None == (errcode=aComponentDirectory.getNextItem(aItem)))
+ {
+ osl::FileStatus aItemDescriptor( k_STATUS_FIELDS );
+ errcode = aItem.getFileStatus(aItemDescriptor);
+
+ if ( errcode != osl::DirectoryItem::E_None )
+ {
+ OSL_ASSERT(errcode != osl::Directory::E_NOENT); // unexpected failure for getFileStatus for existing file
+ if (errcode == osl::Directory::E_NOENT) continue;
+
+ OSL_TRACE("Reading Component Directory - Error (%u) getting status of directory item.\n", unsigned(errcode));
+ break;
+ }
+
+ OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_Type), "Could not get type of directory item");
+ if (aItemDescriptor.getFileType() != osl::FileStatus::Regular)
+ continue;
+
+ OSL_ENSURE( aItemDescriptor.isValid(FileStatusMask_FileName), "Could not get name of component found");
+ rtl::OUString const aFileName = aItemDescriptor.getFileName();
+ if (!aFileName.endsWithIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(kLocalDataSuffix)))
+ continue;
+
+ aResult.push_back( makeLayerId(aComponent,aFileName) );
+ }
+ OSL_ASSERT(errcode != osl::Directory::E_None); // Loop postcond
+
+ // joint error handling with open failure
+ if (errcode != osl::Directory::E_NOENT) // normal loop termination
+ {
+ default: // if open() truly failed we also go here
+ rtl::OUStringBuffer errbuf;
+ errbuf.appendAscii("LocalMultiStratum::listLayerIds: ");
+ errbuf.appendAscii("Error scanning directory ").append(aComponentUrl)
+ .appendAscii(" for particle files. ");
+ errbuf.appendAscii("Error: ").append(FileHelper::createOSLErrorString(errcode));
+ rtl::OUString const errmsg = errbuf.makeStringAndClear();
+ throw backend::BackendAccessException(errmsg,*this,uno::Any());
+ }
+
+ return aResult.empty()
+ ? uno::Sequence< rtl::OUString >()
+ : uno::Sequence< rtl::OUString >(
+ &aResult.front(), static_cast<sal_Int32>(aResult.size()));
+ }
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString SAL_CALL
+ LocalMultiStratum::getUpdateLayerId( const rtl::OUString& aComponent,
+ const rtl::OUString& /*aEntity*/ )
+ throw (backend::BackendAccessException, lang::NoSupportException,
+ lang::IllegalArgumentException, uno::RuntimeException)
+{
+ failReadonly();
+ return aComponent;
+}
+
+//------------------------------------------------------------------------------
+uno::Reference< backend::XLayer > SAL_CALL
+ LocalMultiStratum::getLayer( const rtl::OUString& aLayerId,
+ const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return LocalStratumBase::getLayer(aLayerId,aTimestamp);
+}
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Reference< backend::XLayer > > SAL_CALL
+ LocalMultiStratum::getLayers( const uno::Sequence< rtl::OUString >& aLayerIds,
+ const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ sal_Int32 const nLayers = aLayerIds.getLength();
+ uno::Sequence< uno::Reference< backend::XLayer > > aResult(nLayers);
+ for (sal_Int32 ix=0; ix<nLayers; ++ix)
+ {
+ aResult[ix] = LocalStratumBase::getLayer(aLayerIds[ix],aTimestamp);
+ }
+ return aResult;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Reference< backend::XLayer > > SAL_CALL
+ LocalMultiStratum::getMultipleLayers( const uno::Sequence< rtl::OUString >& aLayerIds,
+ const uno::Sequence< rtl::OUString >& aTimestamps )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (aLayerIds.getLength() != aTimestamps.getLength()) {
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalStratum::getMultipleLayers(): Timestamp count does not match layer count")),
+ *this, 0) ;
+ }
+ sal_Int32 const nLayers = aLayerIds.getLength();
+ uno::Sequence< uno::Reference< backend::XLayer > > aResult(nLayers);
+ for (sal_Int32 ix=0; ix<nLayers; ++ix)
+ {
+ aResult[ix] = LocalStratumBase::getLayer(aLayerIds[ix],aTimestamps[ix]);
+ }
+ return aResult;
+}
+
+//------------------------------------------------------------------------------
+uno::Reference< backend::XUpdatableLayer > SAL_CALL
+ LocalMultiStratum::getUpdatableLayer( const rtl::OUString& /*aLayerId*/ )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ lang::NoSupportException, uno::RuntimeException)
+{
+ failReadonly();
+ return 0;
+}
+//------------------------------------------------------------------------------
+
+void LocalMultiStratum::getLayerDirectories(rtl::OUString& aLayerUrl,
+ rtl::OUString& aSubLayerUrl) const
+{
+ aLayerUrl = impl_getLayerDataDirectory(getBaseUrl());
+ aSubLayerUrl = rtl::OUString();
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+static const sal_Char * const kMultiStratumImplementation =
+ "com.sun.star.comp.configuration.backend.LocalMultiStratum" ;
+static const sal_Char * const kBackendService =
+ "com.sun.star.configuration.backend.MultiStratum" ;
+static const sal_Char * const kLocalService =
+ "com.sun.star.configuration.backend.LocalMultiStratum" ;
+
+static sal_Char const * kServiceNames [] = { kLocalService, 0, kBackendService, 0 } ;
+static const ServiceImplementationInfo kMultiStratumServiceInfo = { kMultiStratumImplementation , kServiceNames, kServiceNames + 2 } ;
+
+const ServiceRegistrationInfo *getLocalMultiStratumServiceInfo()
+{ return getRegistrationInfo(&kMultiStratumServiceInfo) ; }
+
+uno::Reference<uno::XInterface> SAL_CALL
+instantiateLocalMultiStratum(const uno::Reference< uno::XComponentContext >& xContext) {
+ return *new LocalMultiStratum(xContext) ;
+}
+
+//------------------------------------------------------------------------------
+
+const ServiceImplementationInfo * LocalMultiStratum::getServiceInfoData() const
+{
+ return &kMultiStratumServiceInfo;
+}
+//------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------
+
+} } // configmgr.localsinglestratum
diff --git a/configmgr/source/localbe/localmultistratum.hxx b/configmgr/source/localbe/localmultistratum.hxx
new file mode 100644
index 000000000000..6bb7f623d4d9
--- /dev/null
+++ b/configmgr/source/localbe/localmultistratum.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localmultistratum.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_LOCALMULTISTRATUM_HXX_
+#define CONFIGMGR_LOCALBE_LOCALMULTISTRATUM_HXX_
+
+#include "localstratumbase.hxx"
+#include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+namespace configmgr
+{
+ namespace localbe
+ {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backend = css::configuration::backend ;
+
+/**
+ Implements the MultiLayerStratum service for local file access.
+ */
+class LocalMultiStratum : public cppu::ImplInheritanceHelper1< LocalStratumBase, backend::XMultiLayerStratum >
+{
+public :
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ LocalMultiStratum(const uno::Reference<uno::XComponentContext>& xContext) ;
+
+ /** Destructor */
+ ~LocalMultiStratum() ;
+
+
+ // XMultiLayerStratum
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ listLayerIds( const rtl::OUString& aComponent, const rtl::OUString& aEntity )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ getUpdateLayerId( const rtl::OUString& aComponent, const rtl::OUString& aEntity )
+ throw (backend::BackendAccessException, lang::NoSupportException,
+ lang::IllegalArgumentException, uno::RuntimeException);
+
+ virtual uno::Reference< backend::XLayer > SAL_CALL
+ getLayer( const rtl::OUString& aLayerId, const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException);
+
+ virtual uno::Sequence< uno::Reference< backend::XLayer > > SAL_CALL
+ getLayers( const uno::Sequence< rtl::OUString >& aLayerIds, const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException);
+
+ virtual uno::Sequence< uno::Reference< backend::XLayer > > SAL_CALL
+ getMultipleLayers( const uno::Sequence< rtl::OUString >& aLayerIds, const uno::Sequence< rtl::OUString >& aTimestamps )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException);
+
+ virtual uno::Reference< backend::XUpdatableLayer > SAL_CALL
+ getUpdatableLayer( const rtl::OUString& aLayerId )
+ throw (backend::BackendAccessException, lang::NoSupportException,
+ lang::IllegalArgumentException, uno::RuntimeException);
+
+private:
+ virtual void getLayerDirectories(rtl::OUString& aLayerUrl, rtl::OUString& aSubLayerUrl) const;
+ virtual const ServiceImplementationInfo * getServiceInfoData() const;
+} ;
+
+
+} } // configmgr.localbe
+
+#endif
diff --git a/configmgr/source/localbe/localoutputstream.cxx b/configmgr/source/localbe/localoutputstream.cxx
new file mode 100644
index 000000000000..f4b538f63c65
--- /dev/null
+++ b/configmgr/source/localbe/localoutputstream.cxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localoutputstream.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "localoutputstream.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
+
+namespace configmgr { namespace localbe {
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+
+LocalOutputStream::LocalOutputStream(const rtl::OUString& aFileUrl)
+ throw (backend::BackendAccessException, uno::RuntimeException)
+: mFileUrl(aFileUrl)
+, mTemporaryFileUrl(mFileUrl)
+, mWriteFile(NULL)
+{
+ // First, ensure the directory where the file is supposed to be
+ // put exists.
+ mTemporaryFileUrl += rtl::OUString::createFromAscii("_tmp") ;
+ rtl::OUString parentDirectory = FileHelper::getParentDir(aFileUrl) ;
+
+ if (osl::File::RC errorCode = FileHelper::mkdirs(parentDirectory))
+ {
+ rtl::OUStringBuffer message ;
+ message.appendAscii("Cannot create directory \"") ;
+ message.append(parentDirectory).appendAscii("\". Error is ") ;
+ message.append(FileHelper::createOSLErrorString(errorCode));
+ message.appendAscii(" [").append(sal_Int32(errorCode)).appendAscii("].") ;
+
+ rtl::OUString const sIOMsg = message.makeStringAndClear();
+ uno::Any ioe = uno::makeAny(io::IOException(sIOMsg,0));
+
+ switch (errorCode)
+ {
+ case osl::File::E_ACCES:
+ case osl::File::E_ROFS:
+ message.appendAscii("Configuration LocalOutputStream - No Write Access: ");
+ message.append(sIOMsg);
+ throw backend::InsufficientAccessRightsException(message.makeStringAndClear(), NULL, ioe) ;
+
+ case osl::File::E_None: OSL_ASSERT(!"can't happen");
+ default:
+ message.appendAscii("Configuration LocalOutputStream - IO Error: ");
+ message.append(sIOMsg);
+ throw backend::BackendAccessException(message.makeStringAndClear(), NULL, ioe) ;
+ }
+ }
+
+ osl::File::remove(mTemporaryFileUrl) ;
+ mWriteFile = new osl::File(mTemporaryFileUrl) ;
+
+ if (osl::File::RC errorCode = mWriteFile->open(OpenFlag_Write | OpenFlag_Create) )
+ {
+ delete mWriteFile, mWriteFile = NULL;
+
+ rtl::OUStringBuffer message ;
+ message.appendAscii("Cannot open file \"") ;
+ message.append(mTemporaryFileUrl).appendAscii("\" for writing. ");
+ message.appendAscii("Error is ").append(FileHelper::createOSLErrorString(errorCode));
+ message.appendAscii(" [").append(sal_Int32(errorCode)).appendAscii("].") ;
+
+ rtl::OUString const sIOMsg = message.makeStringAndClear();
+ uno::Any ioe = uno::makeAny(io::IOException(sIOMsg,0));
+
+ switch (errorCode)
+ {
+ case osl::File::E_EXIST: // take inability to remove as indicator of missing rights
+ case osl::File::E_ACCES:
+ case osl::File::E_ROFS:
+ message.appendAscii("Configuration LocalOutputStream - No Write Access: ");
+ message.append(sIOMsg);
+ throw backend::InsufficientAccessRightsException(message.makeStringAndClear(), NULL, ioe) ;
+
+ case osl::File::E_None: OSL_ASSERT(!"can't happen");
+ default:
+ message.appendAscii("Configuration LocalOutputStream - IO Error: ");
+ message.append(sIOMsg);
+ throw backend::BackendAccessException(message.makeStringAndClear(), NULL, ioe) ;
+ }
+ }
+ mTemporaryFile = new OSLOutputStreamWrapper(*mWriteFile) ;
+}
+//------------------------------------------------------------------------------
+
+LocalOutputStream::~LocalOutputStream()
+{
+ try
+ {
+ this->closeOutput();
+ }
+ catch (uno::Exception&)
+ {
+ OSL_ENSURE(false,"Exception from closing LocalOutputStream ignored.");
+ }
+
+ delete mWriteFile;
+}
+//------------------------------------------------------------------------------
+
+void LocalOutputStream::finishOutput()
+ throw (backend::BackendAccessException, uno::RuntimeException)
+{
+ if (mWriteFile)
+ try
+ {
+ this->closeOutput();
+ delete mWriteFile, mWriteFile = NULL;
+
+ FileHelper::replaceFile(mFileUrl, mTemporaryFileUrl) ;
+ }
+ catch (io::IOException& ioe)
+ {
+ rtl::OUStringBuffer message ;
+ message.appendAscii("Configuration LocalOutputStream - IO Error: ");
+ message.appendAscii("Cannot finish output to \"").append(mTemporaryFileUrl) ;
+ message.appendAscii("\" or copy the result to \"").append(mFileUrl).appendAscii("\". ");
+ message.appendAscii("Error is \"").append(ioe.Message).appendAscii("\". ");
+ throw backend::BackendAccessException(message.makeStringAndClear(), *this, uno::makeAny(ioe));
+ }
+}
+//------------------------------------------------------------------------------
+
+inline
+uno::Reference<io::XOutputStream> LocalOutputStream::getOutputFile()
+{
+ if (!mTemporaryFile.is())
+ {
+ throw io::NotConnectedException(
+ rtl::OUString::createFromAscii("LocalOutputStream: no output file."),
+ *this);
+ }
+ return mTemporaryFile;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL LocalOutputStream::writeBytes(const uno::Sequence<sal_Int8>& aData)
+ throw (io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException)
+{
+ getOutputFile()->writeBytes(aData) ;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL LocalOutputStream::flush()
+ throw (io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException)
+{
+ getOutputFile()->flush() ;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL LocalOutputStream::closeOutput()
+ throw (io::NotConnectedException, io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException)
+{
+ if (mTemporaryFile.is())
+ {
+ mTemporaryFile->closeOutput() ;
+
+ mTemporaryFile.clear();
+ }
+}
+//------------------------------------------------------------------------------
+
+} } // configmgr.localbe
diff --git a/configmgr/source/localbe/localoutputstream.hxx b/configmgr/source/localbe/localoutputstream.hxx
new file mode 100644
index 000000000000..fa86c0e73b1e
--- /dev/null
+++ b/configmgr/source/localbe/localoutputstream.hxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localoutputstream.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_LOCALOUTPUTSTREAM_HXX_
+#define CONFIGMGR_LOCALBE_LOCALOUTPUTSTREAM_HXX_
+
+#include "oslstream.hxx"
+#include "filehelper.hxx"
+#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
+
+namespace configmgr { namespace localbe {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace io = css::io ;
+namespace backend = css::configuration::backend ;
+
+/**
+ Class wrapping the use of the XOutputStream implementation on a file
+ to make it handle a temporary file and synch the contents to the
+ actual file being accessed only on successful completion of the output
+ process.
+ */
+class LocalOutputStream : public cppu::WeakImplHelper1<io::XOutputStream>
+{
+ public :
+ /**
+ Constructor using the URL of the file to access.
+ The actual writing will occur in a temporary file
+ whose name is derived from the URL, and the file
+ specified by the parameter will be overwritten
+ on closing the stream.
+
+ @param aFileUrl URL of the file to write
+ @throws com::sun::star::io::IOException
+ if access to the temporary file fails.
+ */
+ LocalOutputStream(const rtl::OUString& aFileUrl)
+ throw (backend::BackendAccessException, uno::RuntimeException) ;
+ /** Destructor */
+ ~LocalOutputStream(void) ;
+
+ // closeOutput and mark as successful
+ void finishOutput()
+ throw (backend::BackendAccessException, uno::RuntimeException) ;
+ protected :
+ // XOutputStream
+ virtual void SAL_CALL writeBytes(const uno::Sequence<sal_Int8>& aData)
+ throw (io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException);
+
+ virtual void SAL_CALL flush(void)
+ throw (io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException);
+
+ virtual void SAL_CALL closeOutput(void)
+ throw (io::NotConnectedException,
+ io::BufferSizeExceededException,
+ io::IOException, uno::RuntimeException) ;
+
+
+ private :
+ uno::Reference<io::XOutputStream> getOutputFile() ;
+
+ /** Temporary file used during access */
+ uno::Reference<io::XOutputStream> mTemporaryFile ;
+ /** URL of the target file */
+ rtl::OUString mFileUrl ;
+ /** URL of the temporary file */
+ rtl::OUString mTemporaryFileUrl ;
+ /** File being written */
+ osl::File *mWriteFile ;
+} ;
+
+} } // configmgr.localbe
+
+#endif // CONFIGMGR_LOCALBE_LOCALOUTPUTSTREAM_HXX_
diff --git a/configmgr/source/localbe/localschemasupplier.cxx b/configmgr/source/localbe/localschemasupplier.cxx
new file mode 100644
index 000000000000..c85b985976e1
--- /dev/null
+++ b/configmgr/source/localbe/localschemasupplier.cxx
@@ -0,0 +1,291 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localschemasupplier.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "localschemasupplier.hxx"
+#include "localfilehelper.hxx"
+#include "oslstream.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif // CONFIGMGR_API_FACTORY_HXX_
+#include "serviceinfohelper.hxx"
+#include "bootstrap.hxx"
+#include "filehelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <memory>
+
+namespace configmgr { namespace localbe {
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+
+LocalSchemaSupplier::LocalSchemaSupplier(
+ const uno::Reference<uno::XComponentContext>& xContext)
+ : cppu::WeakComponentImplHelper3<backend::XVersionedSchemaSupplier, lang::XInitialization, lang::XServiceInfo>(mMutex), mFactory(xContext->getServiceManager(),uno::UNO_QUERY) {
+}
+//------------------------------------------------------------------------------
+
+LocalSchemaSupplier::~LocalSchemaSupplier(void) {}
+//------------------------------------------------------------------------------
+static const rtl::OUString kSchemaDataUrl(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"SchemaDataUrl")) ;
+
+static const rtl::OUString kSchemaVersion(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"SchemaVersion")) ;
+
+void SAL_CALL LocalSchemaSupplier::initialize(
+ const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ css::configuration::InvalidBootstrapFileException,
+ backend::CannotConnectException,
+ backend::BackendSetupException)
+{
+ if (aParameters.getLength() == 0) {
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "No parameters provided to LocalSchemaSupplier")),
+ *this, 0) ;
+ }
+ uno::Reference<uno::XComponentContext> context ;
+
+ for (sal_Int32 i = 0 ; i < aParameters.getLength() ; ++ i) {
+ if (aParameters [i] >>= context) { break ; }
+ }
+
+ // Setting: schema version
+ // TODO: Add support for repository-specific versions
+ uno::Any const aSchemaVersionSetting = context->getValueByName(kSchemaVersion);
+ aSchemaVersionSetting >>= mSchemaVersion;
+
+ // Setting: schema diretory(ies)
+ uno::Any const aSchemaDataSetting = context->getValueByName(kSchemaDataUrl);
+ uno::Sequence< rtl::OUString > aSchemas;
+ rtl::OUString schemas;
+
+ if (aSchemaDataSetting >>= schemas)
+ {
+ fillFromBlankSeparated(schemas, aSchemas) ;
+ }
+ else
+ {
+ aSchemaDataSetting >>= aSchemas;
+ }
+ //validate SchemaDataUrls
+ mSchemaDataUrls.realloc(aSchemas.getLength());
+
+ sal_Int32 nSchemaLocations =0;
+ sal_Int32 nExistingSchemaLocations = 0;
+ for (sal_Int32 j = 0; j < aSchemas.getLength(); ++j)
+ {
+ bool bOptional = checkOptionalArg(aSchemas[j]);
+
+ if(!bOptional)
+ validateFileURL(aSchemas[j],*this);
+ else if (!isValidFileURL(aSchemas[j]))
+ continue;
+
+ OSL_ASSERT(isValidFileURL(aSchemas[j]));
+
+ //NormalizeURL
+ implEnsureAbsoluteURL(aSchemas[j]);
+ if(!normalizeURL(aSchemas[j],*this,bOptional))
+ continue;
+
+ //now we have a correct file URL, which we will use
+ mSchemaDataUrls[nSchemaLocations++]= aSchemas[j];
+ if (!bOptional)
+ checkFileExists(aSchemas[j],*this);
+
+ else if(!FileHelper::fileExists(aSchemas[j]))
+ continue; // skip the directory check
+
+ checkIfDirectory(aSchemas[j],*this);
+ ++nExistingSchemaLocations;
+ }
+ if (0 == nExistingSchemaLocations)
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("LocalBackend: No schema directories found");
+ throw backend::BackendSetupException(sMsg,*this, uno::Any()) ;
+ }
+ mSchemaDataUrls.realloc(nSchemaLocations);
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL
+ LocalSchemaSupplier::getSchemaVersion(const rtl::OUString& /*aComponent*/)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ // TODO: Add support for repository-specific versions
+ return mSchemaVersion;
+}
+//------------------------------------------------------------------------------
+static const rtl::OUString kSchemaSuffix(RTL_CONSTASCII_USTRINGPARAM(".xcs")) ;
+static const rtl::OUString kXMLSchemaParser(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.backend.xml.SchemaParser")) ;
+
+uno::Reference<backend::XSchema> SAL_CALL
+ LocalSchemaSupplier::getComponentSchema(const rtl::OUString& aComponent)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ rtl::OUString subPath = componentToPath(aComponent) ;
+
+ osl::File * schemaFile = NULL;
+ rtl::OUString errorMessage;
+ bool bInsufficientAccess = false;
+ for (sal_Int32 ix = 0; ix < mSchemaDataUrls.getLength(); ++ix)
+ {
+ rtl::OUStringBuffer schemaUrl(mSchemaDataUrls[ix]) ;
+
+ schemaUrl.append(subPath).append(kSchemaSuffix) ;
+
+ rtl::OUString const aFileUrl = schemaUrl.makeStringAndClear();
+
+ std::auto_ptr<osl::File> checkFile( new osl::File(aFileUrl) );
+ osl::File::RC rc = checkFile->open(OpenFlag_Read) ;
+
+ if (rc == osl::File::E_None)
+ {
+ schemaFile = checkFile.release();
+ break;
+ }
+ else if (rc != osl::File::E_NOENT)
+ {
+ if (rc == osl::File::E_ACCES)
+ bInsufficientAccess =true;
+
+ // accumulate error messages
+ rtl::OUStringBuffer sMsg(errorMessage);
+ if (errorMessage.getLength())
+ sMsg.appendAscii("LocalFile SchemaSupplier - Error accessing schema: ");
+
+ sMsg.appendAscii("\n- Cannot open input file \"");
+ sMsg.append(aFileUrl);
+ sMsg.appendAscii("\" : ");
+ sMsg.append(FileHelper::createOSLErrorString(rc));
+
+ errorMessage = sMsg.makeStringAndClear();
+ }
+ }
+
+ if (NULL == schemaFile)
+ {
+ if (errorMessage.getLength() != 0)
+ {
+ // a real error occured
+ io::IOException ioe(errorMessage,*this);
+
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("LocalFileLayer - Cannot readData: ").append(errorMessage);
+
+ if (bInsufficientAccess)
+ throw backend::InsufficientAccessRightsException(sMsg.makeStringAndClear(),*this,uno::makeAny(ioe));
+ else
+ throw backend::BackendAccessException(sMsg.makeStringAndClear(),*this,uno::makeAny(ioe));
+ }
+ // simply not found
+ return NULL;
+ }
+
+ uno::Sequence<uno::Any> arguments(1) ;
+ uno::Reference<io::XInputStream> stream( new OSLInputStreamWrapper(schemaFile, true) );
+
+ arguments [0] <<= stream ;
+ uno::Reference<backend::XSchema> schema(
+ mFactory->createInstanceWithArguments(kXMLSchemaParser, arguments),
+ uno::UNO_QUERY) ;
+
+ if (!schema.is())
+ {
+ throw uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Cannot instantiate Schema Parser for ")) + aComponent,
+ *this) ;
+ }
+ return schema ;
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+
+static const sal_Char * const kImplementation =
+ "com.sun.star.comp.configuration.backend.LocalSchemaSupplier" ;
+static const sal_Char * const kSchemaService =
+ "com.sun.star.configuration.backend.SchemaSupplier" ;
+static const sal_Char * const kLocalService =
+ "com.sun.star.configuration.backend.LocalSchemaSupplier" ;
+
+static sal_Char const * kServiceNames [] = {kLocalService, 0, kSchemaService, 0 } ;
+static const ServiceImplementationInfo kServiceInfo = { kImplementation, kServiceNames,kServiceNames+2 } ;
+
+const ServiceRegistrationInfo *getLocalSchemaSupplierServiceInfo()
+{ return getRegistrationInfo(&kServiceInfo) ; }
+
+uno::Reference<uno::XInterface> SAL_CALL
+instantiateLocalSchemaSupplier(const uno::Reference< uno::XComponentContext >& xContext) {
+ return *new LocalSchemaSupplier(xContext) ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL LocalSchemaSupplier::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).getImplementationName() ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL LocalSchemaSupplier::supportsService(
+ const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).supportsService(aServiceName);
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString>
+SAL_CALL LocalSchemaSupplier::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ;
+}
+
+// ---------------------------------------------------------------------------------------
+
+} } // configmgr.localbe
diff --git a/configmgr/source/localbe/localschemasupplier.hxx b/configmgr/source/localbe/localschemasupplier.hxx
new file mode 100644
index 000000000000..4447c98f984b
--- /dev/null
+++ b/configmgr/source/localbe/localschemasupplier.hxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localschemasupplier.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_LOCALSCHEMASUPPLIER_HXX_
+#define CONFIGMGR_LOCALBE_LOCALSCHEMASUPPLIER_HXX_
+
+#include <com/sun/star/configuration/backend/XVersionedSchemaSupplier.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/backend/CannotConnectException.hpp>
+#include <cppuhelper/compbase3.hxx>
+
+namespace configmgr { namespace localbe {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backend = css::configuration::backend ;
+
+/**
+ Implements the SchemaSupplier service for local schema file access.
+ */
+class LocalSchemaSupplier : public cppu::WeakComponentImplHelper3<backend::XVersionedSchemaSupplier, lang::XInitialization, lang::XServiceInfo> {
+ public :
+ /**
+ Service constructor from a service factory.
+
+ @param xConxtext Component Context
+ */
+ LocalSchemaSupplier(const uno::Reference<uno::XComponentContext>& xContext) ;
+
+ /** Destructor */
+ ~LocalSchemaSupplier(void) ;
+
+
+ // XInitialize
+ virtual void SAL_CALL
+ initialize( const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ css::configuration::InvalidBootstrapFileException,
+ backend::CannotConnectException,
+ backend::BackendSetupException);
+
+ // XVersionedSchemaSupplier
+ virtual rtl::OUString SAL_CALL
+ getSchemaVersion( const rtl::OUString& aComponent )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ // XSchemaSupplier
+ virtual uno::Reference<backend::XSchema> SAL_CALL
+ getComponentSchema( const rtl::OUString& aComponent )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException) ;
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& aServiceName )
+ throw (uno::RuntimeException) ;
+
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException) ;
+
+ private :
+ /** Service factory */
+ uno::Reference<lang::XMultiServiceFactory> mFactory ;
+ /** Mutex for resources protection */
+ osl::Mutex mMutex ;
+ /**
+ Base of the schema data. Is a list to allow
+ for multiple schema directories.
+ */
+ uno::Sequence<rtl::OUString> mSchemaDataUrls ;
+ /** Version of the schema repository */
+ // TODO: Add support for repository-specific versions
+ rtl::OUString mSchemaVersion;
+} ;
+
+} } // configmgr.localschemasupplirt
+
+#endif // CONFIGMGR_LOCALBE_LOCALSCHEMASUPPLIER_HXX_
diff --git a/configmgr/source/localbe/localsinglebackend.cxx b/configmgr/source/localbe/localsinglebackend.cxx
new file mode 100644
index 000000000000..ef41babb04c2
--- /dev/null
+++ b/configmgr/source/localbe/localsinglebackend.cxx
@@ -0,0 +1,801 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localsinglebackend.cxx,v $
+ * $Revision: 1.23 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "localsinglebackend.hxx"
+#include "localfilehelper.hxx"
+#include "localfilelayer.hxx"
+#include "oslstream.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif // CONFIGMGR_API_FACTORY_HXX_
+#include "serviceinfohelper.hxx"
+#include "bootstrap.hxx"
+#include "filehelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <memory>
+
+namespace configmgr { namespace localbe {
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+
+LocalSingleBackend::LocalSingleBackend(
+ const uno::Reference<uno::XComponentContext>& xContext)
+ : cppu::WeakComponentImplHelper5<backend::XSchemaSupplier, backend::XMultiLayerStratum, backend::XBackendEntities, lang::XInitialization, lang::XServiceInfo>(mMutex), mFactory(xContext->getServiceManager(),uno::UNO_QUERY) {
+}
+//------------------------------------------------------------------------------
+
+LocalSingleBackend::~LocalSingleBackend(void) {}
+//------------------------------------------------------------------------------
+static const rtl::OUString kSchemaDataUrl(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"SchemaDataUrl")) ;
+static const rtl::OUString kDefaultDataUrl(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"DefaultLayerUrls")) ;
+static const rtl::OUString kUserDataUrl(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"UserLayerUrl")) ;
+static const rtl::OUString kEntity(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_PREFIX_"EntityLayer")) ;
+
+static const rtl::OUString kAdminModeFlag(
+ RTL_CONSTASCII_USTRINGPARAM(CONTEXT_ITEM_ADMINFLAG)) ;
+
+void SAL_CALL LocalSingleBackend::initialize(
+ const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ css::configuration::InvalidBootstrapFileException,
+ backend::CannotConnectException,
+ backend::BackendSetupException)
+{
+ if (aParameters.getLength() == 0) {
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "No parameters provided to SingleBackend")),
+ *this, 0) ;
+ }
+ uno::Reference<uno::XComponentContext> context ;
+
+ for (sal_Int32 i = 0 ; i < aParameters.getLength() ; ++ i) {
+ if (aParameters [i] >>= context) { break ; }
+ }
+
+ // Setting: schema diretory(ies)
+ uno::Any const aSchemaDataSetting = context->getValueByName(kSchemaDataUrl);
+ uno::Sequence< rtl::OUString > aSchemas;
+ rtl::OUString schemas;
+
+ if (aSchemaDataSetting >>= schemas)
+ {
+ fillFromBlankSeparated(schemas, aSchemas) ;
+ }
+ else
+ {
+ aSchemaDataSetting >>= aSchemas;
+ }
+ //validate SchemaDataUrls
+ mSchemaDataUrls.realloc(aSchemas.getLength());
+
+ sal_Int32 nSchemaLocations = 0;
+ sal_Int32 nExistingSchemaLocations = 0;
+ for (sal_Int32 j = 0; j < aSchemas.getLength(); ++j)
+ {
+ bool bOptional = checkOptionalArg(aSchemas[j]);
+
+ if (!bOptional)
+ validateFileURL(aSchemas[j],*this);
+
+ else if (!isValidFileURL(aSchemas[j]))
+ continue;
+
+ OSL_ASSERT(isValidFileURL(aSchemas[j]));
+
+ //NormalizeURL
+ implEnsureAbsoluteURL(aSchemas[j]);
+ if (!normalizeURL(aSchemas[j],*this,bOptional))
+ continue;
+
+ // now we have a correct file URL, which we will use
+ mSchemaDataUrls[nSchemaLocations++] = aSchemas[j];
+
+ // check existence
+ if (!bOptional)
+ checkFileExists(aSchemas[j], *this);
+
+ else if(!FileHelper::fileExists(aSchemas[j]))
+ continue; // skip the directory check
+
+
+ checkIfDirectory(aSchemas[j],*this);
+
+ ++nExistingSchemaLocations;
+ }
+ mSchemaDataUrls.realloc(nSchemaLocations);
+
+ if (0 == nExistingSchemaLocations)
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("LocalBackend: No schema directories found");
+ throw backend::BackendSetupException(sMsg,*this, uno::Any()) ;
+ }
+
+ // Setting: default layer(s)
+ uno::Any const aDefaultDataSetting = context->getValueByName(kDefaultDataUrl);
+ uno::Sequence< rtl::OUString > aDefaults;
+ rtl::OUString defaults;
+
+ if (aDefaultDataSetting >>= defaults)
+ {
+ fillFromBlankSeparated(defaults, aDefaults) ;
+ }
+ else
+ {
+ aDefaultDataSetting >>= aDefaults ;
+ }
+
+ //validate DefaultDataUrls
+ mDefaultDataUrls.realloc(aDefaults.getLength());
+ sal_Int32 nDefaultLayers = 0;
+
+ for (sal_Int32 ix = 0; ix < aDefaults.getLength(); ++ix)
+ {
+ // skip invalid URLs
+ if (!isValidFileURL(aDefaults[ix]))
+ continue;
+
+ //NormalizeURL
+ implEnsureAbsoluteURL(aDefaults[ix]);
+ if (!normalizeURL(aDefaults[ix],*this,true))
+ continue;
+
+ if(FileHelper::fileExists(aDefaults[ix]))
+ {
+ checkIfDirectory(aDefaults[ix],*this);
+ }
+
+ // good URL -> use it
+ mDefaultDataUrls[nDefaultLayers++] = aDefaults[ix];
+ }
+ mDefaultDataUrls.realloc(nDefaultLayers);
+
+ // Setting: admin mode tag
+ sal_Bool bAdminMode = false;
+ context->getValueByName(kAdminModeFlag) >>= bAdminMode;
+
+ if (bAdminMode)
+ {
+ // find given entity
+ if ( (context->getValueByName(kEntity) >>= mUserDataUrl) && mUserDataUrl.getLength() )
+ {
+ //Validate UserDataUrl
+ validateFileURL(mUserDataUrl,*this);
+ //NormalizeURL
+ implEnsureAbsoluteURL(mUserDataUrl);
+ normalizeURL(mUserDataUrl,*this);
+ if(FileHelper::fileExists(mUserDataUrl))
+ {
+ checkIfDirectory(mUserDataUrl,*this);
+ }
+
+ for (sal_Int32 ix = 0; ix < mDefaultDataUrls.getLength(); ++ix)
+ {
+ if (mDefaultDataUrls.getConstArray()[ix].equals(mUserDataUrl))
+ {
+ mDefaultDataUrls.realloc(ix);
+ // this is the last round through the loop
+ }
+ }
+ }
+ else if (aDefaults.getLength()) // administrate first default layer
+ {
+ mUserDataUrl = aDefaults[0];
+ mDefaultDataUrls.realloc(0);
+ }
+ else
+ {
+ OSL_ENSURE(false, "Cannot find target entity for admin mode - fallback to local mode");
+ bAdminMode = false;
+ }
+ }
+
+ if (!bAdminMode)
+ {
+ context->getValueByName(kUserDataUrl) >>= mUserDataUrl ;
+ //Validate UserDataUrl
+ if (isValidFileURL(mUserDataUrl))
+ {
+ implEnsureAbsoluteURL(mUserDataUrl);
+ normalizeURL(mUserDataUrl,*this);
+ if(FileHelper::fileExists(mUserDataUrl))
+ {
+ checkIfDirectory(mUserDataUrl,*this);
+ }
+ }
+ }
+
+ if (mUserDataUrl.getLength() == 0)
+ {
+ mUserDataUrl = rtl::OUString::createFromAscii("*");
+ OSL_ASSERT(!isValidFileURL(mUserDataUrl));
+ }
+}
+//------------------------------------------------------------------------------
+const sal_Int32 k_UserLayerEntity = 0;
+const sal_Int32 k_InvalidEntity = k_UserLayerEntity - 1;
+const sal_Int32 k_DefaultEntityOffset = k_UserLayerEntity + 1;
+//------------------------------------------------------------------------------
+static inline bool isValidEntity(sal_Int32 ent)
+{
+ return ent > k_InvalidEntity;
+}
+//------------------------------------------------------------------------------
+static inline sal_Int32 indexToEntity(sal_Int32 ix)
+{
+ OSL_ASSERT(0 <= ix);
+ return ix + k_DefaultEntityOffset;
+}
+static inline sal_Int32 entityToIndex(sal_Int32 ent)
+{
+ OSL_ASSERT(k_DefaultEntityOffset <= ent);
+ return ent - k_DefaultEntityOffset;
+}
+//------------------------------------------------------------------------------
+
+
+/**
+ Transforms a file url into a layer id. The layer id will
+ contain the URL passed plus an integer indicating which
+ layer the URL points to. If the integer is 0, the URL
+ is a user layer, otherwise it is one of the default layers.
+
+ @param aFileUrl URL to encode
+ @param aIndex index of the layer concerned (0 = user, other = default)
+ @return layer id
+ */
+static
+rtl::OUString urlToLayerId(const rtl::OUString& aFileUrl,sal_Int32 aIndex)
+{
+ rtl::OUStringBuffer id ;
+
+ OSL_ASSERT(isValidEntity(aIndex));
+ if (aIndex)
+ id.append(aIndex).appendAscii(" ",1); // non-user layers
+ else
+ id.appendAscii("U ",2); // user layer
+
+ id.append(aFileUrl) ;
+ return id.makeStringAndClear() ;
+}
+
+static
+inline
+bool layerIdToUrl( const rtl::OUString& aLayerId,
+ rtl::OUString& aFileUrl,
+ sal_Int32& aIndex)
+{
+ sal_Int32 const sep = aLayerId.indexOf(sal_Unicode(' ')) ;
+
+ if (sep < 0) return false;
+
+ // detect user layer id
+ if (aLayerId[0] == sal_Unicode('U'))
+ {
+ if (sep != 1) return false;
+ aIndex = 0;
+ }
+ else
+ {
+ aIndex = aLayerId.copy(0, sep).toInt32() ;
+ if (0 == aIndex || !isValidEntity(aIndex)) return false;
+
+ OSL_ENSURE( aLayerId.copy(0, sep).equals(rtl::OUString::valueOf(aIndex)),
+ "Invalid layer id was not detected");
+ }
+ aFileUrl = aLayerId.copy(sep + 1);
+
+ return true;
+}
+//------------------------------------------------------------------------------
+sal_Int32 LocalSingleBackend::resolveLayerId(const rtl::OUString& aLayerId,
+ rtl::OUString& aFileUrl)
+{
+ sal_Int32 nIndex = k_InvalidEntity;
+ if (!layerIdToUrl(aLayerId,aFileUrl,nIndex))
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Invalid layer id: "));
+
+ // layer id is always the second parameter
+ throw lang::IllegalArgumentException(sMsg.concat(aLayerId), *this, 2);
+ }
+ OSL_ASSERT(isValidEntity(nIndex));
+ return nIndex;
+}
+//------------------------------------------------------------------------------
+
+sal_Int32 LocalSingleBackend::findEntity(const rtl::OUString& aEntity)
+{
+ if (aEntity.getLength() == 0)
+ {
+ return k_InvalidEntity;
+ }
+
+ // quick check for OwnerEntity first
+ if (aEntity.equals(mUserDataUrl))
+ {
+ return k_UserLayerEntity;
+ }
+
+ rtl::OUString sNormalizedEntityUrl(aEntity);
+ normalizeURL(sNormalizedEntityUrl,*this);
+
+ for (sal_Int32 ix = 0; ix < mDefaultDataUrls.getLength(); ++ix)
+ {
+ rtl::OUString sNormalizedDefaultUrl(mDefaultDataUrls[ix]);
+ OSL_VERIFY(normalizeURL(sNormalizedDefaultUrl,*this,true));
+
+ if (sNormalizedEntityUrl.equals(sNormalizedDefaultUrl))
+ {
+ // found it
+ return indexToEntity(ix);
+ }
+ }
+
+ //Try normalized version of mUserDataUrl
+ rtl::OUString sNormalizedUserUrl(mUserDataUrl);
+
+ if (normalizeURL(sNormalizedUserUrl,*this,true))
+ {
+ if (sNormalizedEntityUrl.equals(sNormalizedUserUrl))
+ {
+ return k_UserLayerEntity;
+ }
+ }
+
+ // not found
+ return k_InvalidEntity;
+}
+//------------------------------------------------------------------------------
+
+static const rtl::OUString kDataSuffix(RTL_CONSTASCII_USTRINGPARAM(".xcu")) ;
+
+uno::Sequence<rtl::OUString> SAL_CALL LocalSingleBackend::listLayerIds(
+ const rtl::OUString& aComponent, const rtl::OUString& aEntity)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ sal_Int32 nEntity = findEntity(aEntity);
+ if ( !isValidEntity(nEntity) )
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Unknown entity: "));
+
+ throw lang::IllegalArgumentException(sMsg.concat(aEntity), *this, 2);
+ }
+
+ sal_Int32 nDefLayers = (k_UserLayerEntity == nEntity)
+ ? mDefaultDataUrls.getLength()
+ : entityToIndex(nEntity);
+
+ OSL_ASSERT(0 <= nDefLayers && nDefLayers <= mDefaultDataUrls.getLength());
+
+ rtl::OUString const componentSubPath = componentToPath(aComponent) + kDataSuffix ;
+
+ uno::Sequence<rtl::OUString> aLayerIds(nDefLayers + 1) ;
+ OSL_ASSERT(0 < aLayerIds.getLength());
+
+ // First, the defaults...
+ for (sal_Int32 ix = 0; ix < nDefLayers ; ++ ix)
+ {
+ aLayerIds[ix] = urlToLayerId(componentSubPath, indexToEntity(ix)) ;
+ }
+ // Then the entity data.
+ aLayerIds [nDefLayers] = urlToLayerId(componentSubPath, nEntity) ;
+
+ return aLayerIds;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL LocalSingleBackend::getUpdateLayerId(
+ const rtl::OUString& aComponent, const rtl::OUString& aEntity)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ sal_Int32 nEntity = findEntity(aEntity);
+ if ( !isValidEntity(nEntity) )
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Unknown entity for update: "));
+
+ throw lang::IllegalArgumentException(sMsg.concat(aEntity), *this, 2);
+ }
+
+ return urlToLayerId(componentToPath(aComponent) + kDataSuffix, nEntity) ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL LocalSingleBackend::getOwnerEntity()
+ throw (uno::RuntimeException)
+{
+ return mUserDataUrl ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL LocalSingleBackend::getAdminEntity()
+ throw (uno::RuntimeException)
+{
+ return mDefaultDataUrls.getLength() > 0 ? mDefaultDataUrls[0] : mUserDataUrl;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL LocalSingleBackend::supportsEntity( const rtl::OUString& aEntity )
+ throw (backend::BackendAccessException, uno::RuntimeException)
+{
+ return isValidEntity(findEntity(aEntity)) ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL LocalSingleBackend::isEqualEntity(const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException)
+{
+ if (aEntity.getLength() == 0)
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Invalid empty entity."));
+
+ throw lang::IllegalArgumentException(sMsg, *this, 1);
+ }
+ if (aOtherEntity.getLength() == 0)
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Invalid empty entity."));
+
+ throw lang::IllegalArgumentException(sMsg, *this, 2);
+ }
+ rtl::OUString aNormalizedEntity(aEntity);
+ normalizeURL(aNormalizedEntity,*this);
+
+ rtl::OUString aNormalizedOther(aOtherEntity);
+ normalizeURL(aNormalizedOther,*this);
+
+ return aNormalizedEntity == aNormalizedOther;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool LocalSingleBackend::isMoreRecent(const rtl::OUString& aFileUrl,
+ sal_Int32 aLayerIndex,
+ const rtl::OUString& aTimestamp) {
+ rtl::OUString layerUrl ;
+ rtl::OUString subLayerUrl ;
+
+ // if we don't find a layer, but have a non-empty timestamp -> modified
+ if (!getLayerDirectories(aLayerIndex,layerUrl, subLayerUrl))
+ return aTimestamp.getLength() != 0;
+
+ return layerUrl.getLength() == 0 ||
+ BasicLocalFileLayer::getTimestamp(layerUrl + aFileUrl).compareTo( aTimestamp) != 0;
+}
+//------------------------------------------------------------------------------
+
+static const rtl::OUString kDataSubPath(
+ RTL_CONSTASCII_USTRINGPARAM("/data")) ;
+static const rtl::OUString kLocalisedDataSubPath(
+ RTL_CONSTASCII_USTRINGPARAM("/res")) ;
+
+uno::Reference<backend::XLayer> SAL_CALL LocalSingleBackend::getLayer(
+ const rtl::OUString& aLayerId, const rtl::OUString& aTimestamp)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ rtl::OUString fileUrl ;
+
+ sal_Int32 defaultIndex = resolveLayerId(aLayerId, fileUrl) ;
+
+ if (!isMoreRecent(fileUrl, defaultIndex, aTimestamp)) { return NULL ; }
+
+ uno::Reference<backend::XUpdatableLayer> xLayer = getFileLayer(fileUrl,defaultIndex);
+ uno::Reference<backend::XLayer> xResult = xLayer.get();
+ return xResult;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<uno::Reference<backend::XLayer> > SAL_CALL
+LocalSingleBackend::getLayers(const uno::Sequence<rtl::OUString>& aLayerIds,
+ const rtl::OUString& aTimestamp)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ uno::Sequence<uno::Reference<backend::XLayer> >
+ retCode(aLayerIds.getLength()) ;
+
+ for (sal_Int32 i = 0 ; i < aLayerIds.getLength() ; ++ i) {
+ retCode [i] = getLayer(aLayerIds [i], aTimestamp) ;
+ }
+ return retCode ;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<uno::Reference<backend::XLayer> > SAL_CALL
+LocalSingleBackend::getMultipleLayers(
+ const uno::Sequence<rtl::OUString>& aLayerIds,
+ const uno::Sequence<rtl::OUString>& aTimestamps)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ if (aLayerIds.getLength() != aTimestamps.getLength()) {
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Not enough or too many timestamps")),
+ *this, 0) ;
+ }
+ uno::Sequence<uno::Reference<backend::XLayer> >
+ retCode(aLayerIds.getLength()) ;
+
+ for (sal_Int32 i = 0 ; i < aLayerIds.getLength() ; ++ i) {
+ retCode [i] = getLayer(aLayerIds [i], aTimestamps [i]) ;
+ }
+ return retCode ;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backend::XUpdatableLayer> SAL_CALL
+LocalSingleBackend::getUpdatableLayer(const rtl::OUString& aLayerId)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return getFileLayer(aLayerId) ;
+}
+//------------------------------------------------------------------------------
+
+static const rtl::OUString kSchemaSuffix(RTL_CONSTASCII_USTRINGPARAM(".xcs")) ;
+static const rtl::OUString kXMLSchemaParser(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.backend.xml.SchemaParser")) ;
+
+uno::Reference<backend::XSchema> SAL_CALL
+ LocalSingleBackend::getComponentSchema(const rtl::OUString& aComponent)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ rtl::OUString subPath = componentToPath(aComponent) ;
+
+ osl::File * schemaFile = NULL;
+ rtl::OUString errorMessage;
+ bool bInsufficientAccess = false;
+ for (sal_Int32 ix = 0; ix < mSchemaDataUrls.getLength(); ++ix)
+ {
+ rtl::OUStringBuffer schemaUrl(mSchemaDataUrls[ix]) ;
+
+ schemaUrl.append(subPath).append(kSchemaSuffix) ;
+
+ rtl::OUString const aFileUrl = schemaUrl.makeStringAndClear();
+
+ std::auto_ptr<osl::File> checkFile( new osl::File(aFileUrl) );
+ osl::File::RC rc = checkFile->open(OpenFlag_Read) ;
+
+ if (rc == osl::File::E_None)
+ {
+ schemaFile = checkFile.release();
+ break;
+ }
+ else if (rc != osl::File::E_NOENT)
+ {
+ if (rc == osl::File::E_ACCES)
+ bInsufficientAccess =true;
+
+ // accumulate error messages
+ rtl::OUStringBuffer sMsg(errorMessage);
+ if (errorMessage.getLength())
+ sMsg.appendAscii("LocalFile SchemaSupplier - Error accessing schema: ");
+
+ sMsg.appendAscii("\n- Cannot open input file \"");
+ sMsg.append(aFileUrl);
+ sMsg.appendAscii("\" : ");
+ sMsg.append(FileHelper::createOSLErrorString(rc));
+
+ errorMessage = sMsg.makeStringAndClear();
+ }
+ }
+
+ if (NULL == schemaFile)
+ {
+ if (errorMessage.getLength() != 0)
+ {
+ // a real error occured
+ io::IOException ioe(errorMessage,*this);
+
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("LocalFileLayer - Cannot readData: ").append(errorMessage);
+
+ if (bInsufficientAccess)
+ throw backend::InsufficientAccessRightsException(sMsg.makeStringAndClear(),*this,uno::makeAny(ioe));
+ else
+ throw backend::BackendAccessException(sMsg.makeStringAndClear(),*this,uno::makeAny(ioe));
+ }
+ // simply not found
+ return NULL;
+ }
+
+ uno::Sequence<uno::Any> arguments(1) ;
+ uno::Reference<io::XInputStream> stream( new OSLInputStreamWrapper(schemaFile, true) );
+
+ arguments [0] <<= stream ;
+ uno::Reference<backend::XSchema> schema(
+ mFactory->createInstanceWithArguments(kXMLSchemaParser, arguments),
+ uno::UNO_QUERY) ;
+
+ if (!schema.is())
+ {
+ throw uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "Cannot instantiate Schema Parser for ")) + aComponent,
+ *this) ;
+ }
+ return schema ;
+}
+//------------------------------------------------------------------------------
+
+static
+inline
+bool impl_getLayerSubDirectories(rtl::OUString const & aLayerBaseUrl,
+ rtl::OUString& aMainLayerUrl,
+ rtl::OUString& aSubLayerUrl)
+{
+ if (!isValidFileURL(aLayerBaseUrl)) return false;
+
+ aMainLayerUrl = aLayerBaseUrl + kDataSubPath ;
+ aSubLayerUrl = aLayerBaseUrl + kLocalisedDataSubPath ;
+ return true;
+}
+//------------------------------------------------------------------------------
+
+bool LocalSingleBackend::getLayerSubDirectories(rtl::OUString const & aLayerBaseUrl,
+ rtl::OUString& aMainLayerUrl,
+ rtl::OUString& aSubLayerUrl)
+{
+ return impl_getLayerSubDirectories(aLayerBaseUrl,aMainLayerUrl,aSubLayerUrl);
+}
+//------------------------------------------------------------------------------
+
+bool LocalSingleBackend::getLayerDirectories(sal_Int32 aLayerIndex,
+ rtl::OUString& aLayerUrl,
+ rtl::OUString& aSubLayerUrl)
+{
+ OSL_ASSERT(isValidEntity(aLayerIndex));
+ rtl::OUString aLayerBaseUrl = (aLayerIndex == k_UserLayerEntity) ? mUserDataUrl : mDefaultDataUrls [entityToIndex(aLayerIndex)] ;
+
+ return impl_getLayerSubDirectories(aLayerBaseUrl,aLayerUrl,aSubLayerUrl);
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backend::XLayer> LocalSingleBackend::createSimpleLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ rtl::OUString const & aComponentUrl)
+{
+ SimpleLocalFileLayer * pLayer = new SimpleLocalFileLayer(xFactory, aComponentUrl);
+ return pLayer;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backend::XLayer> LocalSingleBackend::createSimpleLayer(
+ const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ rtl::OUString const & aLayerBaseUrl,
+ rtl::OUString const & aComponent)
+{
+ rtl::OUString aLayerUrl, aSubLayerUrl;
+ if (!impl_getLayerSubDirectories(aLayerBaseUrl,aLayerUrl,aSubLayerUrl))
+ return NULL;
+
+ SimpleLocalFileLayer * pLayer = new SimpleLocalFileLayer(xFactory, aLayerUrl, componentToPath(aComponent) + kDataSuffix);
+ return pLayer;
+}
+//------------------------------------------------------------------------------
+
+
+uno::Reference<backend::XUpdatableLayer> LocalSingleBackend::getFileLayer(const rtl::OUString& aLayerId)
+ throw (lang::IllegalArgumentException)
+{
+ rtl::OUString fileUrl ;
+ sal_Int32 defaultIndex = resolveLayerId(aLayerId, fileUrl) ;
+
+ return getFileLayer(fileUrl, defaultIndex) ;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backend::XUpdatableLayer> LocalSingleBackend::getFileLayer(
+ const rtl::OUString& aComponent, sal_Int32 aLayerIndex) {
+ rtl::OUString layerPath ;
+ rtl::OUString subLayerPath ;
+
+ if (!getLayerDirectories(aLayerIndex, layerPath, subLayerPath))
+ {
+ OSL_ENSURE(aLayerIndex == k_UserLayerEntity, "Unexpected: Invalid non-user layer url");
+
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("LocalSingleBackend: Cannot create file layer - Layer URL '");
+ sMsg.append(mUserDataUrl).appendAscii("' is invalid.");
+
+ throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),*this,1);
+ }
+
+ return createUpdatableLocalFileLayer(mFactory, layerPath, aComponent, subLayerPath) ;
+}
+//------------------------------------------------------------------------------
+
+static const sal_Char * const kImplementation =
+ "com.sun.star.comp.configuration.backend.LocalSingleBackend" ;
+static const sal_Char * const kBackendService =
+ "com.sun.star.configuration.backend.SingleBackend" ;
+static const sal_Char * const kLocalService =
+ "com.sun.star.configuration.backend.LocalSingleBackend" ;
+
+static sal_Char const * kServiceNames [] = { kLocalService, 0, kBackendService, 0 } ;
+static const ServiceImplementationInfo kServiceInfo = { kImplementation, kServiceNames, kServiceNames + 2 } ;
+
+const ServiceRegistrationInfo *getLocalBackendServiceInfo()
+{ return getRegistrationInfo(&kServiceInfo) ; }
+
+uno::Reference<uno::XInterface> SAL_CALL
+instantiateLocalBackend(const uno::Reference< uno::XComponentContext >& xContext) {
+ return *new LocalSingleBackend(xContext) ;
+}
+
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL LocalSingleBackend::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).getImplementationName() ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL LocalSingleBackend::supportsService(
+ const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).supportsService(aServiceName);
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString>
+SAL_CALL LocalSingleBackend::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ;
+}
+
+// ---------------------------------------------------------------------------------------
+
+} } // configmgr.localbe
diff --git a/configmgr/source/localbe/localsinglebackend.hxx b/configmgr/source/localbe/localsinglebackend.hxx
new file mode 100644
index 000000000000..3a2968f0fcc2
--- /dev/null
+++ b/configmgr/source/localbe/localsinglebackend.hxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localsinglebackend.hxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_LOCALSINGLEBACKEND_HXX_
+#define CONFIGMGR_LOCALBE_LOCALSINGLEBACKEND_HXX_
+
+#include <com/sun/star/configuration/backend/XSchemaSupplier.hpp>
+#include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
+#include <com/sun/star/configuration/backend/XBackendEntities.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/backend/CannotConnectException.hpp>
+#include <cppuhelper/compbase5.hxx>
+
+namespace configmgr { namespace localbe {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backend = css::configuration::backend ;
+
+/**
+ Implements the SingleBackend service for local file access.
+ Layer identifiers in that backend are file URLs.
+ */
+class LocalSingleBackend : public cppu::WeakComponentImplHelper5<backend::XSchemaSupplier, backend::XMultiLayerStratum, backend::XBackendEntities, lang::XInitialization, lang::XServiceInfo> {
+ public :
+ /**
+ Service constructor from a service factory.
+
+ @param xFactory service factory
+ */
+ LocalSingleBackend(const uno::Reference<uno::XComponentContext>& xContext) ;
+
+ /** Destructor */
+ ~LocalSingleBackend(void) ;
+
+
+ // XInitialize
+ virtual void SAL_CALL
+ initialize( const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ css::configuration::InvalidBootstrapFileException,
+ backend::CannotConnectException,
+ backend::BackendSetupException);
+
+ // XSchemaSupplier
+ virtual uno::Reference<backend::XSchema> SAL_CALL
+ getComponentSchema( const rtl::OUString& aComponent )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ // XMultiLayerStratum
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ listLayerIds( const rtl::OUString& aComponent, const rtl::OUString& aEntity )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual rtl::OUString SAL_CALL
+ getUpdateLayerId( const rtl::OUString& aComponent, const rtl::OUString& aEntity )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Reference<backend::XLayer> SAL_CALL
+ getLayer( const rtl::OUString& aLayerId, const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Sequence<uno::Reference<backend::XLayer> > SAL_CALL
+ getLayers(const uno::Sequence<rtl::OUString>& aLayerIds,
+ const rtl::OUString& aTimestamp)
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Sequence<uno::Reference<backend::XLayer> > SAL_CALL
+ getMultipleLayers(const uno::Sequence<rtl::OUString>& aLayerIds,
+ const uno::Sequence<rtl::OUString>& aTimestamps)
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Reference<backend::XUpdatableLayer> SAL_CALL
+ getUpdatableLayer( const rtl::OUString& aLayerId )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ // XBackendEntities
+ virtual rtl::OUString SAL_CALL
+ getOwnerEntity( )
+ throw (uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ getAdminEntity( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsEntity( const rtl::OUString& aEntity )
+ throw (backend::BackendAccessException, uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isEqualEntity( const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException) ;
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& aServiceName )
+ throw (uno::RuntimeException) ;
+
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException) ;
+
+ public: // helpers for other implementation that need to use the same data
+ /**
+ Locates the main layer data and localized data directories in a layer directory hierarchy
+ */
+ static bool getLayerSubDirectories( rtl::OUString const & aLayerBaseUrl,
+ rtl::OUString& aMainLayerUrl,
+ rtl::OUString& aSubLayerUrl);
+ /**
+ Creates a simple readonly non-composite layer for a component in a base directory
+ */
+ static uno::Reference<backend::XLayer>
+ createSimpleLayer(const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ rtl::OUString const & aLayerBaseUrl,
+ rtl::OUString const & aComponent);
+
+ /**
+ Creates a simple readonly non-composite layer for a component in a given file
+ */
+ static uno::Reference<backend::XLayer>
+ createSimpleLayer(const uno::Reference<lang::XMultiServiceFactory>& xFactory,
+ rtl::OUString const & aComponentUrl);
+ private :
+ /** Service factory */
+ uno::Reference<lang::XMultiServiceFactory> mFactory ;
+ /** Mutex for resources protection */
+ osl::Mutex mMutex ;
+ /**
+ Base of the schema data. Is a list to allow
+ for multiple schema directories.
+ */
+ uno::Sequence<rtl::OUString> mSchemaDataUrls ;
+ /**
+ Base of the default data. Is a list to allow
+ for multiple layers of default data.
+ */
+ uno::Sequence<rtl::OUString> mDefaultDataUrls ;
+ /** Base of the user data */
+ rtl::OUString mUserDataUrl ;
+
+ /** special index for entity */
+ sal_Int32 findEntity(rtl::OUString const & _aEntity);
+ /** parse and translate layer-id */
+ sal_Int32 resolveLayerId(rtl::OUString const & _aLayerId, rtl::OUString & _aFile);
+
+ /**
+ Builds a LocalFileLayer object given a layer id.
+ Since the LocalFileLayer implements the various
+ interfaces a layer can be accessed as, a few methods
+ need one. This method handles the layer id mapping
+ and the existence or not of sublayers.
+
+ @param aLayerId layer id
+ @return local file layer
+ @throws com::sun::star::lang::IllegalArgumentException
+ if the layer id is invalid.
+ */
+ uno::Reference<backend::XUpdatableLayer> getFileLayer(const rtl::OUString& aLayerId)
+ throw (lang::IllegalArgumentException) ;
+ /**
+ Same as above, but using a component URL and layer index
+ combination instead of a layer id (which encodes both).
+
+ @param aComponent component URL
+ @param aLayerIndex layer index
+ @return local file layer
+ */
+ uno::Reference<backend::XUpdatableLayer> getFileLayer(const rtl::OUString& aComponent,
+ sal_Int32 aLayerIndex) ;
+ /**
+ Maps a layer index (-1 for user layer, 0-x for defaults)
+ to the appropriate layer and sublayers base directories.
+
+ @param aLayerIndex layer index
+ @param aLayerUrl layer base URL, filled on return
+ @param aSubLayerUrl sublayer base URL, filled on return
+ */
+ bool getLayerDirectories(sal_Int32 aLayerIndex,
+ rtl::OUString& aLayerUrl,
+ rtl::OUString& aSubLayerUrl) ;
+ /**
+ Tells if a file is more recent than a given date.
+ The date is formatted YYYYMMDDhhmmssZ.
+
+ @param aComponent URL of the component to check
+ @param aLayerIndex index of the layer involved (-1 = user)
+ @param aTimestamp timestamp to check against
+ @return sal_True if the file is more recent, sal_False otherwise
+ */
+ sal_Bool isMoreRecent(const rtl::OUString& aComponent,
+ sal_Int32 aLayerId,
+ const rtl::OUString& aTimestamp) ;
+ } ;
+
+} } // configmgr.localbe
+
+#endif // CONFIGMGR_LOCALBE_LOCALSINGLEBACKEND_HXX_
diff --git a/configmgr/source/localbe/localsinglestratum.cxx b/configmgr/source/localbe/localsinglestratum.cxx
new file mode 100644
index 000000000000..3cab41f6344b
--- /dev/null
+++ b/configmgr/source/localbe/localsinglestratum.cxx
@@ -0,0 +1,233 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localsinglestratum.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "localsinglestratum.hxx"
+#include "localfilehelper.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif // CONFIGMGR_API_FACTORY_HXX_
+#include "serviceinfohelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
+
+namespace configmgr { namespace localbe {
+
+//==============================================================================
+
+static inline rtl::OUString getDataSubPath()
+{ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/data")); }
+
+static inline rtl::OUString getLocalisedDataSubPath()
+{ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/res")); }
+//------------------------------------------------------------------------------
+
+LocalSingleStratumBase::LocalSingleStratumBase(const uno::Reference<uno::XComponentContext>& xContext)
+: cppu::ImplInheritanceHelper1< LocalStratumBase, backend::XSingleLayerStratum >(xContext)
+{
+}
+//------------------------------------------------------------------------------
+
+LocalSingleStratumBase::~LocalSingleStratumBase() {}
+
+//------------------------------------------------------------------------------
+uno::Reference<backend::XLayer> SAL_CALL
+ LocalSingleStratumBase::getLayer( const rtl::OUString& aComponent, const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return LocalStratumBase::getLayer(aComponent,aTimestamp);
+}
+//------------------------------------------------------------------------------
+uno::Reference<backend::XUpdatableLayer> SAL_CALL
+ LocalSingleStratumBase::getUpdatableLayer(const rtl::OUString& aComponent)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ lang::NoSupportException, uno::RuntimeException)
+{
+ if (aComponent.getLength() == 0){
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleStratum:getLayer - no component specified")),
+ *this, 0) ;
+ }
+ rtl::OUString const componentSubPath = componentToPath(aComponent) + getDataSuffix();
+ return createUpdatableFileLayer( componentSubPath) ;
+}
+//------------------------------------------------------------------------------
+uno::Reference<backend::XUpdatableLayer> SAL_CALL
+ LocalReadonlyStratum::getUpdatableLayer(const rtl::OUString& /*aComponent*/)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ lang::NoSupportException, uno::RuntimeException)
+{
+ failReadonly();
+ return 0;
+}
+uno::Reference<backend::XUpdatableLayer> SAL_CALL
+ LocalResourceStratum::getUpdatableLayer(const rtl::OUString& /*aComponent*/)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ lang::NoSupportException, uno::RuntimeException)
+{
+ failReadonly();
+ return 0;
+}
+//------------------------------------------------------------------------------
+static
+inline
+void impl_getLayerDataDirectory(rtl::OUString const & aLayerBaseUrl,
+ rtl::OUString& aMainLayerUrl)
+{
+ aMainLayerUrl = aLayerBaseUrl + getDataSubPath() ;
+}
+//------------------------------------------------------------------------------
+static
+inline
+void impl_getLayerResDirectory(rtl::OUString const & aLayerBaseUrl,
+ rtl::OUString& aSubLayerUrl)
+{
+ aSubLayerUrl = aLayerBaseUrl + getLocalisedDataSubPath() ;
+}
+//------------------------------------------------------------------------------
+
+void LocalSingleStratum::getLayerDirectories(rtl::OUString& aLayerUrl,
+ rtl::OUString& aSubLayerUrl) const
+{
+ impl_getLayerDataDirectory(getBaseUrl(),aLayerUrl);
+ impl_getLayerResDirectory(getBaseUrl(),aSubLayerUrl);
+}
+//------------------------------------------------------------------------------
+
+void LocalDataStratum::getLayerDirectories(rtl::OUString& aLayerUrl,
+ rtl::OUString& aSubLayerUrl) const
+{
+ impl_getLayerDataDirectory(getBaseUrl(),aLayerUrl);
+ aSubLayerUrl = rtl::OUString();
+}
+//------------------------------------------------------------------------------
+
+void LocalReadonlyStratum::getLayerDirectories(rtl::OUString& aLayerUrl,
+ rtl::OUString& aSubLayerUrl) const
+{
+ impl_getLayerDataDirectory(getBaseUrl(),aLayerUrl);
+ aSubLayerUrl = rtl::OUString();
+}
+//------------------------------------------------------------------------------
+
+void LocalResourceStratum::adjustBaseURL(rtl::OUString& aBaseUrl)
+{
+ impl_getLayerResDirectory(aBaseUrl,aBaseUrl);
+}
+//------------------------------------------------------------------------------
+
+void LocalResourceStratum::getLayerDirectories(rtl::OUString& aLayerUrl,
+ rtl::OUString& aSubLayerUrl) const
+{
+ aLayerUrl = rtl::OUString();
+ aSubLayerUrl = getBaseUrl();
+ // impl_getLayerResDirectory(getBaseUrl(),aSubLayerUrl);
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+static const sal_Char * const kLegacyStratumImplementation =
+ "com.sun.star.comp.configuration.backend.LocalSingleStratum" ;
+static const sal_Char * const kDataStratumImplementation =
+ "com.sun.star.comp.configuration.backend.LocalStratum" ;
+static const sal_Char * const kReadonlyStratumImplementation =
+ "com.sun.star.comp.configuration.backend.LocalReadonlyStratum" ;
+static const sal_Char * const kResourceStratumImplementation =
+ "com.sun.star.comp.configuration.backend.LocalResourceStratum" ;
+static const sal_Char * const kBackendService =
+ "com.sun.star.configuration.backend.SingleStratum" ;
+static const sal_Char * const kLocalService =
+ "com.sun.star.configuration.backend.LocalSingleStratum" ;
+
+static sal_Char const * kServiceNames [] = { kLocalService, 0, kBackendService, 0 } ;
+static const ServiceImplementationInfo kLegacyStratumServiceInfo = { kLegacyStratumImplementation , kServiceNames, kServiceNames + 2 } ;
+static const ServiceImplementationInfo kDataStratumServiceInfo = { kDataStratumImplementation , kServiceNames, kServiceNames + 2 } ;
+static const ServiceImplementationInfo kReadonlyStratumServiceInfo = { kReadonlyStratumImplementation, kServiceNames, kServiceNames + 2 } ;
+static const ServiceImplementationInfo kResourceStratumServiceInfo = { kResourceStratumImplementation, kServiceNames, kServiceNames + 2 } ;
+
+const ServiceRegistrationInfo *getLocalLegacyStratumServiceInfo()
+{ return getRegistrationInfo(&kLegacyStratumServiceInfo) ; }
+
+const ServiceRegistrationInfo *getLocalDataStratumServiceInfo()
+{ return getRegistrationInfo(&kDataStratumServiceInfo) ; }
+
+const ServiceRegistrationInfo *getLocalReadonlyStratumServiceInfo()
+{ return getRegistrationInfo(&kReadonlyStratumServiceInfo) ; }
+
+const ServiceRegistrationInfo *getLocalResourceStratumServiceInfo()
+{ return getRegistrationInfo(&kResourceStratumServiceInfo) ; }
+
+uno::Reference<uno::XInterface> SAL_CALL
+instantiateLocalLegacyStratum(const uno::Reference< uno::XComponentContext >& xContext) {
+ return *new LocalSingleStratum(xContext) ;
+}
+
+uno::Reference<uno::XInterface> SAL_CALL
+instantiateLocalDataStratum(const uno::Reference< uno::XComponentContext >& xContext) {
+ return *new LocalDataStratum(xContext) ;
+}
+
+uno::Reference<uno::XInterface> SAL_CALL
+instantiateLocalReadonlyStratum(const uno::Reference< uno::XComponentContext >& xContext) {
+ return *new LocalReadonlyStratum(xContext) ;
+}
+
+uno::Reference<uno::XInterface> SAL_CALL
+instantiateLocalResourceStratum(const uno::Reference< uno::XComponentContext >& xContext) {
+ return *new LocalResourceStratum(xContext) ;
+}
+//------------------------------------------------------------------------------
+
+const ServiceImplementationInfo * LocalSingleStratum::getServiceInfoData() const
+{
+ return &kLegacyStratumServiceInfo;
+}
+const ServiceImplementationInfo * LocalDataStratum::getServiceInfoData() const
+{
+ return &kDataStratumServiceInfo;
+}
+const ServiceImplementationInfo * LocalReadonlyStratum::getServiceInfoData() const
+{
+ return &kReadonlyStratumServiceInfo;
+}
+const ServiceImplementationInfo * LocalResourceStratum::getServiceInfoData() const
+{
+ return &kResourceStratumServiceInfo;
+}
+//------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------
+
+} } // configmgr.localsinglestratum
diff --git a/configmgr/source/localbe/localsinglestratum.hxx b/configmgr/source/localbe/localsinglestratum.hxx
new file mode 100644
index 000000000000..5b2b81465c51
--- /dev/null
+++ b/configmgr/source/localbe/localsinglestratum.hxx
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localsinglestratum.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_LOCALSINGLESTRATUM_HXX_
+#define CONFIGMGR_LOCALBE_LOCALSINGLESTRATUM_HXX_
+
+#include "localstratumbase.hxx"
+#include <com/sun/star/configuration/backend/XSingleLayerStratum.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+namespace configmgr
+{
+ namespace localbe
+ {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backend = css::configuration::backend ;
+
+/**
+ Implements the SingleLayerStratum service for local file access.
+ */
+class LocalSingleStratumBase : public cppu::ImplInheritanceHelper1< LocalStratumBase, backend::XSingleLayerStratum >
+{
+public :
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ LocalSingleStratumBase(const uno::Reference<uno::XComponentContext>& xContext) ;
+
+ /** Destructor */
+ ~LocalSingleStratumBase() ;
+
+
+ // XSingleLayerStratum
+ virtual uno::Reference<backend::XLayer> SAL_CALL
+ getLayer( const rtl::OUString& aLayerId, const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Reference<backend::XUpdatableLayer> SAL_CALL
+ getUpdatableLayer( const rtl::OUString& aLayerId )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+
+} ;
+
+class LocalSingleStratum : public LocalSingleStratumBase
+{
+public:
+ LocalSingleStratum(const uno::Reference<uno::XComponentContext>& xContext)
+ : LocalSingleStratumBase(xContext)
+ {};
+
+private:
+ virtual void getLayerDirectories(rtl::OUString& aLayerUrl, rtl::OUString& aSubLayerUrl) const;
+ virtual const ServiceImplementationInfo * getServiceInfoData() const;
+};
+
+class LocalDataStratum : public LocalSingleStratumBase
+{
+public:
+ LocalDataStratum(const uno::Reference<uno::XComponentContext>& xContext)
+ : LocalSingleStratumBase(xContext)
+ {};
+
+private:
+ virtual void getLayerDirectories(rtl::OUString& aLayerUrl, rtl::OUString& aSubLayerUrl) const;
+ virtual const ServiceImplementationInfo * getServiceInfoData() const;
+};
+
+class LocalReadonlyStratum : public LocalSingleStratumBase
+{
+public:
+ LocalReadonlyStratum(const uno::Reference<uno::XComponentContext>& xContext)
+ : LocalSingleStratumBase(xContext)
+ {};
+
+ // XSingleLayerStratum - readonly implementation
+ virtual uno::Reference<backend::XUpdatableLayer> SAL_CALL
+ getUpdatableLayer( const rtl::OUString& aLayerId )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+
+private:
+ virtual void getLayerDirectories(rtl::OUString& aLayerUrl, rtl::OUString& aSubLayerUrl) const;
+ virtual const ServiceImplementationInfo * getServiceInfoData() const;
+};
+
+class LocalResourceStratum : public LocalSingleStratumBase
+{
+public:
+ LocalResourceStratum(const uno::Reference<uno::XComponentContext>& xContext)
+ : LocalSingleStratumBase(xContext)
+ {};
+
+ // XSingleLayerStratum - readonly implementation
+ virtual uno::Reference<backend::XUpdatableLayer> SAL_CALL
+ getUpdatableLayer( const rtl::OUString& aLayerId )
+ throw (backend::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+
+private:
+ virtual void adjustBaseURL(rtl::OUString& aBaseURL);
+ virtual void getLayerDirectories(rtl::OUString& aLayerUrl, rtl::OUString& aSubLayerUrl) const;
+ virtual const ServiceImplementationInfo * getServiceInfoData() const;
+};
+
+
+
+} } // configmgr.localbe
+
+#endif
diff --git a/configmgr/source/localbe/localstratumbase.cxx b/configmgr/source/localbe/localstratumbase.cxx
new file mode 100644
index 000000000000..bbfb0384e134
--- /dev/null
+++ b/configmgr/source/localbe/localstratumbase.cxx
@@ -0,0 +1,256 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localstratumbase.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "localstratumbase.hxx"
+#include "localfilehelper.hxx"
+#include "localfilelayer.hxx"
+#include "oslstream.hxx"
+#include "serviceinfohelper.hxx"
+#include "bootstrap.hxx"
+#include "filehelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/configuration/backend/InsufficientAccessRightsException.hpp>
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <memory>
+
+namespace configmgr { namespace localbe {
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+
+LocalStratumBase::LocalStratumBase(const uno::Reference<uno::XComponentContext>& xContext)
+: cppu::WeakComponentImplHelper3<lang::XInitialization, backend::XBackendEntities, lang::XServiceInfo>(mMutex)
+, mFactory(xContext->getServiceManager(),uno::UNO_QUERY)
+{
+}
+//------------------------------------------------------------------------------
+
+LocalStratumBase::~LocalStratumBase()
+{}
+
+//------------------------------------------------------------------------------
+void SAL_CALL LocalStratumBase::initialize(const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ css::configuration::InvalidBootstrapFileException,
+ backend::CannotConnectException,
+ backend::BackendSetupException)
+{
+
+
+
+ if (aParameters.getLength() == 0)
+ {
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "No parameters provided to local Stratum")),
+ *this, 0) ;
+ }
+
+
+ for (sal_Int32 i = 0 ; i < aParameters.getLength() ; ++ i)
+ {
+ if (aParameters [i] >>= mStrataDataUrl )
+ { break ; }
+
+ }
+
+ // get modified base for special layer implementations (e.g. resources)
+ this->adjustBaseURL(mStrataDataUrl);
+
+ validateFileURL(mStrataDataUrl, *this);
+ implEnsureAbsoluteURL(mStrataDataUrl);
+ normalizeURL(mStrataDataUrl,*this, true);
+
+ if(FileHelper::fileExists(mStrataDataUrl))
+ {
+ checkIfDirectory(mStrataDataUrl, *this);
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void LocalStratumBase::adjustBaseURL(rtl::OUString& )
+{
+}
+//------------------------------------------------------------------------------
+
+sal_Bool LocalStratumBase::isMoreRecent(const rtl::OUString& aFileUrl,
+ const rtl::OUString& aTimestamp) {
+ rtl::OUString layerUrl ;
+ rtl::OUString subLayerUrl ;
+
+ getLayerDirectories(layerUrl, subLayerUrl) ;
+
+ return layerUrl.getLength() == 0 ||
+ !BasicLocalFileLayer::getTimestamp(layerUrl + aFileUrl).equals( aTimestamp);
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backend::XLayer> SAL_CALL
+ LocalStratumBase::getLayer( const rtl::OUString& aLayerId, const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+
+ if (aLayerId.getLength() == 0){
+ throw lang::IllegalArgumentException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalStratum:getLayer - no LayerId specified")),
+ *this, 0) ;
+ }
+ rtl::OUString const componentSubPath = layeridToPath(aLayerId) + getDataSuffix();
+ if (!isMoreRecent(componentSubPath, aTimestamp)) { return NULL ; }
+
+ return createReadonlyFileLayer(componentSubPath);
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL LocalStratumBase::getOwnerEntity()
+ throw (uno::RuntimeException)
+{
+ return mStrataDataUrl ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL LocalStratumBase::getAdminEntity()
+ throw (uno::RuntimeException)
+{
+ return rtl::OUString();
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL LocalStratumBase::supportsEntity( const rtl::OUString& aEntity )
+ throw (backend::BackendAccessException, uno::RuntimeException)
+{
+ if(mStrataDataUrl.getLength() == 0)
+ {
+ return false;
+ }
+ if (aEntity.getLength() == 0)
+ {
+ return false;
+ }
+ return isEqualEntity(mStrataDataUrl,aEntity);
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL LocalStratumBase::isEqualEntity(const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity)
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException)
+{
+ if (aEntity.getLength() == 0)
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Invalid empty entity."));
+
+ throw lang::IllegalArgumentException(sMsg, *this, 1);
+ }
+ if (aOtherEntity.getLength() == 0)
+ {
+ rtl::OUString const sMsg(RTL_CONSTASCII_USTRINGPARAM(
+ "LocalSingleBackend - Invalid empty entity."));
+
+ throw lang::IllegalArgumentException(sMsg, *this, 2);
+ }
+ rtl::OUString aNormalizedEntity(aEntity);
+ normalizeURL(aNormalizedEntity,*this);
+
+ rtl::OUString aNormalizedOther(aOtherEntity);
+ normalizeURL(aNormalizedOther,*this);
+
+ return aNormalizedEntity == aNormalizedOther;
+}
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+uno::Reference<backend::XLayer>
+ LocalStratumBase::createReadonlyFileLayer(const rtl::OUString& aSubpath)
+ throw (lang::IllegalArgumentException)
+{
+ rtl::OUString layerPath ;
+ rtl::OUString subLayerPath ;
+
+ getLayerDirectories(layerPath, subLayerPath) ;
+ return createReadonlyLocalFileLayer(mFactory, layerPath, aSubpath, subLayerPath) ;
+}
+//------------------------------------------------------------------------------
+uno::Reference<backend::XUpdatableLayer>
+ LocalStratumBase::createUpdatableFileLayer(const rtl::OUString& aSubpath)
+ throw (lang::IllegalArgumentException)
+{
+ rtl::OUString layerPath ;
+ rtl::OUString subLayerPath ;
+
+ getLayerDirectories(layerPath, subLayerPath) ;
+ return createUpdatableLocalFileLayer(mFactory, layerPath, aSubpath, subLayerPath) ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL LocalStratumBase::getImplementationName()
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(getServiceInfoData()).getImplementationName() ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL LocalStratumBase::supportsService(const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(getServiceInfoData()).supportsService(aServiceName);
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString> SAL_CALL LocalStratumBase::getSupportedServiceNames()
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(getServiceInfoData()).getSupportedServiceNames() ;
+}
+
+// ---------------------------------------------------------------------------------------
+
+void LocalStratumBase::failReadonly()
+{
+ rtl::OUStringBuffer aMessage;
+ aMessage.appendAscii("Configurations - ")
+ .appendAscii("Cannot get update access to layer: ")
+ .appendAscii("Local file-based stratum at ")
+ .append(this->getBaseUrl())
+ .appendAscii(" is readonly.");
+ throw lang::NoSupportException(aMessage.makeStringAndClear(),*this);
+}
+//------------------------------------------------------------------------------
+
+} } // configmgr.localsinglestratum
diff --git a/configmgr/source/localbe/localstratumbase.hxx b/configmgr/source/localbe/localstratumbase.hxx
new file mode 100644
index 000000000000..292f04be4937
--- /dev/null
+++ b/configmgr/source/localbe/localstratumbase.hxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localstratumbase.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_LOCALBE_LOCALSTRATUMBASE_HXX_
+#define CONFIGMGR_LOCALBE_LOCALSTRATUMBASE_HXX_
+
+#include <com/sun/star/configuration/backend/XBackendEntities.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/configuration/backend/XUpdatableLayer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/backend/CannotConnectException.hpp>
+#include <cppuhelper/compbase3.hxx>
+
+namespace configmgr
+{
+ struct ServiceImplementationInfo;
+
+ namespace localbe
+ {
+//------------------------------------------------------------------------------
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backend = css::configuration::backend ;
+//------------------------------------------------------------------------------
+
+struct LocalStratumMutexHolder { osl::Mutex mMutex; };
+//------------------------------------------------------------------------------
+static const char kLocalDataSuffix[] = ".xcu";
+//------------------------------------------------------------------------------
+
+/**
+ Helper for implementing the [Single|Multi]LayerStratum service for local file access.
+ */
+class LocalStratumBase : protected LocalStratumMutexHolder, public cppu::WeakComponentImplHelper3<lang::XInitialization, backend::XBackendEntities, lang::XServiceInfo>
+{
+protected :
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ LocalStratumBase(const uno::Reference<uno::XComponentContext>& xContext) ;
+
+ /** Destructor */
+ ~LocalStratumBase() ;
+
+
+public:
+ // XInitialize
+ virtual void SAL_CALL
+ initialize( const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ css::configuration::InvalidBootstrapFileException,
+ backend::CannotConnectException,
+ backend::BackendSetupException);
+
+
+ // XBackendEntities
+ virtual rtl::OUString SAL_CALL
+ getOwnerEntity( )
+ throw (uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ getAdminEntity( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsEntity( const rtl::OUString& aEntity )
+ throw (backend::BackendAccessException, uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ isEqualEntity( const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const rtl::OUString& aServiceName )
+ throw (uno::RuntimeException) ;
+
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException) ;
+
+protected:
+ rtl::OUString const & getBaseUrl() const
+ { return mStrataDataUrl; }
+
+ static rtl::OUString getDataSuffix()
+ { return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(kLocalDataSuffix)); }
+//------------------------------------------------------------------------------
+ /// raise a NoSupportException for an attempt to update this layer
+ void failReadonly();
+
+ // helper for implementing the stratum getLayer[s] function[s]
+ uno::Reference<backend::XLayer> SAL_CALL
+ getLayer( const rtl::OUString& aLayerId, const rtl::OUString& aTimestamp )
+ throw (backend::BackendAccessException, lang::IllegalArgumentException, uno::RuntimeException);
+
+ /**
+ Builds a LocalFileLayer object given a subpath
+ Since the LocalFileLayer implements the various
+ interfaces a layer can be accessed as, a few methods
+ need one.
+
+ @param aSubpath Subpath
+ @return local file layer
+ @throws com::sun::star::lang::IllegalArgumentException
+ if the subpath is invalid.
+ */
+ uno::Reference<backend::XLayer> createReadonlyFileLayer(const rtl::OUString& aSubpath)
+ throw (lang::IllegalArgumentException) ;
+
+ /**
+ Builds a LocalFileLayer object given a subpath.
+ Since the LocalFileLayer implements the various
+ interfaces a layer can be accessed as, a few methods
+ need one.
+
+ @param aSubpath subpath
+ @return local file layer
+ @throws com::sun::star::lang::IllegalArgumentException
+ if the subpath is invalid.
+ */
+ uno::Reference<backend::XUpdatableLayer> createUpdatableFileLayer(const rtl::OUString& aSubpath)
+ throw (lang::IllegalArgumentException) ;
+
+ /**
+ Tells if a file is more recent than a given date.
+ The date is formatted YYYYMMDDhhmmssZ.
+
+ @param aSubpath relative URL of the component to check
+ @param aTimestamp timestamp to check against
+ @return sal_True if the file is more recent, sal_False otherwise
+ */
+ sal_Bool isMoreRecent(const rtl::OUString& aSubpath,
+ const rtl::OUString& aTimestamp) ;
+
+protected:
+ /// Parses and adjusts the passed base URL
+ virtual void adjustBaseURL(rtl::OUString& aBaseURL);
+
+private:
+ /**
+ Retrieves the appropriate layer and sublayers base directories.
+
+ @param aLayerUrl layer base URL, filled on return
+ @param aSubLayerUrl sublayer base URL, filled on return
+ */
+ virtual void getLayerDirectories(rtl::OUString& aLayerUrl,
+ rtl::OUString& aSubLayerUrl) const = 0;
+ virtual const ServiceImplementationInfo * getServiceInfoData() const = 0;
+
+private :
+ /** Service factory */
+ uno::Reference<lang::XMultiServiceFactory> mFactory ;
+ /**
+ Base of the strata data.
+ */
+ rtl::OUString mStrataDataUrl ;
+
+} ;
+
+
+} } // configmgr.localbe
+
+#endif
diff --git a/configmgr/source/localbe/makefile.mk b/configmgr/source/localbe/makefile.mk
new file mode 100644
index 000000000000..5462836be4d7
--- /dev/null
+++ b/configmgr/source/localbe/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source$/inc
+PRJNAME=configmgr
+TARGET=localbe
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES=\
+ $(SLO)$/localsinglebackend.obj \
+ $(SLO)$/localfilelayer.obj \
+ $(SLO)$/localoutputstream.obj \
+ $(SLO)$/localdataimportsvc.obj \
+ $(SLO)$/localhierarchybrowsersvc.obj \
+ $(SLO)$/localschemasupplier.obj \
+ $(SLO)$/localstratumbase.obj \
+ $(SLO)$/localsinglestratum.obj \
+ $(SLO)$/localmultistratum.obj \
+ $(SLO)$/localfilehelper.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/misc/anypair.cxx b/configmgr/source/misc/anypair.cxx
new file mode 100644
index 000000000000..eea9167aaaff
--- /dev/null
+++ b/configmgr/source/misc/anypair.cxx
@@ -0,0 +1,691 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: anypair.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <anypair.hxx>
+#include <uno/any2.h>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Type.hxx>
+
+#define CFG_PRECOND( expr ) OSL_PRECOND ( expr, "Violated Precondition: " #expr)
+#define CFG_POSTCOND( expr ) OSL_POSTCOND( expr, "Violated Postcondition: " #expr)
+
+namespace configmgr
+{
+ namespace css = com::sun::star;
+ namespace uno = css::uno;
+
+// -----------------------------------------------------------------------------
+ static inline bool impl_Any_hasValue(uno_Any const * _pData)
+ { return (typelib_TypeClass_VOID != _pData->pType->eTypeClass); }
+
+// -----------------------------------------------------------------------------
+ static inline bool impl_Any_storesData(uno_Any const * _pData)
+ {
+ const void * pAnyData = _pData->pData;
+
+ const bool bSelfReferential = (pAnyData == &_pData->pReserved);
+ OSL_ENSURE( bSelfReferential == ( _pData <= pAnyData && pAnyData < _pData+1 ),
+ "uno_Any layout changed: Unreckognized self-referentiality" );
+
+ return bSelfReferential;
+ }
+
+// -----------------------------------------------------------------------------
+ static inline void * impl_getDataPointer(const void * const * _pAnyPairData)
+ {
+ const void * const pResult = *_pAnyPairData;
+
+ return const_cast<void*>(pResult);
+ }
+
+// -----------------------------------------------------------------------------
+ static inline void * impl_getData(const void * const * _pAnyPairData, bool _bStoredData)
+ {
+ const void * const pResult = _bStoredData ? _pAnyPairData : *_pAnyPairData;
+
+ return const_cast<void*>(pResult);
+ }
+
+// -----------------------------------------------------------------------------
+ static inline void impl_setDataPointer(const void * * _pAnyPairData, void* _pData)
+ {
+ *_pAnyPairData = _pData;
+ }
+// -----------------------------------------------------------------------------
+ static const unsigned SHIFT_DATA_FLAG = 4;
+// -----------------------------------------------------------------------------
+ static
+ inline void impl_state_setState(sal_uInt8* _pState, sal_uInt8 _nState, sal_uInt8 _nSelect)
+ {
+ sal_uInt8 const nSelectMask = _nSelect | (_nSelect<<SHIFT_DATA_FLAG);
+ OSL_ENSURE( (_nState & nSelectMask) == _nState, "State specified does not belong to the selector");
+
+ *_pState &= ~nSelectMask;
+ *_pState |= _nState;
+ }
+
+// -----------------------------------------------------------------------------
+ static
+ inline void impl_state_setNull(sal_uInt8* _pState, sal_uInt8 _nSelect)
+ {
+ sal_uInt8 const nSelectMask = _nSelect | (_nSelect<<SHIFT_DATA_FLAG);
+ *_pState &= ~nSelectMask;
+ }
+
+// -----------------------------------------------------------------------------
+ static inline
+ void impl_state_setData(sal_uInt8* _pState, sal_uInt8 _nSelect)
+ {
+ sal_uInt8 const nSelectMask = _nSelect | (_nSelect<<SHIFT_DATA_FLAG);
+ *_pState |= nSelectMask;
+ }
+
+// -----------------------------------------------------------------------------
+ static inline
+ void impl_state_setValue(sal_uInt8* _pState, sal_uInt8 _nSelect, bool _bStoresData)
+ {
+ *_pState |= _nSelect;
+
+ _nSelect <<= SHIFT_DATA_FLAG;
+ if (_bStoresData)
+ *_pState |= _nSelect;
+ else
+ *_pState &= ~_nSelect;
+ }
+
+// -----------------------------------------------------------------------------
+ static
+ inline bool impl_state_isNull(sal_uInt8 const _nState, sal_uInt8 _nSelect)
+ {
+ return 0 == (_nState & _nSelect);
+ }
+
+// -----------------------------------------------------------------------------
+ static
+ inline bool impl_state_isData(sal_uInt8 const _nState, sal_uInt8 _nSelect)
+ {
+ return 0 != (_nState & (_nSelect<<SHIFT_DATA_FLAG));
+ }
+
+
+// -----------------------------------------------------------------------------
+ static
+ typelib_TypeDescriptionReference * impl_getVoidType()
+ {
+ static const uno::Type aNullType;
+ return aNullType.getTypeLibType();
+ }
+
+// -----------------------------------------------------------------------------
+ static inline
+ void anypair_type_construct_Desc( cfgmgr_AnyPair_Desc* _pAnyPairDesc,
+ typelib_TypeDescriptionReference * _pType)
+ {
+ _pAnyPairDesc->nState = 0;
+ _pAnyPairDesc->pType = _pType;
+
+ typelib_typedescriptionreference_acquire( _pAnyPairDesc->pType );
+ }
+
+// -----------------------------------------------------------------------------
+ static inline
+ void anypair_default_construct_Desc( cfgmgr_AnyPair_Desc* _pAnyPairDesc )
+ {
+ anypair_type_construct_Desc(_pAnyPairDesc, impl_getVoidType());
+ }
+
+// -----------------------------------------------------------------------------
+ static inline
+ void anypair_empty_set_Data( const void ** _pAnyPairData )
+ {
+ impl_setDataPointer(_pAnyPairData, NULL);
+ OSL_DEBUG_ONLY( impl_setDataPointer(_pAnyPairData, reinterpret_cast<void*>(0xdeadbeef)) );
+ }
+
+// -----------------------------------------------------------------------------
+ // returns a state for the specified selector
+ static inline
+ sal_uInt8 anypair_any_set_Data( const void ** _pAnyPairData,
+ sal_uInt8 _nSelect,
+ uno_Any const *_pUnoAny)
+ {
+ sal_uInt8 nState = 0;
+
+ bool bValue = impl_Any_hasValue(_pUnoAny);
+ if (bValue)
+ {
+ uno_Any aTmpAny;
+ uno_type_any_construct(&aTmpAny, _pUnoAny->pData, _pUnoAny->pType, reinterpret_cast< uno_AcquireFunc >( uno::cpp_acquire ));
+
+ bool bData = impl_Any_storesData(&aTmpAny);
+
+ impl_setDataPointer(_pAnyPairData, bData ? aTmpAny.pReserved : aTmpAny.pData);
+
+ impl_state_setValue(&nState, _nSelect, bData);
+ }
+ else
+ anypair_empty_set_Data(_pAnyPairData);
+
+ return nState;
+ }
+
+// -----------------------------------------------------------------------------
+ static inline
+ sal_uInt8 anypair_copy_Data( const void ** _pAnyPairData,
+ sal_uInt8 _nSelect,
+ cfgmgr_AnyPair_Desc const* _pAnyPairDescFrom,
+ const void * const* _pAnyPairDataFrom )
+ {
+ sal_uInt8 nState = 0;
+
+ if (impl_state_isNull(_pAnyPairDescFrom->nState, _nSelect))
+ {
+ anypair_empty_set_Data(_pAnyPairData);
+ }
+
+ else
+ {
+ bool bOldIsData = impl_state_isData(_pAnyPairDescFrom->nState, _nSelect);
+
+ void * pFromData = impl_getData(_pAnyPairDataFrom, bOldIsData);
+
+ uno_Any aTmpAny;
+ uno_type_any_construct(&aTmpAny, pFromData, _pAnyPairDescFrom->pType, reinterpret_cast< uno_AcquireFunc >( uno::cpp_acquire ));
+
+ bool bNewIsData = impl_Any_storesData(&aTmpAny);
+ OSL_ENSURE(bOldIsData == bNewIsData, "INFO [safe to ignore]: Copy of uno_Any changes directness !?");
+
+ impl_setDataPointer(_pAnyPairData, bNewIsData ? aTmpAny.pReserved : aTmpAny.pData);
+
+ impl_state_setValue(&nState, _nSelect, bNewIsData);
+ }
+
+ return nState;
+ }
+
+// -----------------------------------------------------------------------------
+ static inline
+ void anypair_destruct_Desc(cfgmgr_AnyPair_Desc* _pAnyPairDesc)
+ {
+ typelib_typedescriptionreference_release( _pAnyPairDesc->pType );
+ OSL_DEBUG_ONLY(_pAnyPairDesc->nState = 0xDD);
+ OSL_DEBUG_ONLY(_pAnyPairDesc->pType = (typelib_TypeDescriptionReference*)0xdeadbeef);
+ }
+
+// -----------------------------------------------------------------------------
+ static
+ void anypair_clear_Data( const void ** _pAnyPairData,
+ sal_uInt8 _nSelect,
+ cfgmgr_AnyPair_Desc const* _pAnyPairDesc
+ )
+ {
+ if (!impl_state_isNull(_pAnyPairDesc->nState,_nSelect))
+ {
+ uno_Any aTmpAny;
+ aTmpAny.pType = _pAnyPairDesc->pType;
+
+ if (impl_state_isData(_pAnyPairDesc->nState,_nSelect))
+ {
+ aTmpAny.pReserved = impl_getDataPointer(_pAnyPairData);
+ aTmpAny.pData = &aTmpAny.pReserved;
+ }
+ else
+ {
+ aTmpAny.pReserved = NULL;
+ aTmpAny.pData = impl_getDataPointer(_pAnyPairData);
+ }
+
+ typelib_typedescriptionreference_acquire( aTmpAny.pType );
+ uno_any_destruct(&aTmpAny, reinterpret_cast< uno_ReleaseFunc >( uno::cpp_release ));
+
+ impl_setDataPointer(_pAnyPairData, NULL);
+ OSL_DEBUG_ONLY(impl_setDataPointer(_pAnyPairData, reinterpret_cast<void*>(0xDeadBeef)));
+ }
+ }
+
+// -----------------------------------------------------------------------------
+ static
+ void anypair_Data_fill_Any( uno_Any* _pUnoAny,
+ cfgmgr_AnyPair_Desc const* _pAnyPairDesc,
+ const void * const* _pAnyPairData,
+ sal_uInt8 _nSelect )
+ {
+ if (impl_state_isNull(_pAnyPairDesc->nState,_nSelect))
+ {
+ _pUnoAny->pType = impl_getVoidType();
+ _pUnoAny->pReserved = NULL;
+ _pUnoAny->pData = NULL;
+ }
+ else if (impl_state_isData(_pAnyPairDesc->nState,_nSelect))
+ {
+ _pUnoAny->pType = _pAnyPairDesc->pType;
+ _pUnoAny->pReserved = impl_getDataPointer(_pAnyPairData);
+ _pUnoAny->pData = &_pUnoAny->pReserved;
+ }
+ else
+ {
+ _pUnoAny->pType = _pAnyPairDesc->pType;
+ _pUnoAny->pReserved = NULL;
+ _pUnoAny->pData = impl_getDataPointer(_pAnyPairData);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+ static inline
+ typelib_TypeDescriptionReference*
+ anypair_test_assigned_type( typelib_TypeDescriptionReference* _pOldType,
+ typelib_TypeDescriptionReference* _pNewType)
+ {
+ typelib_TypeDescriptionReference* pResult;
+ if ( _pNewType->eTypeClass == typelib_TypeClass_VOID)
+ pResult = _pOldType;
+
+ else if (_pOldType->eTypeClass == typelib_TypeClass_VOID || _pOldType->eTypeClass == typelib_TypeClass_ANY )
+ pResult = _pNewType;
+
+ else if ( typelib_typedescriptionreference_equals(_pOldType,_pNewType) )
+ pResult = _pOldType;
+
+ else
+ pResult = NULL;
+
+ return pResult;
+ }
+
+// -----------------------------------------------------------------------------
+ static
+ sal_Bool anypair_any_assign_Data( cfgmgr_AnyPair_Desc* _pAnyPairDesc,
+ const void ** _pAnyPairData,
+ sal_uInt8 _nSelect,
+ uno_Any const *_pUnoAny)
+ {
+ typelib_TypeDescriptionReference* pOldType = _pAnyPairDesc->pType;
+ typelib_TypeDescriptionReference* pNewType = anypair_test_assigned_type(pOldType,_pUnoAny->pType);
+
+ if (pNewType != NULL)
+ {
+ uno_Any aTmpAny;
+ anypair_Data_fill_Any(&aTmpAny,_pAnyPairDesc,_pAnyPairData,_nSelect);
+
+ typelib_typedescriptionreference_acquire(aTmpAny.pType);
+
+ uno_type_any_assign(&aTmpAny,
+ _pUnoAny->pData,
+ _pUnoAny->pType,
+ reinterpret_cast< uno_AcquireFunc >( uno::cpp_acquire ),
+ reinterpret_cast< uno_AcquireFunc >( uno::cpp_release ));
+
+ sal_uInt8 nNewState = anypair_any_set_Data(_pAnyPairData,_nSelect,&aTmpAny);
+ impl_state_setState(&_pAnyPairDesc->nState, nNewState, _nSelect);
+
+ uno_any_destruct(
+ &aTmpAny,
+ reinterpret_cast< uno_ReleaseFunc >(uno::cpp_release));
+
+ if (pNewType != pOldType)
+ {
+ typelib_typedescriptionreference_acquire(pNewType);
+ typelib_typedescriptionreference_release(pOldType);
+ _pAnyPairDesc->pType = pNewType;
+ }
+
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(_pAnyPairDesc,_nSelect) == !impl_Any_hasValue(_pUnoAny) );
+ CFG_POSTCOND( typelib_typedescriptionreference_equals(_pAnyPairDesc->pType,pNewType) );
+ }
+ else
+ OSL_ENSURE(false, "anypair_assign_XXX(): Cannot assign - Type mismatch");
+
+ return (pNewType != NULL);
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ void anypair_construct_default(cfgmgr_AnyPair * _pAnyPair)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+
+ anypair_default_construct_Desc(&_pAnyPair->desc);
+ anypair_empty_set_Data(&_pAnyPair->first);
+ anypair_empty_set_Data(&_pAnyPair->second);
+
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_BOTH) );
+ CFG_POSTCOND( cfgmgr_AnyPair_isEmpty(&_pAnyPair->desc) );
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_construct_type(cfgmgr_AnyPair * _pAnyPair, typelib_TypeDescriptionReference* _pType)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+ CFG_PRECOND( _pType != NULL );
+
+ anypair_type_construct_Desc(&_pAnyPair->desc, _pType);
+ anypair_empty_set_Data(&_pAnyPair->first);
+ anypair_empty_set_Data(&_pAnyPair->second);
+
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_BOTH) );
+ CFG_POSTCOND( typelib_typedescriptionreference_equals(_pAnyPair->desc.pType,_pType) );
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_construct_first(cfgmgr_AnyPair * _pAnyPair, uno_Any const *_pUnoAny)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+ CFG_PRECOND( _pUnoAny != NULL );
+
+ anypair_type_construct_Desc(&_pAnyPair->desc, _pUnoAny->pType);
+
+ _pAnyPair->desc.nState = anypair_any_set_Data (&_pAnyPair->first, cfgmgr_SELECT_FIRST, _pUnoAny);
+
+ anypair_empty_set_Data(&_pAnyPair->second);
+
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_FIRST) == !impl_Any_hasValue(_pUnoAny) );
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_SECOND) );
+ CFG_POSTCOND( typelib_typedescriptionreference_equals(_pAnyPair->desc.pType,_pUnoAny ->pType) );
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_construct_second(cfgmgr_AnyPair * _pAnyPair, uno_Any const *_pUnoAny)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+ CFG_PRECOND( _pUnoAny != NULL );
+
+ anypair_type_construct_Desc(&_pAnyPair->desc, _pUnoAny->pType);
+
+ anypair_empty_set_Data(&_pAnyPair->first);
+
+ _pAnyPair->desc.nState = anypair_any_set_Data (&_pAnyPair->second, cfgmgr_SELECT_SECOND, _pUnoAny);
+
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_FIRST) );
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_SECOND) == !impl_Any_hasValue(_pUnoAny) );
+ CFG_POSTCOND( typelib_typedescriptionreference_equals(_pAnyPair->desc.pType,_pUnoAny ->pType) );
+ }
+
+// -----------------------------------------------------------------------------
+ // if type not equal, you got false and the struct contains undefined values
+ sal_Bool anypair_construct(cfgmgr_AnyPair * _pAnyPair, uno_Any const * _pFirstAny, uno_Any const *_pSecondAny)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+ CFG_PRECOND( _pFirstAny != NULL );
+ CFG_PRECOND( _pSecondAny != NULL );
+
+ bool bHasFirst = impl_Any_hasValue(_pFirstAny);
+ bool bHasSecond = impl_Any_hasValue(_pSecondAny);
+
+ if (bHasFirst && bHasSecond)
+ {
+ if ( ! typelib_typedescriptionreference_equals(_pFirstAny->pType,_pSecondAny->pType))
+ {
+ OSL_ENSURE(false, "anypair_construct(): Cannot construct - Different types");
+ return false;
+ }
+ }
+
+ anypair_type_construct_Desc(&_pAnyPair->desc, bHasFirst ? _pFirstAny->pType : _pSecondAny->pType);
+
+ sal_uInt8 nState = 0;
+
+ nState |= anypair_any_set_Data (&_pAnyPair->first, cfgmgr_SELECT_FIRST, _pFirstAny);
+ nState |= anypair_any_set_Data (&_pAnyPair->second, cfgmgr_SELECT_SECOND, _pSecondAny);
+
+ _pAnyPair->desc.nState = nState;
+
+ CFG_POSTCOND((bHasFirst || bHasSecond) == !cfgmgr_AnyPair_isEmpty(&_pAnyPair->desc) );
+ CFG_POSTCOND( bHasFirst == !cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_FIRST) );
+ CFG_POSTCOND( bHasSecond == !cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_SECOND) );
+ CFG_POSTCOND( !bHasFirst || typelib_typedescriptionreference_equals(_pAnyPair->desc.pType,_pFirstAny ->pType) );
+ CFG_POSTCOND( !bHasSecond || typelib_typedescriptionreference_equals(_pAnyPair->desc.pType,_pSecondAny->pType) );
+
+ return true;
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_copy_construct(cfgmgr_AnyPair* _pAnyPair, cfgmgr_AnyPair const * _pAnyPairFrom)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+ CFG_PRECOND( _pAnyPairFrom != NULL );
+
+ anypair_type_construct_Desc(&_pAnyPair->desc, _pAnyPairFrom->desc.pType);
+
+ sal_uInt8 nState = 0;
+
+ nState |= anypair_copy_Data(&_pAnyPair->first, cfgmgr_SELECT_FIRST,
+ &_pAnyPairFrom->desc, &_pAnyPairFrom->first );
+
+ nState |= anypair_copy_Data(&_pAnyPair->second, cfgmgr_SELECT_SECOND,
+ &_pAnyPairFrom->desc, &_pAnyPairFrom->second );
+
+ _pAnyPair->desc.nState = nState;
+
+ OSL_ENSURE(_pAnyPairFrom->desc.nState == nState, "Unexpected: Copy changes state");
+ CFG_POSTCOND( typelib_typedescriptionreference_equals(_pAnyPair->desc.pType,_pAnyPairFrom->desc.pType) );
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_destruct(cfgmgr_AnyPair* _pAnyPair)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+
+ anypair_clear_Data(&_pAnyPair->first, cfgmgr_SELECT_FIRST, &_pAnyPair->desc);
+ anypair_clear_Data(&_pAnyPair->second, cfgmgr_SELECT_SECOND, &_pAnyPair->desc);
+ anypair_destruct_Desc(&_pAnyPair->desc );
+ }
+
+// -----------------------------------------------------------------------------
+ sal_Bool anypair_assign_first(cfgmgr_AnyPair* _pAnyPair, uno_Any const * _pUnoAny)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+ CFG_PRECOND( _pUnoAny != NULL );
+
+ return anypair_any_assign_Data(&_pAnyPair->desc, &_pAnyPair->first, cfgmgr_SELECT_FIRST, _pUnoAny);
+ }
+
+// -----------------------------------------------------------------------------
+ sal_Bool anypair_assign_second(cfgmgr_AnyPair* _pAnyPair, uno_Any const * _pUnoAny)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+ CFG_PRECOND( _pUnoAny != NULL );
+
+ return anypair_any_assign_Data(&_pAnyPair->desc, &_pAnyPair->second, cfgmgr_SELECT_SECOND, _pUnoAny);
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_assign(cfgmgr_AnyPair* _pAnyPair, cfgmgr_AnyPair const * _pAnyPairFrom)
+ {
+ if (_pAnyPair != _pAnyPairFrom)
+ {
+ anypair_destruct(_pAnyPair);
+ anypair_copy_construct(_pAnyPair, _pAnyPairFrom);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_clear_first(cfgmgr_AnyPair* _pAnyPair)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+
+ anypair_clear_Data(&_pAnyPair->first, cfgmgr_SELECT_FIRST, &_pAnyPair->desc);
+ impl_state_setNull(&_pAnyPair->desc.nState, cfgmgr_SELECT_FIRST);
+
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_FIRST) );
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_clear_second(cfgmgr_AnyPair* _pAnyPair)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+
+ anypair_clear_Data(&_pAnyPair->second, cfgmgr_SELECT_SECOND, &_pAnyPair->desc );
+ impl_state_setNull(&_pAnyPair->desc.nState, cfgmgr_SELECT_SECOND);
+
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_SECOND) );
+ }
+
+// -----------------------------------------------------------------------------
+ void anypair_clear_values(cfgmgr_AnyPair* _pAnyPair)
+ {
+ CFG_PRECOND( _pAnyPair != NULL );
+
+ anypair_clear_Data(&_pAnyPair->first, cfgmgr_SELECT_FIRST, &_pAnyPair->desc);
+ anypair_clear_Data(&_pAnyPair->second, cfgmgr_SELECT_SECOND, &_pAnyPair->desc );
+ impl_state_setNull(&_pAnyPair->desc.nState, cfgmgr_SELECT_BOTH);
+
+ CFG_POSTCOND( cfgmgr_AnyPair_isNull(&_pAnyPair->desc,cfgmgr_SELECT_BOTH) );
+ }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ static
+ inline
+ uno::Any anypair_Data_toAny(cfgmgr_AnyPair_Desc const* _pAnyPairDesc,
+ const void * const* _pAnyPairData,
+ sal_uInt8 _nSelect)
+ {
+ uno_Any aTmpAny;
+ anypair_Data_fill_Any(&aTmpAny,_pAnyPairDesc,_pAnyPairData,_nSelect);
+
+ return uno::Any( aTmpAny.pData, aTmpAny.pType );
+ }
+
+// -----------------------------------------------------------------------------
+ AnyPair::AnyPair(uno::Type const& _aType) // one Type, any's are null
+ {
+ anypair_construct_type(&m_aAnyPair, _aType.getTypeLibType());
+ }
+
+// -----------------------------------------------------------------------------
+ AnyPair::AnyPair(uno::Any const& _aAny, SelectMember _select)
+ {
+ switch (_select)
+ {
+ case SELECT_FIRST: anypair_construct_first(&m_aAnyPair,&_aAny); break;
+ case SELECT_SECOND: anypair_construct_second(&m_aAnyPair,&_aAny); break;
+ case SELECT_BOTH: OSL_VERIFY( anypair_construct(&m_aAnyPair,&_aAny,&_aAny) ); break;
+
+ default: OSL_ENSURE(false, "AnyPair: Unknown member selector");
+ anypair_construct_default(&m_aAnyPair); break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+ AnyPair::AnyPair(uno::Any const& _aAny, uno::Any const& _aAny2) SAL_THROW((lang::IllegalArgumentException))
+ {
+ if (!anypair_construct(&m_aAnyPair,&_aAny, &_aAny2))
+ {
+ throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AnyPair: Type mismatch in constructor.")),NULL,-1);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+ // copy-ctor
+ AnyPair::AnyPair(AnyPair const& _aOther)
+ {
+ anypair_copy_construct(&m_aAnyPair, &_aOther.m_aAnyPair);
+ }
+
+// -----------------------------------------------------------------------------
+ // assign operator
+ AnyPair& AnyPair::operator=(AnyPair const& _aOther)
+ {
+ anypair_assign(&m_aAnyPair, &_aOther.m_aAnyPair);
+ return *this;
+ }
+
+// -----------------------------------------------------------------------------
+ // d-tor
+ AnyPair::~AnyPair()
+ {
+ anypair_destruct(&m_aAnyPair);
+ }
+
+
+// -----------------------------------------------------------------------------
+ sal_Bool AnyPair::setFirst(uno::Any const& _aAny)
+ {
+ return anypair_assign_first(&m_aAnyPair,&_aAny);
+ }
+
+// -----------------------------------------------------------------------------
+ sal_Bool AnyPair::setSecond(uno::Any const& _aAny)
+ {
+ return anypair_assign_second(&m_aAnyPair,&_aAny);
+ }
+
+// -----------------------------------------------------------------------------
+ void AnyPair::clear(SelectMember _select)
+ {
+ switch (_select)
+ {
+ case SELECT_FIRST: anypair_clear_first(&m_aAnyPair); break;
+ case SELECT_SECOND: anypair_clear_second(&m_aAnyPair); break;
+ case SELECT_BOTH: anypair_clear_values(&m_aAnyPair); break;
+
+ default: OSL_ENSURE(false, "AnyPair: Unknown member selector");
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+ uno::Type AnyPair::getValueType() const
+ {
+ return uno::Type(m_aAnyPair.desc.pType);
+ }
+
+// -----------------------------------------------------------------------------
+ uno::Any AnyPair::getFirst() const
+ {
+ return anypair_Data_toAny( &m_aAnyPair.desc, &m_aAnyPair.first, cfgmgr_SELECT_FIRST );
+ }
+// -----------------------------------------------------------------------------
+ uno::Any AnyPair::getSecond() const
+ {
+ return anypair_Data_toAny( &m_aAnyPair.desc, &m_aAnyPair.second, cfgmgr_SELECT_SECOND );
+ }
+
+// -----------------------------------------------------------------------------
+ uno::Any AnyPair::getValue(SelectMember _select) const
+ {
+ switch (_select)
+ {
+ case SELECT_FIRST: return getFirst();
+ case SELECT_SECOND: return getSecond();
+
+ default: OSL_ENSURE(false, "AnyPair: Unknown member selector");
+ case SELECT_BOTH: OSL_ENSURE(false, "AnyPair: Cannot get value - Invalid selector");
+ return uno::Any();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+
+} // namespace
+
diff --git a/configmgr/source/misc/bootstrap.cxx b/configmgr/source/misc/bootstrap.cxx
new file mode 100644
index 000000000000..809d992c5ec4
--- /dev/null
+++ b/configmgr/source/misc/bootstrap.cxx
@@ -0,0 +1,717 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bootstrap.cxx,v $
+ * $Revision: 1.35 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "bootstrap.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include "serviceinfohelper.hxx"
+#include "matchlocale.hxx"
+#include "tracer.hxx"
+#include <cppuhelper/component_context.hxx>
+#include <rtl/bootstrap.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <osl/module.hxx>
+#include <osl/diagnose.h>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
+#include <com/sun/star/configuration/InstallationIncompleteException.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+// ---------------------------------------------------------------------------------------
+// legacy argument names
+#define ARGUMENT_LOCALE_COMPAT "locale"
+#define ARGUMENT_ASYNC_COMPAT "lazywrite"
+#define ARGUMENT_SERVERTYPE_COMPAT "servertype"
+
+// legacy servertype setting
+#define SETTING_SERVERTYPE_COMPAT "ServerType"
+#define BOOTSTRAP_SERVERTYPE_COMPAT CONTEXT_ITEM_PREFIX_ SETTING_SERVERTYPE_COMPAT
+
+#define SERVERTYPE_UNO_COMPAT "uno"
+#define SERVERTYPE_PLUGIN_COMPAT "plugin"
+// ---------------------------------------------------------------------------------------
+
+#define NAME( N ) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(N))
+#define ITEM( N ) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(N))
+// ---------------------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------------------
+namespace configmgr
+{
+// ---------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------
+ static void convertToBool(const uno::Any& aValue, sal_Bool& bValue)
+ {
+ rtl::OUString aStrValue;
+ if (aValue >>= aStrValue)
+ {
+ if (aStrValue.equalsIgnoreAsciiCaseAscii("true"))
+ {
+ bValue = sal_True;
+ }
+ else if (aStrValue.equalsIgnoreAsciiCaseAscii("false"))
+ {
+ bValue = sal_False;
+ }
+ }
+ }
+ // ----------------------------------------------------------------------------------
+ const sal_Char k_BootstrapContextImplName[] = "com.sun.star.comp.configuration.bootstrap.BootstrapContext" ;
+ const sal_Char k_BootstrapContextServiceName[] = "com.sun.star.configuration.bootstrap.BootstrapContext" ;
+
+ // -------------------------------------------------------------------------
+ static sal_Char const * const k_BootstrapContextServiceNames [] =
+ {
+ k_BootstrapContextServiceName,
+ 0
+ };
+ static const ServiceImplementationInfo k_BootstrapContextServiceInfo =
+ {
+ k_BootstrapContextImplName,
+ k_BootstrapContextServiceNames,
+ 0
+ };
+ static const SingletonRegistrationInfo k_BootstrapContextSingletonInfo =
+ {
+ A_BootstrapContextSingletonName,
+ k_BootstrapContextImplName,
+ k_BootstrapContextServiceName,
+ 0
+ };
+// ---------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------
+ uno::Reference<uno::XInterface> SAL_CALL
+ instantiateBootstrapContext( uno::Reference< uno::XComponentContext > const& xTargetContext )
+ {
+ uno::Reference< uno::XComponentContext > xContext = UnoContextTunnel::recoverContext(xTargetContext);
+
+ BootstrapContext * pContext = new BootstrapContext(xContext);
+ uno::Reference< uno::XComponentContext > xResult(pContext);
+
+ pContext->initialize();
+
+ return uno::Reference< uno::XInterface >( xResult, uno::UNO_QUERY );
+ }
+
+ const SingletonRegistrationInfo * getBootstrapContextSingletonInfo()
+ {
+ return &k_BootstrapContextSingletonInfo;
+ }
+ const ServiceRegistrationInfo * getBootstrapContextServiceInfo()
+ {
+ return getRegistrationInfo(&k_BootstrapContextServiceInfo);
+ }
+// ---------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+
+ static
+ inline
+ cppu::ContextEntry_Init makeEntry(beans::NamedValue const & aOverride)
+ {
+ return cppu::ContextEntry_Init(aOverride.Name,aOverride.Value);
+ }
+// ---------------------------------------------------------------------------
+
+ static
+ cppu::ContextEntry_Init makeSingleton(SingletonRegistrationInfo const * pSingletonInfo)
+ {
+ OSL_ASSERT( pSingletonInfo &&
+ pSingletonInfo->singletonName &&
+ pSingletonInfo->instantiatedServiceName );
+
+ rtl::OUStringBuffer aSingletonName;
+ aSingletonName.appendAscii( RTL_CONSTASCII_STRINGPARAM(SINGLETON_) );
+ aSingletonName.appendAscii(pSingletonInfo->singletonName);
+
+ rtl::OUString const aServiceName = rtl::OUString::createFromAscii(pSingletonInfo->instantiatedServiceName);
+
+ return cppu::ContextEntry_Init(aSingletonName.makeStringAndClear(), uno::makeAny(aServiceName), true);
+ }
+// ---------------------------------------------------------------------------
+
+uno::Reference< uno::XComponentContext > BootstrapContext::createWrapper(uno::Reference< uno::XComponentContext > const & _xContext, uno::Sequence < beans::NamedValue > const & _aOverrides)
+{
+ std::vector< cppu::ContextEntry_Init > aContextEntries;
+ aContextEntries.reserve(_aOverrides.getLength() + 5);
+
+ // marker + bootstrap context
+ aContextEntries.push_back( cppu::ContextEntry_Init(NAME(CONTEXT_ITEM_IS_WRAPPER_CONTEXT), uno::makeAny(sal_True)) );
+ aContextEntries.push_back( cppu::ContextEntry_Init(NAME(CONTEXT_ITEM_IS_BOOTSTRAP_CONTEXT), uno::makeAny(sal_False)) );
+
+ aContextEntries.push_back( makeSingleton(getBootstrapContextSingletonInfo()) );
+
+ // singletons except for passthrough
+ if (!isPassthrough(_xContext))
+ {
+ aContextEntries.push_back( makeSingleton(getDefaultProviderSingletonInfo()) );
+ aContextEntries.push_back( makeSingleton(backend::getDefaultBackendSingletonInfo()) );
+ }
+
+ for (sal_Int32 i = 0; i<_aOverrides.getLength(); ++i)
+ aContextEntries.push_back( makeEntry(_aOverrides[i]) );
+
+ return cppu::createComponentContext(&aContextEntries.front(),aContextEntries.size(),_xContext);
+}
+// ---------------------------------------------------------------------------
+
+sal_Bool BootstrapContext::isWrapper(uno::Reference< uno::XComponentContext > const & _xContext)
+{
+ OSL_ASSERT(_xContext.is());
+ if (!_xContext.is()) return false;
+
+ uno::Any aSetting = _xContext->getValueByName( NAME(CONTEXT_ITEM_IS_WRAPPER_CONTEXT) );
+
+ if (!aSetting.hasValue()) return false;
+
+ sal_Bool bValue = false;
+ OSL_VERIFY(aSetting >>= bValue);
+
+ return bValue;
+}
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+
+BootstrapContext::BootstrapContext(uno::Reference< uno::XComponentContext > const & _xContext)
+: ComponentContext(_xContext)
+{
+}
+// ---------------------------------------------------------------------------
+
+BootstrapContext::~BootstrapContext()
+{
+}
+// ---------------------------------------------------------------------------
+
+void BootstrapContext::initialize()
+{
+ // get default Bootstrap URL
+ rtl::OUString sURL;
+ uno::Any aExplicitURL;
+ if ( this->lookupInContext(aExplicitURL,NAME(CONTEXT_ITEM_PREFIX_ SETTING_INIFILE)) )
+ {
+ OSL_VERIFY(aExplicitURL >>= sURL);
+ }
+ else if (!rtl::Bootstrap::get(NAME(BOOTSTRAP_ITEM_INIFILE),sURL))
+ {
+ sURL = getDefaultConfigurationBootstrapURL();
+ }
+
+ ComponentContext::initialize(sURL);
+}
+// ---------------------------------------------------------------------------
+
+static rtl::OUString getCurrentModuleDirectory() // URL including terminating slash
+{
+ rtl::OUString aFileURL;
+ if ( !osl::Module::getUrlFromAddress(reinterpret_cast< oslGenericFunction >( &getCurrentModuleDirectory ),aFileURL) )
+ {
+ OSL_TRACE(false, "Cannot locate current module - using executable instead");
+
+ OSL_VERIFY(osl_Process_E_None == osl_getExecutableFile(&aFileURL.pData));
+ }
+
+ OSL_ENSURE(0 < aFileURL.lastIndexOf('/'), "Cannot find directory for module URL");
+
+ return aFileURL.copy(0, aFileURL.lastIndexOf('/') + 1);
+}
+// ---------------------------------------------------------------------------------------
+
+rtl::OUString BootstrapContext::getDefaultConfigurationBootstrapURL()
+{
+ return getCurrentModuleDirectory() + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CONFIGMGR_INIFILE));
+}
+// ---------------------------------------------------------------------------------------
+
+rtl::OUString BootstrapContext::makeContextName(rtl::OUString const & _aName)
+{
+ // check that it isn't long already
+ OSL_ENSURE(!_aName.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM(CONTEXT_MODULE_PREFIX_) ),
+ "configmgr::BootstrapContext: passing argument in long context form won't work");
+
+ return NAME(CONTEXT_ITEM_PREFIX_).concat(_aName);
+}
+// ---------------------------------------------------------------------------
+
+rtl::OUString BootstrapContext::makeBootstrapName(rtl::OUString const & _aName)
+{
+ // check if already is short
+ if (!_aName.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM(CONTEXT_ITEM_PREFIX_) ) )
+ {
+ OSL_TRACE( "configmgr: Cannot map name to bootstrap name: %s",
+ rtl::OUStringToOString(_aName,RTL_TEXTENCODING_ASCII_US).getStr() );
+ return _aName;
+ }
+ return NAME(BOOTSTRAP_ITEM_PREFIX_).concat(_aName.copy(RTL_CONSTASCII_LENGTH(CONTEXT_ITEM_PREFIX_)));
+}
+// ---------------------------------------------------------------------------
+
+uno::Any SAL_CALL
+ BootstrapContext::getValueByName( const rtl::OUString& aName )
+ throw (uno::RuntimeException)
+{
+ sal_Bool const bOurName = aName.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM(CONTEXT_MODULE_PREFIX_) );
+
+ if (bOurName)
+ {
+ if (aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(CONTEXT_ITEM_BOOTSTRAP_ERROR) ) )
+ return this->makeBootstrapException();
+
+ if (aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(CONTEXT_ITEM_PREFIX_ SETTING_INIFILE) ) )
+ return uno::makeAny( this->getBootstrapURL() );
+
+ if (aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(CONTEXT_ITEM_IS_BOOTSTRAP_CONTEXT) ) )
+ return uno::makeAny( sal_True );
+ }
+ else if (aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SINGLETON_ A_BootstrapContextSingletonName) ) )
+ {
+ return uno::makeAny( uno::Reference< uno::XComponentContext >(this) );
+ }
+
+ uno::Any aResult;
+
+ bool bFound = lookupInContext ( aResult, aName );
+
+ if (!bFound && bOurName) // requires: CONTEXT_ITEM_PREFIX_ starts with CONTEXT_MODULE_PREFIX_
+ {
+ if ( aName.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM(CONTEXT_ITEM_PREFIX_) ) )
+ {
+ bFound = lookupInBootstrap( aResult, makeBootstrapName(aName) );
+ }
+ }
+ return aResult;
+}
+
+// ---------------------------------------------------------------------------
+// class ContextReader
+// ---------------------------------------------------------------------------
+
+ ContextReader::ContextReader(uno::Reference< uno::XComponentContext > const & context)
+ : m_basecontext(context)
+ , m_fullcontext()
+ {
+ OSL_ENSURE(context.is(), "ERROR: trying to create reader on NULL context\n");
+ if (context.is())
+ {
+ uno::Any aBootstrapContext = context->getValueByName( SINGLETON(A_BootstrapContextSingletonName) );
+ aBootstrapContext >>= m_fullcontext;
+ }
+ }
+// ---------------------------------------------------------------------------
+
+ uno::Reference< lang::XMultiComponentFactory > ContextReader::getServiceManager() const
+ {
+ OSL_ASSERT(m_basecontext.is());
+ return m_basecontext->getServiceManager();
+ }
+// ---------------------------------------------------------------------------
+ inline
+ uno::Any ContextReader::getSetting(rtl::OUString const & _aSetting) const
+ {
+ OSL_ASSERT(m_basecontext.is());
+ return getBestContext()->getValueByName(_aSetting);
+ }
+
+ inline
+ sal_Bool ContextReader::hasSetting(rtl::OUString const & _aSetting) const
+ {
+ return getSetting(_aSetting).hasValue();
+ }
+
+ inline
+ sal_Bool ContextReader::getBoolSetting(rtl::OUString const & _aSetting, sal_Bool bValue = false) const
+ {
+ uno::Any aValue = getSetting(_aSetting);
+ if (!(aValue >>= bValue))
+ convertToBool(aValue, bValue);
+
+ return bValue;
+ }
+
+ inline
+ rtl::OUString ContextReader::getStringSetting(rtl::OUString const & _aSetting, rtl::OUString aValue = rtl::OUString()) const
+ {
+ getSetting(_aSetting) >>= aValue;
+ return aValue;
+ }
+// ---------------------------------------------------------------------------------------
+
+ sal_Bool ContextReader::isUnoBackend() const
+ {
+ rtl::OUString aSettingName = NAME(BOOTSTRAP_SERVERTYPE_COMPAT);
+
+ rtl::OUString aValue;
+ if (getSetting(aSettingName) >>= aValue)
+ {
+ return aValue.equalsAscii(SERVERTYPE_UNO_COMPAT);
+ }
+ else
+ {
+ return true;
+ }
+ }
+// ---------------------------------------------------------------------------------------
+
+ sal_Bool ContextReader::hasUnoBackendService() const
+ {
+ return hasSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_UNOSERVICE) );
+ }
+ sal_Bool ContextReader::hasUnoBackendWrapper() const
+ {
+ return hasSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_UNOWRAPPER) );
+ }
+
+ sal_Bool ContextReader::hasLocale() const
+ {
+ return hasSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_LOCALE_NEW) );
+ }
+ sal_Bool ContextReader::hasAsyncSetting() const
+ {
+ return hasSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_ASYNC_NEW) );
+ }
+ sal_Bool ContextReader::hasOfflineSetting() const
+ {
+ return hasSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_OFFLINE) );
+ }
+// ---------------------------------------------------------------------------------------
+
+ rtl::OUString ContextReader::getUnoBackendService() const
+ {
+ return getStringSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_UNOSERVICE) );
+ }
+ rtl::OUString ContextReader::getUnoBackendWrapper() const
+ {
+ return getStringSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_UNOWRAPPER) );
+ }
+
+ rtl::OUString ContextReader::getLocale() const
+ {
+ return getStringSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_LOCALE_NEW) );
+ }
+ sal_Bool ContextReader::getAsyncSetting() const
+ {
+ return getBoolSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_ASYNC_NEW) );
+ }
+ sal_Bool ContextReader::getOfflineSetting() const
+ {
+ return getBoolSetting( NAME(CONTEXT_ITEM_PREFIX_ SETTING_OFFLINE) );
+ }
+
+ // get a special setting
+ sal_Bool ContextReader::isAdminService() const
+ {
+ return getBoolSetting( NAME(CONTEXT_ITEM_ADMINFLAG) );
+ }
+
+ sal_Bool ContextReader::isBootstrapValid() const
+ {
+ return this->isUnoBackend() &&
+ this->hasUnoBackendService() &&
+ (this->hasUnoBackendWrapper() || !this->getOfflineSetting());
+ }
+
+ uno::Any ContextReader::getBootstrapError() const
+ {
+ return getSetting( NAME(CONTEXT_ITEM_BOOTSTRAP_ERROR) );
+ }
+// ---------------------------------------------------------------------------------------
+
+ bool ContextReader::testAdminService(uno::Reference< uno::XComponentContext > const & context, bool bAdmin)
+ {
+ OSL_ASSERT(context.is());
+ if (!context.is()) return false;
+
+ uno::Any aSetting = context->getValueByName( NAME(CONTEXT_ITEM_ADMINFLAG) );
+
+ sal_Bool bValue = false;
+ bool bTest = (aSetting >>= bValue) && bValue;
+
+ return bTest == bAdmin;
+ }
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------
+
+ bool ArgumentHelper::extractArgument(beans::NamedValue & rValue, const uno::Any & aOverride)
+ {
+ if ( ! (aOverride >>= rValue) )
+ {
+ // it must be a PropertyValue, if it isn't a NamedValue
+ beans::PropertyValue aPV;
+ if ( !(aOverride >>= aPV) )
+ return false;
+
+ rValue.Name = aPV.Name;
+ rValue.Value = aPV.Value;
+ }
+
+ return true;
+ }
+
+// ---------------------------------------------------------------------------------------
+
+ bool ArgumentHelper::checkBackendArgument(beans::NamedValue const & aAdjustedValue)
+ {
+ bool isWrappable =
+ aAdjustedValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(CONTEXT_ITEM_PREFIX_ SETTING_ASYNC_NEW)) ||
+ aAdjustedValue.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(CONTEXT_ITEM_PREFIX_ SETTING_LOCALE_NEW));
+
+ if (isWrappable) return false;
+
+ m_bHasBackendArguments = true;
+ return true;
+ }
+// ---------------------------------------------------------------------------------------
+
+ bool ArgumentHelper::filterAndAdjustArgument(beans::NamedValue & rValue)
+ {
+ // handle old servertype argument and filter the 'plugin' value
+ if (rValue.Name.equalsAscii(ARGUMENT_SERVERTYPE_COMPAT))
+ {
+ rtl::OUString aServertype;
+ if (! (rValue.Value >>= aServertype))
+ return false;
+
+ if (aServertype.equalsAscii(SERVERTYPE_PLUGIN_COMPAT))
+ return false;
+
+ rValue.Name = NAME(BOOTSTRAP_SERVERTYPE_COMPAT);
+ // check, if it is already there
+ uno::Any const aExistingValue = m_context->getValueByName(rValue.Name);
+
+ if (aExistingValue.hasValue())
+ return !(aExistingValue == rValue.Value);
+
+ else
+ return !aServertype.equalsAscii(SERVERTYPE_UNO_COMPAT);
+ }
+
+ // map old argument names for comatibility
+ else if (rValue.Name.equalsAscii(ARGUMENT_LOCALE_COMPAT))
+ rValue.Name = NAME(SETTING_LOCALE_NEW);
+
+ else if (rValue.Name.equalsAscii(ARGUMENT_ASYNC_COMPAT))
+ rValue.Name = NAME(SETTING_ASYNC_NEW);
+
+ // give the item a long name
+ rValue.Name = BootstrapContext::makeContextName(rValue.Name);
+
+ // check, if it is already there
+ uno::Any const aExistingValue = m_context->getValueByName(rValue.Name);
+
+ return ! (aExistingValue == rValue.Value);
+ }
+// ---------------------------------------------------------------------------------------
+
+ beans::NamedValue ArgumentHelper::makeAdminServiceOverride(sal_Bool bAdmin)
+ {
+ return beans::NamedValue( NAME(CONTEXT_ITEM_ADMINFLAG), uno::makeAny(bAdmin) );
+ }
+// ---------------------------------------------------------------------------------------
+// ---------------------------------------------------------------------------------------
+// - bootstrapping error checking helper
+// ---------------------------------------------------------------------------------------
+namespace {
+// ---------------------------------------------------------------------------------------
+// error handling
+// ---------------------------------------------------------------------------------------
+ enum BootstrapResult
+ {
+ BOOTSTRAP_DATA_OK,
+ INCOMPLETE_BOOTSTRAP_DATA,
+ INCOMPLETE_BOOTSTRAP_FILE,
+ MISSING_BOOTSTRAP_FILE,
+ BOOTSTRAP_FAILURE
+ };
+// ---------------------------------------------------------------------------------------
+ static
+ rtl::OUString getFallbackErrorMessage( BootstrapResult _rc )
+ {
+ rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM("The program cannot start. "));
+
+ switch (_rc)
+ {
+ case MISSING_BOOTSTRAP_FILE:
+ sMessage = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("A main configuration file is missing"));
+ break;
+
+ case INCOMPLETE_BOOTSTRAP_FILE:
+ sMessage = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("A main configuration file is invalid"));
+ break;
+
+ case INCOMPLETE_BOOTSTRAP_DATA:
+ sMessage = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Required bootstrap data is not available"));
+ break;
+
+ default:
+ sMessage = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unexpected bootstrap failure"));
+ break;
+
+ case BOOTSTRAP_DATA_OK:
+ break;
+ }
+ sMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" (No detailed error message available.)"));
+
+ return sMessage;
+ }
+// ---------------------------------------------------------------------------------------
+
+ static
+ uno::Any impl_makeBootstrapException( BootstrapResult _rc, rtl::OUString const& _sMessage, rtl::OUString const& _sURL, uno::Reference< uno::XInterface > _xContext )
+ {
+ rtl::OUString sMessage(_sMessage);
+ // ensure a message
+ if (sMessage.getLength()== 0)
+ {
+ OSL_ENSURE(false, "Bootstrap error message missing");
+
+ sMessage = getFallbackErrorMessage(_rc);
+ }
+
+ // raise the error
+ switch (_rc)
+ {
+ case MISSING_BOOTSTRAP_FILE:
+ return uno::makeAny( com::sun::star::configuration::MissingBootstrapFileException(sMessage, _xContext, _sURL) );
+
+ case INCOMPLETE_BOOTSTRAP_FILE:
+ return uno::makeAny( com::sun::star::configuration::InvalidBootstrapFileException(sMessage, _xContext, _sURL) );
+
+ default: OSL_ENSURE(false, "Undefined BootstrapResult code");
+ case INCOMPLETE_BOOTSTRAP_DATA:
+ case BOOTSTRAP_FAILURE:
+ return uno::makeAny( com::sun::star::configuration::CannotLoadConfigurationException(sMessage, _xContext) );
+
+ case BOOTSTRAP_DATA_OK:
+ break;
+ }
+ return uno::Any();
+ }
+// ---------------------------------------------------------------------------------------
+
+ static
+ inline
+ bool urlExists(rtl::OUString const& _sURL)
+ {
+ osl::DirectoryItem aCheck;
+ return (osl::DirectoryItem::get(_sURL,aCheck) == osl::DirectoryItem::E_None);
+ }
+// ---------------------------------------------------------------------------------------
+
+ static
+ rtl::OUString buildBootstrapError( sal_Char const* _sWhat, rtl::OUString const& _sName, sal_Char const* _sHow)
+ {
+ rtl::OUStringBuffer sMessage;
+
+ sMessage.appendAscii(RTL_CONSTASCII_STRINGPARAM("The program cannot start. "));
+ sMessage.appendAscii(_sWhat);
+ sMessage.appendAscii(RTL_CONSTASCII_STRINGPARAM(" '")).append(_sName).appendAscii(RTL_CONSTASCII_STRINGPARAM("' "));
+ sMessage.appendAscii(_sHow).appendAscii(". ");
+
+ return sMessage.makeStringAndClear();
+ }
+// ---------------------------------------------------------------------------------------
+
+ BootstrapResult getBootstrapErrorMessage(BootstrapContext const & aContext, ContextReader const & aSettings, rtl::OUString& _rMessage, rtl::OUString& _rIniFile )
+ {
+ BootstrapResult eResult = BOOTSTRAP_DATA_OK;
+
+ _rIniFile = aContext.getBootstrapURL();
+
+ if ( !urlExists(_rIniFile) )
+ {
+ _rMessage = buildBootstrapError("The configuration file ",_rIniFile.copy(1+_rIniFile.lastIndexOf('/')),"is missing");
+ eResult = MISSING_BOOTSTRAP_FILE;
+ }
+ else if (!aSettings.isUnoBackend())
+ {
+ _rMessage = buildBootstrapError("The configuration file ",_rIniFile.copy(1+_rIniFile.lastIndexOf('/')),"is for an older version of the configuration database");
+ eResult = INCOMPLETE_BOOTSTRAP_FILE;
+ }
+ else if (!aSettings.isBootstrapValid() )
+ {
+ _rMessage = buildBootstrapError("Needed information to access",rtl::OUString::createFromAscii("application"), "configuration data is missing");
+ eResult = INCOMPLETE_BOOTSTRAP_DATA;
+ }
+
+ return eResult;
+ }
+// ---------------------------------------------------------------------------------------
+} // anonymous namespace
+// ---------------------------------------------------------------------------------------
+uno::Any BootstrapContext::makeBootstrapException()
+{
+ ContextReader aReader(this);
+
+ if (aReader.isBootstrapValid()) return uno::Any();
+
+ rtl::OUString sMessage,sURL;
+
+ BootstrapResult rc = getBootstrapErrorMessage(*this,aReader,sMessage,sURL);
+
+ return impl_makeBootstrapException(rc,sMessage,sURL,*this);
+}
+// ---------------------------------------------------------------------------
+rtl::OUString SAL_CALL
+ BootstrapContext::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&k_BootstrapContextServiceInfo).getImplementationName() ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL
+ BootstrapContext::supportsService(const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&k_BootstrapContextServiceInfo).supportsService(aServiceName) ;
+}
+//------------------------------------------------------------------------------
+uno::Sequence<rtl::OUString> SAL_CALL
+ BootstrapContext::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ return ServiceInfoHelper(&k_BootstrapContextServiceInfo).getSupportedServiceNames() ;
+}
+// ---------------------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/misc/bootstrapcontext.cxx b/configmgr/source/misc/bootstrapcontext.cxx
new file mode 100644
index 000000000000..07447fe835d5
--- /dev/null
+++ b/configmgr/source/misc/bootstrapcontext.cxx
@@ -0,0 +1,417 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bootstrapcontext.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "bootstrapcontext.hxx"
+#include "datalock.hxx"
+#include <uno/current_context.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include "utility.hxx"
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+#define IMPL_ITEM_PREFIX_ "/implementations/com.sun.star.com.configuration.bootstrap.ComponentContext/"
+#define IMPL_ITEM_PASSTHRU IMPL_ITEM_PREFIX_"isPassthrough"
+#define IMPL_ITEM_BASECONTEXT IMPL_ITEM_PREFIX_"theBaseContext"
+#define A_SERVICEMANAGER "com.sun.star.lang.theServiceManager"
+// ---------------------------------------------------------------------------
+
+#define OUSTR( text ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( text ) )
+#define OU2ASCII( str ) ( rtl::OUStringToOString(str,RTL_TEXTENCODING_ASCII_US) .getStr() )
+// ---------------------------------------------------------------------------
+#if 0
+static void testComplete()
+{
+ uno::Reference< uno::XInterface > test = * new ComponentContext(uno::Reference< uno::XComponentContext >,uno::Sequence < beans::NamedValue >(),true);
+}
+#endif
+// ---------------------------------------------------------------------------
+
+ComponentContext::ComponentContext(uno::Reference< uno::XComponentContext > const & _xContext)
+: cppu::WeakComponentImplHelper3 < uno::XComponentContext, uno::XCurrentContext, lang::XServiceInfo >(UnoApiLock::getLock())
+, m_xContext(_xContext)
+, m_hBootstrapData(NULL)
+, m_xServiceManager()
+{
+}
+// ---------------------------------------------------------------------------
+
+ComponentContext::~ComponentContext()
+{
+ if (m_hBootstrapData) rtl_bootstrap_args_close(m_hBootstrapData);
+}
+// ---------------------------------------------------------------------------
+
+void ComponentContext::initialize( const rtl::OUString& _aURL )
+{
+ UnoApiLock aLock;
+
+ OSL_ASSERT(!m_hBootstrapData);
+ m_hBootstrapData = rtl_bootstrap_args_open(_aURL.pData);
+
+ uno::Reference< lang::XComponent > xOwner(m_xContext, uno::UNO_QUERY);
+
+ if (xOwner.is()) DisposingForwarder::forward(xOwner,this);
+
+ if (!m_xContext.is())
+ {
+ OSL_ENSURE(rBHelper.bDisposed,"ComponentContext::initialize - Context unexpectedly missing");
+ throw lang::DisposedException(OUSTR("Parent context has been disposed early"),*this);
+ }
+}
+// ---------------------------------------------------------------------------
+
+// ComponentHelper
+void SAL_CALL ComponentContext::disposing()
+{
+ UnoApiLock aLock;
+
+ m_xContext.clear();
+
+ if (m_hBootstrapData)
+ {
+ rtl_bootstrap_args_close(m_hBootstrapData);
+ m_hBootstrapData = NULL;
+ }
+}
+// ---------------------------------------------------------------------------
+
+rtl::OUString ComponentContext::getBootstrapURL() const
+{
+ rtl::OUString aResult;
+
+ UnoApiLock aLock;
+
+ if (m_hBootstrapData)
+ {
+ rtl_bootstrap_get_iniName_from_handle(m_hBootstrapData,&aResult.pData);
+ }
+ else
+ {
+ OSL_TRACE( "configmgr: No bootstrap data URL set");
+ }
+
+ return aResult;
+}
+// ---------------------------------------------------------------------------
+
+uno::Reference< lang::XMultiComponentFactory > SAL_CALL
+ ComponentContext::getServiceManager( )
+ throw (uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ if (!m_xServiceManager.is())
+ {
+ uno::Reference< uno::XComponentContext > xBase = basecontext();
+ if (!xBase.is())
+ throw lang::DisposedException(OUSTR("Parent context has been disposed"),*this);
+
+ uno::Reference< lang::XMultiComponentFactory > xBaseServiceManager = xBase->getServiceManager();
+ OSL_ENSURE( xBaseServiceManager.is(), "Base context has no service manager");
+
+ if (xBaseServiceManager.is())
+ {
+ // create new smgr based on delegate's one
+ m_xServiceManager.set(
+ xBaseServiceManager->createInstanceWithContext( OUSTR("com.sun.star.comp.stoc.OServiceManagerWrapper"), xBase ),
+ uno::UNO_QUERY );
+ // patch DefaultContext property of new one
+ uno::Reference< beans::XPropertySet > xProps( m_xServiceManager, uno::UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ uno::Reference< XComponentContext > xThis( this );
+ xProps->setPropertyValue( OUSTR("DefaultContext"), uno::makeAny( xThis ) );
+ }
+ else
+ OSL_ENSURE(!m_xServiceManager.is(), "Cannot set Default Context of Service Manager Wrapper: no property set");
+ }
+ }
+ return m_xServiceManager;
+}
+// ---------------------------------------------------------------------------
+
+
+// ---------------------------------------------------------------------------
+
+sal_Bool ComponentContext::isPassthrough(uno::Reference< uno::XComponentContext > const & _xContext)
+{
+ OSL_ENSURE(_xContext.is(),"Unexpected NULL context");
+ if (!_xContext.is()) return false;
+
+ sal_Bool bValue = false;
+ _xContext->getValueByName(OUSTR(IMPL_ITEM_PASSTHRU)) >>= bValue;
+ return bValue;
+}
+// ---------------------------------------------------------------------------
+
+beans::NamedValue ComponentContext::makePassthroughMarker(sal_Bool bPassthrough)
+{
+ return beans::NamedValue(OUSTR(IMPL_ITEM_PASSTHRU),uno::makeAny(bPassthrough));
+}
+// ---------------------------------------------------------------------------
+
+bool ComponentContext::lookupInContext( uno::Any & _rValue, const rtl::OUString& _aName ) const
+{
+ uno::Reference< uno::XComponentContext > xBase = basecontext();
+ if (!xBase.is())
+ throw lang::DisposedException(OUSTR("Parent context has been disposed"),const_cast<ComponentContext&>(*this));
+
+ if (_aName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM( IMPL_ITEM_BASECONTEXT )))
+ {
+ _rValue = uno::makeAny(xBase);
+ return true;
+ }
+
+ uno::Any aCtxValue = xBase->getValueByName( _aName );
+
+ if (aCtxValue.hasValue())
+ {
+ _rValue = aCtxValue;
+ return true;
+ }
+ else
+ return false;
+}
+// ---------------------------------------------------------------------------
+
+bool ComponentContext::lookupInBootstrap( uno::Any & _rValue, const rtl::OUString& _aName ) const
+{
+ UnoApiLock aLock;
+ rtl::OUString sResult;
+ if ( rtl_bootstrap_get_from_handle( m_hBootstrapData, _aName.pData, &sResult.pData, 0) )
+ {
+ _rValue <<= sResult;
+ return true;
+ }
+ else
+ return false;
+}
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+
+static const char k_TunneledContext[] = "/services/com.sun.star.configuration.bootstrap.Context";
+
+class UnoContextTunnel::Tunnel
+: public ::cppu::WeakImplHelper2< uno::XCurrentContext, lang::XUnoTunnel >
+{
+ uno::Reference< uno::XComponentContext > m_xTunneledContext;
+ uno::Reference< uno::XCurrentContext > m_xOldContext;
+ uno::Any m_aFailure;
+public:
+ Tunnel(uno::Reference< uno::XComponentContext > const & xTunneledContext, uno::Reference< uno::XCurrentContext > const & xOldContext)
+ : m_xTunneledContext(xTunneledContext)
+ , m_xOldContext(xOldContext)
+ , m_aFailure()
+ {}
+
+ virtual uno::Any SAL_CALL
+ getValueByName( const rtl::OUString& name )
+ throw (uno::RuntimeException)
+ {
+ if (name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(k_TunneledContext) ) )
+ {
+ return uno::makeAny(m_xTunneledContext);
+ }
+ else if (m_xOldContext.is())
+ {
+ return m_xOldContext->getValueByName(name);
+ }
+ else
+ {
+ return uno::Any();
+ }
+ }
+
+ virtual sal_Int64 SAL_CALL
+ getSomething( const uno::Sequence< sal_Int8 >& aIdentifier )
+ throw (uno::RuntimeException)
+ {
+ if (getTunnelId() == aIdentifier)
+ return reinterpret_cast<sal_Int64>(&m_aFailure);
+ else
+ return 0;
+ }
+
+ static uno::Any * getFailure(uno::Reference< lang::XUnoTunnel > const & xTunnel);
+
+ static uno::Sequence< sal_Int8 > getTunnelId();
+};
+// ---------------------------------------------------------------------------
+
+uno::Sequence< sal_Int8 > UnoContextTunnel::Tunnel::getTunnelId()
+{
+ static ::cppu::OImplementationId aTunnelId;
+ return aTunnelId.getImplementationId();
+}
+// ---------------------------------------------------------------------------
+
+uno::Any * UnoContextTunnel::Tunnel::getFailure(uno::Reference< lang::XUnoTunnel > const & xTunnel)
+{
+ if (xTunnel.is())
+ {
+ if (sal_Int64 nSomething = xTunnel->getSomething(getTunnelId()))
+ {
+ return reinterpret_cast<uno::Any *>(nSomething);
+ }
+ }
+ return NULL;
+}
+// ---------------------------------------------------------------------------
+
+UnoContextTunnel::UnoContextTunnel()
+: m_xOldContext( uno::getCurrentContext() )
+, m_xActiveTunnel()
+{
+}
+// ---------------------------------------------------------------------------
+
+UnoContextTunnel::~UnoContextTunnel()
+{
+ uno::setCurrentContext( m_xOldContext );
+}
+// ---------------------------------------------------------------------------
+
+void UnoContextTunnel::passthru(uno::Reference< uno::XComponentContext > const & xContext)
+{
+ OSL_ASSERT( xContext.is() );
+ if ( ComponentContext::isPassthrough(xContext) )
+ {
+ this ->tunnel(xContext);
+ }
+ else
+ {
+ this->tunnel(NULL);
+ }
+}
+// ---------------------------------------------------------------------------
+
+void UnoContextTunnel::tunnel(uno::Reference< uno::XComponentContext > const & xContext)
+{
+ Tunnel * pNewTunnel = new Tunnel(xContext,m_xOldContext);
+ m_xActiveTunnel = pNewTunnel;
+ uno::setCurrentContext( pNewTunnel );
+}
+// ---------------------------------------------------------------------------
+
+uno::Reference< uno::XComponentContext > UnoContextTunnel::recoverContext(uno::Reference< uno::XComponentContext > const & xFallback )
+{
+ try
+ {
+ uno::Reference< uno::XCurrentContext > const xCurrContext = uno::getCurrentContext();
+
+ if (xCurrContext.is())
+ {
+ rtl::OUString aName(RTL_CONSTASCII_USTRINGPARAM(k_TunneledContext));
+ uno::Reference< uno::XComponentContext > xResult;
+ if (xCurrContext->getValueByName(aName) >>= xResult)
+ {
+ if (xResult.is())
+ return xResult;
+ }
+ else
+ {
+ OSL_ASSERT( !xResult.is() );
+ OSL_ENSURE( !xCurrContext->getValueByName(aName).hasValue(),
+ "Value in context has wrong type");
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ OSL_ENSURE(false, "Unexpected: Exception from accessing current context");
+ }
+
+ return xFallback;
+}
+// ---------------------------------------------------------------------------
+
+uno::Any UnoContextTunnel::recoverFailure(bool bRaise)
+{
+ if (uno::Any * pFail = UnoContextTunnel::Tunnel::getFailure(m_xActiveTunnel))
+ {
+ if (bRaise)
+ {
+ if (pFail->hasValue())
+ cppu::throwException(*pFail);
+ else
+ throw;
+ }
+ return *pFail;
+ }
+
+ return uno::Any();
+}
+// ---------------------------------------------------------------------------
+
+bool UnoContextTunnel::tunnelFailure(uno::Any const & aException, bool bRaise)
+{
+ OSL_ASSERT( !aException.hasValue() || aException.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+
+ uno::Reference< lang::XUnoTunnel > xTunnel( uno::getCurrentContext(), uno::UNO_QUERY );
+
+ if (uno::Any * pFail = Tunnel::getFailure(xTunnel))
+ {
+ *pFail = aException;
+
+ if (bRaise && aException.hasValue())
+ cppu::throwException(aException);
+
+ if (bRaise) throw;
+ return true;
+ }
+ else
+ {
+ if (bRaise) throw;
+ return false;
+ }
+}
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+void DisposingForwarder::disposing( lang::EventObject const & /*rSource*/ )
+throw (uno::RuntimeException)
+{
+ m_xTarget->dispose();
+ m_xTarget.clear();
+}
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+} // namespace config
+
+
diff --git a/configmgr/source/misc/bufferedfile.cxx b/configmgr/source/misc/bufferedfile.cxx
new file mode 100644
index 000000000000..a3170bbde833
--- /dev/null
+++ b/configmgr/source/misc/bufferedfile.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bufferedfile.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <string.h>
+#include "bufferedfile.hxx"
+
+#include "filehelper.hxx"
+
+#include <algorithm>
+
+
+namespace configmgr
+{
+
+BufferedOutputFile::BufferedOutputFile( rtl::OUString const& aFileURL, sal_uInt32 nBufferSizeHint )
+: m_pFile(new osl::File(aFileURL))
+, m_buffer()
+{
+ m_buffer.reserve( nBufferSizeHint ? nBufferSizeHint : 512 );
+}
+
+BufferedOutputFile::~BufferedOutputFile ()
+{
+ delete m_pFile;
+}
+
+
+BufferedOutputFile::RC BufferedOutputFile::open( sal_uInt32 uFlags )
+{
+ if (!m_pFile) return E_BADF;
+
+ return m_pFile->open(uFlags);
+}
+
+BufferedOutputFile::RC BufferedOutputFile::close()
+{
+ if (!m_pFile) return E_BADF;
+
+ RC rc = this->sync();
+ RC rc2 = m_pFile->close();
+
+ delete m_pFile, m_pFile = 0;
+ if (rc == E_None)
+ rc = rc2;
+ return rc;
+}
+
+
+//BufferedOutputFile::RC BufferedOutputFile::getPos( sal_uInt64& uPos )
+
+BufferedOutputFile::RC BufferedOutputFile::write(const void *pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64& rBytesWritten)
+{
+ if (!m_pFile) return E_BADF;
+
+ if (uBytesToWrite > m_buffer.max_size()-m_buffer.size())
+ {
+ // write big chunks natively
+ RC rc = this->sync();
+ if (rc == E_None)
+ {
+ OSL_ASSERT(m_buffer.empty());
+ rc = m_pFile->write(pBuffer, uBytesToWrite, rBytesWritten);
+ }
+ return rc;
+ }
+
+ // FIXME: handle out-out-memory here
+ const sal_uInt8 * data = static_cast<const sal_uInt8 *>(pBuffer);
+ m_buffer.insert(m_buffer.end(), data, data + uBytesToWrite);
+ rBytesWritten = uBytesToWrite;
+
+ return E_None;
+}
+
+BufferedOutputFile::RC BufferedOutputFile::sync()
+{
+ if (!m_pFile) return E_BADF;
+
+ sal_uInt64 size = m_buffer.size();
+ sal_uInt64 written = 0;
+
+ RC rc = m_pFile->write(&m_buffer.front(),size,written);
+
+ if (rc != E_None)
+ return rc;
+
+ // we don't support special files where multiple write passes are needed
+ if (written < size)
+ {
+ // but we try our best to stay consistent
+ m_buffer.erase(m_buffer.begin(),
+ m_buffer.end() + sal::static_int_cast<sal_uInt32>( written ));
+
+ return E_IO;
+ }
+
+ m_buffer.clear();
+
+ return E_None;
+}
+
+} // namespace configmgr
+
diff --git a/configmgr/source/misc/configinteractionhandler.cxx b/configmgr/source/misc/configinteractionhandler.cxx
new file mode 100644
index 000000000000..34ca0e505e9a
--- /dev/null
+++ b/configmgr/source/misc/configinteractionhandler.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configinteractionhandler.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "sal/config.h"
+
+#include "configinteractionhandler.hxx"
+
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/XCurrentContext.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "rtl/string.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "uno/current_context.hxx"
+
+namespace {
+
+namespace css = com::sun::star;
+
+static char const INTERACTION_HANDLER[] = "configuration.interaction-handler";
+
+}
+
+namespace configmgr { namespace apihelper {
+
+class ConfigurationInteractionHandler::Context:
+ public cppu::WeakImplHelper1< css::uno::XCurrentContext >
+{
+public:
+ explicit Context(ConfigurationInteractionHandler * parent):
+ m_parent(parent) {}
+
+ virtual css::uno::Any SAL_CALL getValueByName(rtl::OUString const & name)
+ throw (css::uno::RuntimeException)
+ {
+ return
+ name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(INTERACTION_HANDLER))
+ ? m_handler : m_parent->getPreviousContextValue(name);
+ }
+
+ void setInteractionHandler(
+ css::uno::Reference< css::task::XInteractionHandler > const & handler)
+ { m_handler <<= handler; }
+
+private:
+ Context(Context &); // not defined
+ void operator =(Context &); // not defined
+
+ virtual ~Context() {}
+
+ ConfigurationInteractionHandler * m_parent;
+ css::uno::Any m_handler;
+};
+
+ConfigurationInteractionHandler::ConfigurationInteractionHandler():
+ m_context(new Context(this)), m_layer(m_context.get()) {}
+
+ConfigurationInteractionHandler::~ConfigurationInteractionHandler() {}
+
+css::uno::Reference< css::task::XInteractionHandler >
+ConfigurationInteractionHandler::get() const {
+ return css::uno::Reference< css::task::XInteractionHandler >(
+ getPreviousContextValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(INTERACTION_HANDLER))),
+ css::uno::UNO_QUERY);
+}
+
+void ConfigurationInteractionHandler::setRecursive(
+ css::uno::Reference< css::task::XInteractionHandler > const & handler)
+{
+ m_context->setInteractionHandler(handler);
+}
+
+css::uno::Any ConfigurationInteractionHandler::getPreviousContextValue(
+ rtl::OUString const & name) const
+{
+ css::uno::Reference< css::uno::XCurrentContext > c(
+ m_layer.getPreviousContext());
+ return c.is() ? c->getValueByName(name) : css::uno::Any();
+}
+
+} }
diff --git a/configmgr/source/misc/configunoreg.cxx b/configmgr/source/misc/configunoreg.cxx
new file mode 100644
index 000000000000..203acca20479
--- /dev/null
+++ b/configmgr/source/misc/configunoreg.cxx
@@ -0,0 +1,389 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configunoreg.cxx,v $
+ * $Revision: 1.33 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+
+#include "confapifactory.hxx"
+#include "serviceinfohelper.hxx"
+#include <cppuhelper/factory.hxx>
+#include <rtl/ustrbuf.hxx>
+
+// ***************************************************************************************
+//
+// Die vorgeschriebene C-Api muss erfuellt werden!
+// Sie besteht aus drei Funktionen, die von dem Modul exportiert werden muessen.
+//
+
+//---------------------------------------------------------------------------------------
+void RegisterService(
+ const configmgr::ServiceRegistrationInfo* pInfo,
+ const com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > & xKey)
+{
+ if (pInfo == 0 || pInfo->registeredServiceNames==0 || pInfo->implementationName==0)
+ return;
+
+ rtl::OUStringBuffer aMainKeyName;
+ aMainKeyName.appendAscii("/");
+ aMainKeyName.appendAscii(pInfo->implementationName);
+ aMainKeyName.appendAscii("/UNO/SERVICES");
+
+ com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > xNewKey( xKey->createKey(aMainKeyName.makeStringAndClear()) );
+ OSL_ENSURE(xNewKey.is(), "CONFMGR::component_writeInfo : could not create a registry key !");
+
+ for(sal_Char const * const* p = pInfo->registeredServiceNames ; *p; ++p)
+ {
+ xNewKey->createKey(rtl::OUString::createFromAscii(*p));
+ }
+}
+
+//---------------------------------------------------------------------------------------
+
+void RegisterSingleton(
+ const configmgr::SingletonRegistrationInfo* pInfo,
+ const com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > & xKey)
+{
+ if (pInfo == 0 || pInfo->singletonName ==0 ||
+ pInfo->implementationName ==0 ||
+ pInfo->instantiatedServiceName ==0 )
+ return;
+
+ rtl::OUStringBuffer aSingletonKeyName;
+ aSingletonKeyName.appendAscii("/");
+ aSingletonKeyName.appendAscii(pInfo->implementationName);
+ aSingletonKeyName.appendAscii("/UNO/SINGLETONS/");
+ aSingletonKeyName.appendAscii(pInfo->singletonName);
+
+ com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > xNewKey( xKey->createKey(aSingletonKeyName.makeStringAndClear()) );
+ OSL_ENSURE(xNewKey.is(), "CONFMGR::component_writeInfo : could not create a registry key !");
+
+ xNewKey->setStringValue(rtl::OUString::createFromAscii(pInfo->instantiatedServiceName));
+
+ if (pInfo->mappedImplementation != 0)
+ RegisterService(pInfo->mappedImplementation,xKey);
+}
+
+
+//-----------------------------------------------------------------------------
+struct ServiceImplementationRequest
+{
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > xRet;
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > const m_xServiceManager;
+ rtl::OUString const sImplementationName;
+
+ //-------------------------------------------------------------------------
+ ServiceImplementationRequest(
+ void* pServiceManager,
+ sal_Char const* pImplementationName
+ )
+ : m_xServiceManager(reinterpret_cast<com::sun::star::lang::XMultiServiceFactory*>(pServiceManager))
+ , sImplementationName(rtl::OUString::createFromAscii(pImplementationName))
+ {
+ }
+ //-------------------------------------------------------------------------
+ inline
+ sal_Bool shouldCreate(const configmgr::ServiceRegistrationInfo* pInfo) const
+ {
+ OSL_ENSURE(!xRet.is(), "CreateProvider : invalid creation request: we already have a return value !");
+ return !xRet.is() &&
+ pInfo != 0 &&
+ 0 == sImplementationName.compareToAscii(pInfo->implementationName);
+ }
+
+ //-------------------------------------------------------------------------
+
+ sal_Bool CreateProviderFactory(
+ const configmgr::ServiceRegistrationInfo* pInfo,
+ bool bAdmin
+ )
+ {
+ if (this->shouldCreate(pInfo))
+ try
+ {
+ configmgr::ServiceRegistrationHelper aInfo(pInfo);
+
+ const com::sun::star::uno::Sequence< rtl::OUString > Services= aInfo.getRegisteredServiceNames();
+
+ xRet = configmgr::createProviderFactory( aInfo.getImplementationName(), bAdmin);
+
+ OSL_ENSURE(xRet.is(), "CreateProvider : WHERE IS THE return value !");
+ }
+ catch(com::sun::star::uno::Exception&)
+ {
+ }
+ return xRet.is();
+ }
+
+ //-------------------------------------------------------------------------
+
+ sal_Bool CreateServiceFactory(
+ const configmgr::ServiceRegistrationInfo* pInfo,
+ ::cppu::ComponentFactoryFunc Factory
+ )
+ {
+ if (this->shouldCreate(pInfo))
+ try
+ {
+ configmgr::ServiceRegistrationHelper aInfo(pInfo);
+
+ const com::sun::star::uno::Sequence< rtl::OUString > Services= aInfo.getRegisteredServiceNames();
+
+ xRet = cppu::createSingleComponentFactory( Factory, aInfo.getImplementationName(), Services, 0);
+
+ OSL_ENSURE(xRet.is(), "CreateProvider : WHERE IS THE return value !");
+ }
+ catch(com::sun::star::uno::Exception&)
+ {
+ }
+ return xRet.is();
+ }
+
+ //-------------------------------------------------------------------------
+
+ sal_Bool CreateSingletonMapperFactory(
+ const configmgr::SingletonRegistrationInfo* pInfo,
+ ::cppu::ComponentFactoryFunc Mapper
+ )
+ {
+ OSL_ENSURE(pInfo && pInfo->mappedImplementation, "CreateProvider : Cannot map unmapped singleton !");
+
+ return pInfo && pInfo->mappedImplementation &&
+ CreateServiceFactory(pInfo->mappedImplementation,Mapper);
+ }
+
+ //-------------------------------------------------------------------------
+ void* getService() const
+ {
+ // we want to transport the interface pointer as flat C void pointer, so this prevents deletion
+ if (xRet.is())
+ xRet->acquire();
+
+ return xRet.get();
+ }
+};
+
+//---------------------------------------------------------------------------------------
+
+extern "C" SAL_DLLPUBLIC_EXPORT
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char **ppEnvTypeName,
+ uno_Environment ** /* ppEnv */
+ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//---------------------------------------------------------------------------------------
+extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(
+ void* /* pServiceManager */,
+ void* pRegistryKey
+ )
+{
+ if (pRegistryKey)
+ try
+ {
+ com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > xKey(reinterpret_cast<com::sun::star::registry::XRegistryKey*>(pRegistryKey));
+
+ // configuration access entry points: configuration provider
+ RegisterSingleton(configmgr::getDefaultProviderSingletonInfo(), xKey) ;
+
+ RegisterService(configmgr::getConfigurationProviderServiceInfo(), xKey);
+ RegisterService(configmgr::getDefaultProviderServiceInfo(), xKey);
+ RegisterService(configmgr::getAdminProviderServiceInfo(), xKey);
+
+ // registry wrapper (deprecated)
+ RegisterService(configmgr::getConfigurationRegistryServiceInfo(), xKey);
+
+ // updating
+ RegisterService(configmgr::backend::getUpdateMergerServiceInfo(), xKey);
+
+ // xml handling
+ RegisterService(configmgr::xml::getSchemaParserServiceInfo(), xKey);
+ RegisterService(configmgr::xml::getLayerParserServiceInfo(), xKey);
+ RegisterService(configmgr::xml::getLayerWriterServiceInfo(), xKey);
+
+ // bootstrap handling
+ RegisterSingleton(configmgr::getBootstrapContextSingletonInfo(), xKey) ;
+ RegisterService(configmgr::getBootstrapContextServiceInfo(), xKey) ;
+
+ // backend singletons
+ RegisterSingleton(configmgr::backend::getDefaultBackendSingletonInfo(), xKey) ;
+
+ // backends
+ RegisterService(configmgr::backend::getDefaultBackendServiceInfo(), xKey) ;
+ RegisterService(configmgr::backend::getSingleBackendAdapterServiceInfo(), xKey) ;
+ RegisterService(configmgr::backend::getMultiStratumBackendServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalBackendServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalDataImportServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalHierarchyBrowserServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalSchemaSupplierServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalLegacyStratumServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalDataStratumServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalReadonlyStratumServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalResourceStratumServiceInfo(), xKey) ;
+ RegisterService(configmgr::localbe::getLocalMultiStratumServiceInfo(), xKey) ;
+
+ // im/export
+ RegisterService(configmgr::backend::getMergeImportServiceInfo(), xKey);
+ RegisterService(configmgr::backend::getCopyImportServiceInfo(), xKey);
+
+ return sal_True;
+ }
+ catch (::com::sun::star::registry::InvalidRegistryException& )
+ {
+ OSL_ENSURE(sal_False, "configmgr: component_writeInfo : could not create a registry key ! ## InvalidRegistryException !");
+ }
+
+ return sal_False;
+}
+
+//---------------------------------------------------------------------------------------
+extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory(
+ const sal_Char* pImplementationName,
+ void* pServiceManager,
+ void* /*pRegistryKey*/)
+{
+ void* pRet = 0;
+ if (pServiceManager)
+ {
+ ServiceImplementationRequest aReq(pServiceManager,pImplementationName);
+
+ // configuration access entry points: configuration provider
+ aReq.CreateProviderFactory(
+ configmgr::getConfigurationProviderServiceInfo(),
+ false)
+ ||
+ aReq.CreateProviderFactory(
+ configmgr::getAdminProviderServiceInfo(),
+ true)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::getDefaultProviderServiceInfo(),
+ &configmgr::instantiateDefaultProvider)
+ ||
+ // registry wrapper (deprecated)
+ aReq.CreateServiceFactory(
+ configmgr::getConfigurationRegistryServiceInfo(),
+ &configmgr::instantiateConfigRegistry)
+ ||
+ // updating
+ aReq.CreateServiceFactory(
+ configmgr::backend::getUpdateMergerServiceInfo(),
+ &configmgr::backend::instantiateUpdateMerger)
+ ||
+ // xml handling
+ aReq.CreateServiceFactory(
+ configmgr::xml::getSchemaParserServiceInfo(),
+ &configmgr::xml::instantiateSchemaParser)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::xml::getLayerParserServiceInfo(),
+ &configmgr::xml::instantiateLayerParser)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::xml::getLayerWriterServiceInfo(),
+ &configmgr::xml::instantiateLayerWriter)
+ ||
+ // bootstrap handling
+ aReq.CreateServiceFactory(
+ configmgr::getBootstrapContextServiceInfo(),
+ &configmgr::instantiateBootstrapContext)
+ ||
+ // backend singletons
+ aReq.CreateSingletonMapperFactory(
+ configmgr::backend::getDefaultBackendSingletonInfo(),
+ configmgr::backend::getDefaultBackendSingleton)
+ ||
+ // backends
+ aReq.CreateServiceFactory(
+ configmgr::backend::getDefaultBackendServiceInfo(),
+ configmgr::backend::instantiateDefaultBackend)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::backend::getSingleBackendAdapterServiceInfo(),
+ configmgr::backend::instantiateSingleBackendAdapter)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::backend::getMultiStratumBackendServiceInfo(),
+ configmgr::backend::instantiateMultiStratumBackend)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalBackendServiceInfo(),
+ configmgr::localbe::instantiateLocalBackend)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalDataImportServiceInfo(),
+ configmgr::localbe::instantiateLocalDataImporter)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalHierarchyBrowserServiceInfo(),
+ configmgr::localbe::instantiateLocalHierarchyBrowser)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalSchemaSupplierServiceInfo(),
+ configmgr::localbe::instantiateLocalSchemaSupplier)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalLegacyStratumServiceInfo(),
+ configmgr::localbe::instantiateLocalLegacyStratum)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalDataStratumServiceInfo(),
+ configmgr::localbe::instantiateLocalDataStratum)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalReadonlyStratumServiceInfo(),
+ configmgr::localbe::instantiateLocalReadonlyStratum)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalResourceStratumServiceInfo(),
+ configmgr::localbe::instantiateLocalResourceStratum)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::localbe::getLocalMultiStratumServiceInfo(),
+ configmgr::localbe::instantiateLocalMultiStratum)
+ ||
+ // im/export
+ aReq.CreateServiceFactory(
+ configmgr::backend::getMergeImportServiceInfo(),
+ &configmgr::backend::instantiateMergeImporter)
+ ||
+ aReq.CreateServiceFactory(
+ configmgr::backend::getCopyImportServiceInfo(),
+ &configmgr::backend::instantiateCopyImporter);
+
+ pRet = aReq.getService();
+ }
+
+ return pRet;
+}
+//---------------------------------------------------------------------------------------
+
diff --git a/configmgr/source/misc/filehelper.cxx b/configmgr/source/misc/filehelper.cxx
new file mode 100644
index 000000000000..ffa1302c6cac
--- /dev/null
+++ b/configmgr/source/misc/filehelper.cxx
@@ -0,0 +1,390 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: filehelper.cxx,v $
+ * $Revision: 1.19 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+
+#ifndef _RTL_USTRING_H_
+#include <rtl/ustring.hxx>
+#endif
+#include <osl/file.hxx>
+#include "filehelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+
+#define ASCII(x) rtl::OUString::createFromAscii(x)
+
+namespace configmgr
+{
+ //==========================================================================
+ //= FileHelper
+ //==========================================================================
+
+ // -----------------------------------------------------------------------------
+ bool FileHelper::tryToRemoveFile(const rtl::OUString& _aURL, bool tryBackupFirst)
+ {
+ if (tryBackupFirst)
+ {
+ rtl::OUString aBakURL = _aURL.concat( ASCII(".bak") );
+ osl::File::RC eBakError = osl::File::move(_aURL,aBakURL);
+ if (eBakError == osl::File::E_None)
+ return true;
+ }
+ osl::File::RC eError = osl::File::remove(_aURL);
+ return eError == osl::File::E_None || eError == osl::File::E_NOENT;
+ }
+ // -----------------------------------------------------------------------------
+ void FileHelper::replaceFile(
+ const rtl::OUString& _aToURL, const rtl::OUString &_aFromURL) SAL_THROW((io::IOException))
+ {
+ osl::File::remove(_aToURL);
+ osl::File::RC eError = osl::File::move(_aFromURL, _aToURL);
+ if (eError != osl::File::E_None &&
+ eError != osl::File::E_NOENT)
+ {
+ rtl::OUStringBuffer sErrorBuf;
+ sErrorBuf.appendAscii("Configmgr: replaceFile failed ");
+ sErrorBuf.appendAscii("for replacing file \"").append(_aFromURL).appendAscii("\". ");
+ sErrorBuf.appendAscii("by file \"").append(_aToURL).appendAscii("\". ");
+ sErrorBuf.appendAscii("Error = \"").append(FileHelper::createOSLErrorString(eError)).appendAscii("\" ");
+ sErrorBuf.appendAscii("[").append(sal_Int32(eError)).appendAscii("] ");
+
+ rtl::OUString const sError = sErrorBuf.makeStringAndClear();
+ OSL_ENSURE(0, rtl::OUStringToOString(sError,RTL_TEXTENCODING_ASCII_US).getStr());
+ throw io::IOException(sError, NULL);
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ bool FileHelper::fileExists(rtl::OUString const& _sFileURL)
+ {
+ osl::DirectoryItem aItem;
+ return osl::DirectoryItem::get(_sFileURL, aItem) == osl::Directory::E_None;
+ }
+
+ // -----------------------------------------------------------------------------
+ bool FileHelper::dirExists(rtl::OUString const& _sDirURL)
+ {
+ return osl::Directory(_sDirURL).open() == osl::Directory::E_None;
+ }
+
+ // -----------------------------------------------------------------------------
+ sal_uInt64 FileHelper::getModifyStatus(rtl::OUString const& _sURL, TimeValue & rModifyTime)
+ {
+ static const TimeValue k_NullTime = {0,0};
+ sal_uInt64 aSize = 0;
+ rModifyTime = k_NullTime;
+
+ osl::DirectoryItem aItem;
+ if (osl::FileBase::E_None == osl::DirectoryItem::get(_sURL, aItem))
+ {
+ osl::FileStatus aStatus(osl_FileStatus_Mask_ModifyTime|osl_FileStatus_Mask_Type|osl_FileStatus_Mask_FileSize);
+ if (osl::FileBase::E_None == aItem.getFileStatus(aStatus))
+ {
+ if (aStatus.isValid(osl_FileStatus_Mask_ModifyTime))
+ rModifyTime = aStatus.getModifyTime();
+
+ if (aStatus.isValid(osl_FileStatus_Mask_FileSize))
+ aSize = aStatus.getFileSize();
+ }
+ }
+ return aSize;
+ }
+
+ // -----------------------------------------------------------------------------
+ rtl::OUString FileHelper::createOSLErrorString(osl::FileBase::RC eError)
+ {
+ rtl::OUString aRet;
+ switch(eError)
+ {
+ case osl::FileBase::E_None:
+ break;
+
+ case osl::FileBase::E_PERM:
+ aRet = ASCII("Operation not permitted");
+ break;
+
+ case osl::FileBase::E_NOENT:
+ aRet = ASCII("No such file or directory");
+ break;
+
+ case osl::FileBase::E_SRCH:
+ aRet = ASCII("unknown error: osl_File_E_SRCH");
+ break;
+
+ case osl::FileBase::E_INTR:
+ aRet = ASCII("function call was interrupted");
+ break;
+
+ case osl::FileBase::E_IO:
+ aRet = ASCII("I/O error");
+ break;
+
+ case osl::FileBase::E_NXIO:
+ aRet = ASCII("No such device or address");
+ break;
+
+ case osl::FileBase::E_2BIG:
+ aRet = ASCII("unknown error: osl_File_E_2BIG");
+ break;
+
+ case osl::FileBase::E_NOEXEC:
+ aRet = ASCII("unknown error: osl_File_E_NOEXEC");
+ break;
+
+ case osl::FileBase::E_BADF:
+ aRet = ASCII("Bad file");
+ break;
+
+ case osl::FileBase::E_CHILD:
+ aRet = ASCII("unknown error: osl_File_E_CHILD");
+ break;
+
+ case osl::FileBase::E_AGAIN:
+ aRet = ASCII("Operation would block");
+ break;
+
+ case osl::FileBase::E_NOMEM:
+ aRet = ASCII("not enough memory for allocating structures");
+ break;
+
+ case osl::FileBase::E_ACCES:
+ aRet = ASCII("Permission denied");
+ break;
+
+ case osl::FileBase::E_FAULT:
+ aRet = ASCII("Bad address");
+ break;
+
+ case osl::FileBase::E_BUSY:
+ aRet = ASCII("Text file busy");
+ break;
+
+ case osl::FileBase::E_EXIST:
+ aRet = ASCII("File exists");
+ break;
+
+ case osl::FileBase::E_XDEV:
+ aRet = ASCII("unknown error: osl_File_E_XDEV");
+ break;
+
+ case osl::FileBase::E_NODEV:
+ aRet = ASCII("No such device");
+ break;
+
+ case osl::FileBase::E_NOTDIR:
+ aRet = ASCII("Not a directory");
+ break;
+
+ case osl::FileBase::E_ISDIR:
+ aRet = ASCII("Is a director");
+ break;
+
+ case osl::FileBase::E_INVAL:
+ aRet = ASCII("the format of the parameters was not valid");
+ break;
+
+ case osl::FileBase::E_NFILE:
+ aRet = ASCII("too many open files in the system");
+ break;
+
+ case osl::FileBase::E_MFILE:
+ aRet = ASCII("too many open files used by the process");
+ break;
+
+ case osl::FileBase::E_NOTTY:
+ aRet = ASCII("unknown error: osl_File_E_NOTTY");
+ break;
+
+ case osl::FileBase::E_FBIG:
+ aRet = ASCII("File too large");
+ break;
+
+ case osl::FileBase::E_NOSPC:
+ aRet = ASCII("No space left on device");
+ break;
+
+ case osl::FileBase::E_SPIPE:
+ aRet = ASCII("unknown error: osl_File_E_SPIPE");
+ break;
+
+ case osl::FileBase::E_ROFS:
+ aRet = ASCII("Read-only file system");
+ break;
+
+ case osl::FileBase::E_MLINK:
+ aRet = ASCII("Too many links");
+ break;
+
+ case osl::FileBase::E_PIPE:
+ aRet = ASCII("unknown error: osl_File_E_PIPE");
+ break;
+
+ case osl::FileBase::E_DOM:
+ aRet = ASCII("unknown error: osl_File_E_DOM");
+ break;
+
+ case osl::FileBase::E_RANGE:
+ aRet = ASCII("unknown error: osl_File_E_RANGE");
+ break;
+
+ case osl::FileBase::E_DEADLK:
+ aRet = ASCII("unknown error: osl_File_E_DEADLK");
+ break;
+
+ case osl::FileBase::E_NAMETOOLONG:
+ aRet = ASCII("File name too long");
+ break;
+
+ case osl::FileBase::E_NOLCK:
+ aRet = ASCII("No record locks available");
+ break;
+
+ case osl::FileBase::E_NOSYS:
+ aRet = ASCII("Function not implemente");
+ break;
+
+ case osl::FileBase::E_NOTEMPTY:
+ aRet = ASCII("Directory not empt");
+ break;
+
+ case osl::FileBase::E_LOOP:
+ aRet = ASCII("Too many symbolic links encountered");
+ break;
+
+ case osl::FileBase::E_ILSEQ:
+ aRet = ASCII("unknown error: osl_File_E_ILSEQ");
+ break;
+
+ case osl::FileBase::E_NOLINK:
+ aRet = ASCII("Link has been severed");
+ break;
+
+ case osl::FileBase::E_MULTIHOP:
+ aRet = ASCII("Multihop attempted");
+ break;
+
+ case osl::FileBase::E_USERS:
+ aRet = ASCII("unknown error: osl_File_E_USERS");
+ break;
+
+ case osl::FileBase::E_OVERFLOW:
+ aRet = ASCII("Value too large for defined data type");
+ break;
+
+ /* unmapped error: always last entry in enum! */
+ default: OSL_ENSURE(false, "Found unknown OSL File Error");
+ case osl::FileBase::E_invalidError:
+ aRet = ASCII("unmapped Error");
+ break;
+ }
+ return aRet;
+ }
+
+ // -----------------------------------------------------------------------------
+ rtl::OUString FileHelper::getParentDir(rtl::OUString const& _sURL)
+ {
+ rtl::OUString parentDirectory ;
+ rtl::OUString fileName ;
+
+ splitFileUrl(_sURL, parentDirectory, fileName) ;
+ return parentDirectory ;
+ }
+
+ // -----------------------------------------------------------------------------
+ void FileHelper::splitFileUrl(const rtl::OUString& aFileUrl,
+ rtl::OUString& aParentDirectory,
+ rtl::OUString& aFileName) {
+ // goto last '/' and cut the rest.
+ sal_Int32 nIdx = aFileUrl.lastIndexOf(delimiter, aFileUrl.getLength());
+ if (nIdx > 0) {
+ aParentDirectory = aFileUrl.copy(0, nIdx);
+ aFileName = aFileUrl.copy(nIdx + 1) ;
+ }
+ else {
+ aParentDirectory = rtl::OUString() ;
+ aFileName = aFileUrl ;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ rtl::OUString FileHelper::getFileName(const rtl::OUString& aFileUrl) {
+ rtl::OUString parentDirectory ;
+ rtl::OUString fileName ;
+
+ splitFileUrl(aFileUrl, parentDirectory, fileName) ;
+ return fileName ;
+ }
+ // -----------------------------------------------------------------------------
+ osl::FileBase::RC FileHelper::mkdir(rtl::OUString const& _sDirURL)
+ {
+ // direct create a directory
+ osl::FileBase::RC eError = osl::Directory::create(_sDirURL); // try to create the directory
+ if (eError == osl::FileBase::E_EXIST ||
+ eError == osl::FileBase::E_None ||
+ FileHelper::dirExists(_sDirURL))
+ {
+ eError = osl::FileBase::E_None; // Exists or created
+ }
+ return eError;
+ }
+
+ // -----------------------------------------------------------------------------
+ osl::FileBase::RC FileHelper::mkdirs(rtl::OUString const& _sDirURL)
+ {
+ osl::FileBase::RC eError = mkdir(_sDirURL);
+ switch (eError)
+ {
+ case osl::FileBase::E_EXIST: OSL_ASSERT(false);
+ case osl::FileBase::E_None:
+ break;
+
+ case osl::FileBase::E_NOENT:
+ {
+ rtl::OUString sParentDir = FileHelper::getParentDir(_sDirURL);
+ if (sParentDir.getLength() == 0)
+ break;
+
+ eError = mkdirs(sParentDir);
+ if (eError != osl::FileBase::E_None)
+ break;
+
+ eError = mkdir(_sDirURL);
+ }
+ break;
+
+ default: OSL_TRACE("configmgr: Could not create directory (%d).", int(eError));
+ break;
+ }
+ return eError;
+ }
+
+} // namespace configmgr
diff --git a/configmgr/source/misc/interactionrequest.cxx b/configmgr/source/misc/interactionrequest.cxx
new file mode 100644
index 000000000000..b5f32ff9cf17
--- /dev/null
+++ b/configmgr/source/misc/interactionrequest.cxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: interactionrequest.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "interactionrequest.hxx"
+
+namespace configmgr {
+namespace apihelper {
+ namespace uno = com::sun::star::uno;
+ namespace task = com::sun::star::task;
+//=========================================================================
+//=========================================================================
+//
+// InteractionRequest Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+struct InteractionRequest::Impl
+{
+ uno::Reference< task::XInteractionContinuation > m_xSelection;
+ uno::Any m_aRequest;
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > m_aContinuations;
+
+ Impl() {}
+ Impl( const uno::Any & rRequest )
+ : m_aRequest( rRequest )
+ {}
+};
+
+//=========================================================================
+InteractionRequest::InteractionRequest( const uno::Any & rRequest )
+: m_pImpl( new Impl( rRequest ) )
+{
+}
+
+//=========================================================================
+// virtual
+InteractionRequest::~InteractionRequest()
+{
+ delete m_pImpl;
+}
+
+//=========================================================================
+void InteractionRequest::setContinuations(
+ const uno::Sequence< uno::Reference<
+ task::XInteractionContinuation > > & rContinuations )
+{
+ m_pImpl->m_aContinuations = rContinuations;
+}
+
+//=========================================================================
+uno::Reference< task::XInteractionContinuation > InteractionRequest::getSelection() const
+{
+ return m_pImpl->m_xSelection;
+}
+
+//=========================================================================
+void InteractionRequest::setSelection( const uno::Reference< task::XInteractionContinuation > & rxSelection )
+{
+ m_pImpl->m_xSelection = rxSelection;
+}
+
+//=========================================================================
+//
+// XInteractionRequest methods.
+//
+//=========================================================================
+
+// virtual
+uno::Any SAL_CALL InteractionRequest::getRequest()
+ throw( uno::RuntimeException )
+{
+ return m_pImpl->m_aRequest;
+}
+
+//=========================================================================
+// virtual
+uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL
+ InteractionRequest::getContinuations()
+ throw( uno::RuntimeException )
+{
+ return m_pImpl->m_aContinuations;
+}
+
+//=========================================================================
+
+} // namespace apihelper
+} // namespace configmgr
diff --git a/configmgr/source/misc/logger.cxx b/configmgr/source/misc/logger.cxx
new file mode 100644
index 000000000000..40a282265c97
--- /dev/null
+++ b/configmgr/source/misc/logger.cxx
@@ -0,0 +1,96 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: logger.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "logger.hxx"
+
+#define CONFIG_LOGGER_SINGLETON "/singletons/com.sun.star.configuration.theLogger"
+#define OUSTR( lit ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( lit ) )
+#define OU2A( ustr ) rtl::OUStringToOString( ustr, RTL_TEXTENCODING_UTF8 ).getStr()
+#define A2OU( astr ) rtl::OUString::createFromAscii( astr )
+
+static const sal_Char k_unspecifiedClass[] = "configmgr";
+static const sal_Char k_unspecifiedMethod[] = "log-message";
+
+namespace configmgr
+{
+
+//--------------------------------------------------------------------------
+void Logger::log(sal_Int32 nLevel, const char * msg, const char * sourceMethod, const char * sourceClass) const
+{
+ OSL_ASSERT(msg);
+ if (!msg) msg = "";
+
+ this->log(nLevel,A2OU(msg),sourceMethod,sourceClass);
+}
+
+//--------------------------------------------------------------------------
+void Logger::log(sal_Int32 nLevel, const rtl::OUString & msg, const char * sourceMethod, const char * sourceClass) const
+{
+ if (!sourceClass) sourceClass = k_unspecifiedClass;
+ if (!sourceMethod) sourceMethod = k_unspecifiedMethod;
+
+ // this place can be used to further enrich or instrument log output
+ if (m_xLogger.is())
+ try
+ {
+ m_xLogger->logp(nLevel,A2OU(sourceClass),A2OU(sourceMethod),msg);
+ }
+ catch (uno::Exception & e)
+ {
+ OSL_TRACE("Configuration Log failure: %s\n"
+ "Log message was [Level=%04d] %s::%s : %s\n",
+ OU2A(e.Message),int(nLevel),sourceClass,sourceMethod,OU2A(msg));
+ }
+ else if (nLevel >= (LogLevel::SEVERE - OSL_DEBUG_LEVEL*(LogLevel::SEVERE-LogLevel::WARNING)))
+ OSL_TRACE("Configuration Log [%04d] %s::%s : %s\n", int(nLevel),sourceClass,sourceMethod,OU2A(msg));
+
+}
+
+//--------------------------------------------------------------------------
+uno::Reference< logging::XLogger >
+ Logger::getUnoLoggerFromContext(uno::Reference< uno::XComponentContext > const & xContext)
+{
+ uno::Reference< logging::XLogger > xLogger;
+
+ if (xContext.is())
+ try { xContext->getValueByName( OUSTR(CONFIG_LOGGER_SINGLETON) ) >>= xLogger; }
+ catch (uno::Exception & ) {}
+
+ return xLogger;
+}
+
+//--------------------------------------------------------------------------
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/misc/makefile.mk b/configmgr/source/misc/makefile.mk
new file mode 100644
index 000000000000..8fc6389dc9b5
--- /dev/null
+++ b/configmgr/source/misc/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.28 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source
+PRJNAME=configmgr
+TARGET=misc
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+.INCLUDE : $(PRJ)$/version.mk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/bootstrap.obj \
+ $(SLO)$/providerfactory.obj \
+ $(SLO)$/providerwrapper.obj \
+ $(SLO)$/logger.obj \
+ $(SLO)$/tracer.obj \
+ $(SLO)$/configunoreg.obj \
+ $(SLO)$/serviceinfohelper.obj \
+ $(SLO)$/bootstrapcontext.obj \
+ $(SLO)$/anypair.obj \
+ $(SLO)$/strimpl.obj \
+ $(SLO)$/mergechange.obj \
+ $(SLO)$/oslstream.obj \
+ $(SLO)$/filehelper.obj \
+ $(SLO)$/bufferedfile.obj \
+ $(SLO)$/requestoptions.obj \
+ $(SLO)$/interactionrequest.obj \
+ $(SLO)$/configinteractionhandler.obj \
+ $(SLO)$/simpleinteractionrequest.obj \
+ $(SLO)$/propertysethelper.obj \
+
+OBJFILES= \
+ $(OBJ)$/oslstream.obj \
+ $(OBJ)$/filehelper.obj \
+ $(OBJ)$/bufferedfile.obj \
+
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/misc/mergechange.cxx b/configmgr/source/misc/mergechange.cxx
new file mode 100644
index 000000000000..b4b3f0d431fd
--- /dev/null
+++ b/configmgr/source/misc/mergechange.cxx
@@ -0,0 +1,831 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mergechange.cxx,v $
+ * $Revision: 1.27 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "builddata.hxx"
+#include "mergechange.hxx"
+#include "updatehelper.hxx"
+#include "treeactions.hxx"
+#include "treefragment.hxx"
+#include "change.hxx"
+#include "treechangefactory.hxx"
+#include "treechangelist.hxx"
+#include "configexcept.hxx"
+#include "tracer.hxx"
+
+#define ASCII(x) rtl::OUString::createFromAscii(x)
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------
+ class OMergeChanges : private ChangeTreeAction, private OPathCreator<configuration::RelativePath>
+ {
+ SubtreeChange &m_rSubtreeChange; // ChangeList, which will be grown
+ SubtreeChange *m_pCurrentParent; // our current position
+
+ // ------- Helper for Path stack -------
+ SubtreeChange* pushTree(SubtreeChange& _rTree);
+ void popTree(SubtreeChange* _pSaveTree);
+
+ public:
+ // CTor
+ OMergeChanges(SubtreeChange& _rTree);
+
+ // start function, with the Change we want to do.
+ // WARNING this could be a big tree, because a change can contain subtreechanges!
+ void mergeChanges(const SubtreeChange &_rChange, const configuration::RelativePath& _aPathToChange);
+ void mergeChanges(const SubtreeChange &_rChange);
+
+ private:
+ void initRoot(const SubtreeChange &_rRootChange, const configuration::RelativePath& _aPathToChange);
+ private:
+ virtual void handle(ValueChange const& _rValueNode);
+ virtual void handle(AddNode const& _rAddNode);
+ virtual void handle(RemoveNode const& _rRemoveNode);
+ virtual void handle(SubtreeChange const& _rSubtree);
+
+ };
+ // -----------------------------------------------------------------------------
+ void combineUpdates(SubtreeChange const& _anUpdate, SubtreeChange& _aCombinedUpdate)
+ {
+ OMergeChanges aCombined(_aCombinedUpdate);
+ aCombined.mergeChanges(_anUpdate);
+ }
+ // -----------------------------------------------------------------------------
+
+ configuration::Path::Component ONameCreator::createName(Change const& _rChange, SubtreeChange const* _pParent)
+ {
+ OSL_ENSURE(_pParent, "ONameCreator: Cannot create proper name without a parent");
+ if (_pParent && _pParent->isSetNodeChange())
+ {
+ rtl::OUString sElementName = _rChange.getNodeName();
+ rtl::OUString sTypeName = _pParent->getElementTemplateName();
+
+ return configuration::Path::makeCompositeName(sElementName, sTypeName);
+ }
+ else
+ {
+ rtl::OUString sElementName = _rChange.getNodeName();
+
+ // OSL_ENSURE(isSimpleName(sElementName),"Unexpected: Non-simple name in non-set node");
+
+ return configuration::Path::wrapSafeName(sElementName);
+ }
+ }
+
+
+ // -----------------------------------------------------------------------------
+ class OMergeValueChange : private ChangeTreeModification
+ {
+ SubtreeChange& m_rTargetParent;
+ const ValueChange& m_aValueChange;
+ public:
+ OMergeValueChange(SubtreeChange& _rTargetParent, const ValueChange& _aValueChange)
+ :m_rTargetParent(_rTargetParent)
+ ,m_aValueChange(_aValueChange)
+ {
+
+ }
+ void handleChange(Change &_rNode)
+ {
+ this->applyToChange(_rNode);
+ }
+ private:
+ virtual void handle(ValueChange& _rValueChange)
+ {
+ // POST: Handle ValueChange
+ _rValueChange.setNewValue(m_aValueChange.getNewValue(), m_aValueChange.getMode());
+ }
+ virtual void handle(RemoveNode& /*_rRemoveNode*/)
+ {
+ OSL_ENSURE(false, "OMergeValueChange::handle(ValueChange): have a ValueChange for a removed node!");
+ // should never happen. How did the user change a value for a node which is obviously flagged as removed?
+ }
+ virtual void handle(AddNode& _rAddNode);
+ virtual void handle(SubtreeChange& _rSubtree)
+ {
+ if ( isLocalizedValueSet(_rSubtree) )
+ {
+ std::auto_ptr<ValueChange> pNewValueChange( new ValueChange(m_aValueChange) );
+ OSL_ENSURE(pNewValueChange->isLocalizedValue(), "OMergeValueChange:handle(SubtreeChange): have a non-localized ValueChange a for a localized node!");
+
+ std::auto_ptr<Change> pNewChange( pNewValueChange.release() );
+
+ replaceExistingEntry(pNewChange);
+ }
+ else
+ OSL_ENSURE(false, "OMergeValueChange:handle(SubtreeChange): have a ValueChange for a sub tree!");
+ }
+
+ void replaceExistingEntry(std::auto_ptr<Change> pNewChange)
+ {
+ m_rTargetParent.removeChange(pNewChange->getNodeName());
+ m_rTargetParent.addChange(pNewChange);
+ }
+ static std::auto_ptr<ValueNode> createNodeFromChange(ValueChange const& rChange)
+ {
+ std::auto_ptr<ValueNode> aRet;
+
+ uno::Any aNewValue = rChange.getNewValue();
+
+ // currently not supporting change modes !
+ if (aNewValue.hasValue())
+ aRet.reset( new ValueNode(rChange.getNodeName(), aNewValue, rChange.getAttributes()) );
+
+ else // NULL
+ {
+ aRet.reset( new ValueNode(rChange.getNodeName(), rChange.getValueType(), rChange.getAttributes()) );
+
+ OSL_ENSURE(aRet->isValid(), "Cannot recover type for change to NULL");
+ }
+ return aRet;
+ }
+
+ };
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ // TODO: operate directly on new data structures
+
+ void OMergeValueChange::handle(AddNode& _rAddNode)
+ {
+ if (m_aValueChange.isToDefault())
+ {
+ std::auto_ptr<Change> aChangeToDefault(m_aValueChange.clone());
+ m_rTargetParent.removeChange(_rAddNode.getNodeName());
+ m_rTargetParent.addChange( aChangeToDefault );
+ }
+ else
+ {
+ // POST: Handle ValueChange in AddNode
+ rtl::Reference< data::TreeSegment > seg(_rAddNode.getNewTree());
+ std::auto_ptr<INode> pAddedNode = data::convertTree(seg.is() ? seg->fragment : 0, false);
+
+ if (ValueNode *pValueNode = pAddedNode->asValueNode())
+ {
+ m_aValueChange.applyChangeNoRecover(*pValueNode);
+ }
+
+ else if (ISubtree* pValueSetNode = pAddedNode->asISubtree() )
+ {
+ if ( isLocalizedValueSet(*pValueSetNode) )
+ {
+ std::auto_ptr<ValueNode> pNewValueNode = createNodeFromChange(m_aValueChange);
+ if (pNewValueNode.get())
+ {
+ OSL_ENSURE(pNewValueNode->isLocalized(), "OMergeValueChange:handle(AddNode): have a non-localized ValueChange a for a localized node!");
+ pNewValueNode->setName(pAddedNode->getName());
+ }
+ else
+ OSL_ENSURE(false, "OMergeValueChange:handle(SubtreeChange): Creating a NULL node to replace a localized value set not yet supported");
+
+
+ pAddedNode.reset(pNewValueNode.release());
+ }
+ else
+ {
+ OSL_ENSURE(sal_False, "OMergeValueChange:handle(AddNode): have a ValueChange a for non-value node!");
+ pAddedNode.reset(); // leave unchanged
+ }
+
+ }
+ else
+ {
+ OSL_ENSURE(sal_False, "OMergeValueChange:handle(AddNode): Found unknown node type!");
+ pAddedNode.reset(); // leave unchanged
+ }
+
+ if (pAddedNode.get() != NULL)
+ {
+ rtl::Reference< data::TreeSegment > aNewTree = data::TreeSegment::create(_rAddNode.getNodeName(),pAddedNode);
+
+ std::auto_ptr<AddNode> pNewAdd( new AddNode(aNewTree,m_aValueChange.getNodeName(), m_aValueChange.isToDefault()) );
+ if (_rAddNode.isReplacing())
+ pNewAdd->setReplacing();
+
+ std::auto_ptr<Change> pNewChange( pNewAdd.release() );
+ replaceExistingEntry(pNewChange);
+ }
+ }
+ }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ class OMergeRemoveNode : private ChangeTreeModification
+ {
+ public:
+ // actions to take with the remove node change
+ enum Action
+ {
+ RemoveCompletely,
+ FlagDeleted,
+ Undetermined
+ };
+
+ protected:
+ Action m_eAction;
+
+ public:
+ OMergeRemoveNode() : m_eAction(Undetermined) { }
+
+ Action getAction() const { return m_eAction; }
+
+ void handleChange(Change* _pChange)
+ {
+ if (_pChange)
+ applyToChange(*_pChange);
+ else
+ // no change -> flag as deleted
+ m_eAction = FlagDeleted;
+ }
+
+ private:
+ virtual void handle(ValueChange& aValueChange)
+ {
+ if (aValueChange.getAttributes().existsInDefault())
+ m_eAction = FlagDeleted;
+ else
+ m_eAction = RemoveCompletely;
+ }
+
+ virtual void handle(RemoveNode& /*_rRemoveNode*/)
+ {
+ OSL_ENSURE(false, "OMergeRemoveNode::handle(RemoveNode): should never happen!");
+ // how can a RemoveNode change exist if in the file we're merging it into
+ // there already is such a RemoveNode change (_rRemoveNode)?
+ }
+
+ virtual void handle(AddNode& _rAddNode)
+ {
+ if (_rAddNode.isReplacing())
+ m_eAction = FlagDeleted;
+ else
+ m_eAction = RemoveCompletely;
+ }
+
+ virtual void handle(SubtreeChange& _rSubtree)
+ {
+ if (_rSubtree.getAttributes().existsInDefault())
+ m_eAction = FlagDeleted;
+ else
+ m_eAction = RemoveCompletely;
+ }
+ };
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+
+ static
+ inline
+ Change* findExistingChange(SubtreeChange* pCurrentParent, configuration::Path::Component const & _aName)
+ {
+ OSL_ASSERT(pCurrentParent);
+
+ Change *pChange = pCurrentParent->getChange(_aName.getName());
+
+ if (!pChange && !_aName.isSimpleName())
+ {
+ pChange = pCurrentParent->getChange(_aName.toPathString());
+ OSL_ENSURE(!pChange, "Update trouble: Existing node found only by composite name while merging");
+ }
+
+ return pChange;
+ }
+
+ static
+ inline
+ Change* findExistingChange(SubtreeChange* pCurrentParent, rtl::OUString const & _aName)
+ {
+ OSL_ASSERT(pCurrentParent);
+
+ Change *pChange = pCurrentParent->getChange(_aName);
+
+ return pChange;
+ }
+ // -----------------------------------------------------------------------------
+
+ void adjustElementTemplate(SubtreeChange& _rChange, const rtl::OUString& _rName, const rtl::OUString& _rModule)
+ {
+ if (!_rChange.isSetNodeChange() || isGenericSetElementType(_rChange.getElementTemplateName()))
+ {
+ _rChange.setElementTemplate(_rName,_rModule);
+ }
+ else if ( isDummySetElementModule(_rChange.getElementTemplateModule()) &&
+ !isGenericSetElementType(_rName) && !isDummySetElementModule(_rModule))
+ {
+ OSL_ENSURE(_rChange.getElementTemplateName() == _rName, "Adjusting: Template modules do not match");
+
+ _rChange.setElementTemplate(_rName,_rModule);
+ }
+ OSL_POSTCOND(_rChange.getElementTemplateName() == _rName || isGenericSetElementType(_rName),
+ "Adjusting: Template modules do not match");
+ OSL_POSTCOND(_rChange.getElementTemplateModule() == _rModule || isDummySetElementModule(_rModule),
+ "Adjusting: Template modules do not match");
+ }
+ // -----------------------------------------------------------------------------
+
+ inline void adjustElementTemplate(SubtreeChange& _rChange, SubtreeChange const& _rSource)
+ {
+ if (_rSource.isSetNodeChange())
+ adjustElementTemplate(_rChange, _rSource.getElementTemplateName(), _rSource.getElementTemplateModule());
+ }
+
+ // -----------------------------------------------------------------------------
+
+ // CTor
+ OMergeChanges::OMergeChanges(SubtreeChange& _rTree)
+ : m_rSubtreeChange(_rTree), m_pCurrentParent(NULL)
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ void OMergeChanges::initRoot(const SubtreeChange &_rRootChange, const configuration::RelativePath& _aPathToChange)
+ {
+ SubtreeChange* pCurrentParent = &m_rSubtreeChange;
+
+ if (!_aPathToChange.isEmpty())
+ {
+ OSL_PRECOND(_aPathToChange.getLocalName().getName() == _rRootChange.getNodeName(),
+ "Path to change root does not match change being merged" );
+
+ std::vector<configuration::Path::Component>::const_reverse_iterator const firstEnsure = _aPathToChange.begin();
+ std::vector<configuration::Path::Component>::const_reverse_iterator lastEnsure = _aPathToChange.end();
+ std::vector<configuration::Path::Component>::const_reverse_iterator it;
+
+ OSL_ASSERT( firstEnsure != lastEnsure );
+ --lastEnsure; // last to ensure is the actual root
+
+ for( it = firstEnsure; it != lastEnsure; ++it)
+ {
+ OSL_ASSERT( it != _aPathToChange.end() );
+
+ Change *pChange = findExistingChange(pCurrentParent,*it);
+
+ if (!pChange)
+ {
+ OSL_ASSERT( it+1 != _aPathToChange.end());
+ rtl::OUString const aElementTypeName = (it+1)->getTypeName();
+
+ // create a correspondens for the name, we did not find.
+ std::auto_ptr<SubtreeChange> pNewChange =
+ OTreeChangeFactory::createDummyChange(it->getName(), aElementTypeName);
+
+ pChange = pNewChange.get();
+
+ pCurrentParent->addChange(base_ptr(pNewChange));
+
+ OSL_ENSURE(pChange == findExistingChange(pCurrentParent,*it),
+ "ERROR: Newly added change cannot be found in parent change");
+ }
+
+ pCurrentParent = dynamic_cast<SubtreeChange*>( pChange);
+ if (pCurrentParent == 0)
+ {
+ OSL_ENSURE(false, "Change to merge does not point to a Subtree Change");
+ throw configuration::InvalidName(_aPathToChange.toString(), "points to a non- subtree change in this changes list, but a subtree change is required as root.");
+ }
+ }
+
+ Change *pRootChange = findExistingChange(pCurrentParent,*lastEnsure);
+
+ if (!pRootChange)
+ {
+ // create a correspondens for the name, we did not find.
+ std::auto_ptr<SubtreeChange> pNewChange(
+ new SubtreeChange(_rRootChange, treeop::NoChildCopy()) );
+
+ pRootChange = pNewChange.get();
+
+ pCurrentParent->addChange(base_ptr(pNewChange));
+
+ OSL_ENSURE(pRootChange == findExistingChange(pCurrentParent,*it),
+ "ERROR: Newly added change cannot be found in parent change");
+ }
+
+ pCurrentParent = dynamic_cast<SubtreeChange*>( pRootChange);
+ if (pCurrentParent == 0)
+ {
+ OSL_ENSURE(false, "Change to merge does not point to a Subtree Change");
+ throw configuration::InvalidName(_aPathToChange.toString(), "points to a non-subtree change in this changes list, but a subtree change is required as root.");
+ }
+ }
+
+ OSL_ENSURE(pCurrentParent->getNodeName() == _rRootChange.getNodeName(),
+ "Change being merged has a different name");
+
+ adjustElementTemplate(*pCurrentParent,_rRootChange);
+
+ this->init(_aPathToChange);
+
+ m_pCurrentParent = pCurrentParent;
+ }
+ // -----------------------------------------------------------------------------
+
+ // ------- Helper for Path stack -------
+ SubtreeChange* OMergeChanges::pushTree(SubtreeChange& _rTree)
+ {
+ pushName( ONameCreator::createName(_rTree,m_pCurrentParent) );
+
+ SubtreeChange* pSave = m_pCurrentParent;
+ m_pCurrentParent = &_rTree;
+ return pSave;
+ }
+ void OMergeChanges::popTree(SubtreeChange* _pSaveTree)
+ {
+ m_pCurrentParent = _pSaveTree;
+
+ popName();
+ }
+ // -----------------------------------------------------------------------------
+
+ // start function, with the Change we want to do.
+ // WARNING this could be a big tree, because a change can contain subtreechanges!
+ void OMergeChanges::mergeChanges(const SubtreeChange &_rChange)
+ {
+ mergeChanges(_rChange, configuration::RelativePath());
+ }
+ // -----------------------------------------------------------------------------
+
+ // start function, with the Change we want to do.
+ // WARNING this could be a big tree, because a change can contain subtreechanges!
+ void OMergeChanges::mergeChanges(const SubtreeChange &_rChange, const configuration::RelativePath& _aPathToChange)
+ {
+ initRoot(_rChange, _aPathToChange); // path location being merged must exist
+
+ this->applyToChildren(_rChange); //- semantics ?
+ }
+ // -----------------------------------------------------------------------------
+
+ // Algorithm: search the actual path in the out m_aSubtreeChange
+ // if we found something, we must merge/convert the Node with our Node
+ // if we found nothing, we must create a new Node with our change
+ // thats it.
+
+ // the merge is contructed with helper classes because, it's possible that we
+ // are a ValueChange but in the TreeChangeList this change is an AddNode, so
+ // we have something to do.
+
+ void OMergeChanges::handle(ValueChange const& _rValueNode)
+ {
+ // Handle a ValueChange,
+ rtl::OUString aNodeName = _rValueNode.getNodeName();
+
+ if (Change *pChange = findExistingChange(m_pCurrentParent,aNodeName))
+ {
+ // Value found, merge content
+ OMergeValueChange aMergeValue(*m_pCurrentParent,_rValueNode);
+ aMergeValue.handleChange(*pChange);
+ }
+ else
+ {
+ // there is no ValueChange in the List, insert new one
+ std::auto_ptr<Change> pNewChange(new ValueChange(_rValueNode));
+ m_pCurrentParent->addChange(pNewChange);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void OMergeChanges::handle(AddNode const& _rAddNode)
+ {
+ // Handle an AddNode
+ bool bReplacing = _rAddNode.isReplacing();
+
+ rtl::OUString aNodeName = _rAddNode.getNodeName();
+
+ if (Change *pChange = findExistingChange(m_pCurrentParent,aNodeName))
+ {
+ OSL_ENSURE(dynamic_cast< RemoveNode * >(pChange) != 0 || bReplacing, "OMergeChanges::handle(AddNode): the changes tree given already contains a change for this!");
+
+ m_pCurrentParent->removeChange(pChange->getNodeName());
+
+ bReplacing = true;
+ }
+
+ // insert manually
+ rtl::Reference< data::TreeSegment > aAddedTree = data::TreeSegment::create(_rAddNode.getNewTree());
+
+ std::auto_ptr<AddNode> pNewAdd(new AddNode(aAddedTree, _rAddNode.getNodeName(), _rAddNode.isToDefault()));
+ if (bReplacing)
+ pNewAdd->setReplacing();
+
+ std::auto_ptr<Change> pNewChange( pNewAdd.release() );
+ m_pCurrentParent->addChange(pNewChange);
+ }
+ // -----------------------------------------------------------------------------
+
+ void OMergeChanges::handle(RemoveNode const& _rRemoveNode)
+ {
+ // Handle a RemoveNode
+ rtl::OUString aNodeName = _rRemoveNode.getNodeName();
+
+ Change *pChange = findExistingChange(m_pCurrentParent,aNodeName);
+
+ // examine what to do with this change
+ OMergeRemoveNode aExaminer;
+ aExaminer.handleChange(pChange);
+
+ // remove the change from it's parent (may it's re-inserted in another form below)
+ if (pChange)
+ m_pCurrentParent->removeChange(pChange->getNodeName());
+
+ // insert a new change if necessary
+ switch (aExaminer.getAction())
+ {
+ case OMergeRemoveNode::RemoveCompletely:
+ // nothing to do, we already removed it
+ break;
+ default:
+ OSL_ENSURE(sal_False, "OMergeChanges::handle(RemoveNode): don't know what to do with this!");
+ // NO BREAK.
+ // defaulting this so that the node will be marked as deleted
+ case OMergeRemoveNode::FlagDeleted:
+ {
+ std::auto_ptr<Change> pNewChange(new RemoveNode(_rRemoveNode.getNodeName(),_rRemoveNode.isToDefault()));
+ m_pCurrentParent->addChange(pNewChange);
+ }
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+ inline
+ void OStripDefaults::stripOne(Change& _rChange)
+ {
+ m_rParent.removeChange(_rChange.getNodeName());
+ }
+
+ void OStripDefaults::handle(ValueChange& _rValueNode)
+ {
+ if (_rValueNode.isToDefault())
+ stripOne(_rValueNode);
+ }
+ void OStripDefaults::handle(AddNode& _rAddNode)
+ {
+ if (_rAddNode.isToDefault())
+ {
+ sharable::TreeFragment const * pAdded = _rAddNode.getNewTreeData();
+ OSL_ENSURE(pAdded,"No Data in AddNode");
+ if (pAdded == NULL || pAdded->getAttributes().isDefault())
+ stripOne(_rAddNode);
+
+ // else we should strip the defaults from the added node
+ }
+ }
+ void OStripDefaults::handle(RemoveNode& _rRemoveNode)
+ {
+ if (_rRemoveNode.isToDefault())
+ stripOne(_rRemoveNode);
+ }
+ void OStripDefaults::handle(SubtreeChange& _rSubtree)
+ {
+ if ( strip(_rSubtree) )
+ if (_rSubtree.isToDefault() || !_rSubtree.isSetNodeChange())
+ stripOne(_rSubtree);
+ }
+
+ OStripDefaults& OStripDefaults::strip()
+ {
+ SubtreeChange::MutatingChildIterator it = m_rParent.begin_changes(), stop = m_rParent.end_changes();
+
+ while (it != stop)
+ {
+ this->applyToChange(*it++);
+ }
+
+ return *this;
+ }
+
+
+// -----------------------------------------------------------------------------
+ class TreeUpdater : public ChangeTreeAction
+ {
+ ISubtree* m_pCurrentSubtree;
+#if OSL_DEBUG_LEVEL > 1
+ std::vector<rtl::OString> aLog;
+#endif
+
+ public:
+ TreeUpdater(ISubtree* pSubtree):m_pCurrentSubtree(pSubtree){}
+
+ void handle(ValueChange const& aValueNode);
+ void handle(AddNode const& aAddNode);
+ void handle(RemoveNode const& aRemoveNode);
+ void handle(SubtreeChange const& aSubtree);
+ };
+
+// -----------------------------------------------------------------------------
+
+
+ void OMergeChanges::handle(SubtreeChange const& _rSubtree)
+ {
+ // Handle a SubtreeChange
+ // we must check if exact this SubtreeChange is in the TreeChangeList, if not,
+ // we must add this SubtreeChange to the TreeChangeList
+ // with the pointer m_pCurrentParent we remember our SubtreeChange in witch we
+ // add all other Changes.
+
+ rtl::OUString aNodeName = _rSubtree.getNodeName();
+
+ Change *pChange = findExistingChange(m_pCurrentParent,aNodeName);
+
+ // const sal_Char* pType = pChange ? pChange->getType() : NULL;
+ SubtreeChange* pSubtreeChange = NULL;
+ if (pChange == NULL || dynamic_cast< SubtreeChange * >(pChange) != 0)
+ {
+ // need to create a new Subtreechange
+ if (!pChange)
+ {
+ // create a new SubtreeChange
+ std::auto_ptr<SubtreeChange> pNewChange(new SubtreeChange(_rSubtree, treeop::NoChildCopy()));
+ pSubtreeChange = pNewChange.get();
+
+ // add the new SubtreeChange in m_aTreeChangeList
+ m_pCurrentParent->addChange(std::auto_ptr<Change>(pNewChange.release()));
+ // check list for this new SubtreeChange
+ OSL_ASSERT(pSubtreeChange == findExistingChange(m_pCurrentParent,aNodeName));
+ }
+ else
+ {
+ pSubtreeChange = dynamic_cast<SubtreeChange*>(pChange);
+ OSL_ASSERT(pSubtreeChange != 0);
+ adjustElementTemplate(*pSubtreeChange,_rSubtree);
+ }
+
+ // save this SubtreeChange so we allways have the last Subtree
+ SubtreeChange* pSaveParent = pushTree(*pSubtreeChange);
+ this->applyToChildren(_rSubtree);
+ popTree( pSaveParent );
+ }
+ else if (AddNode* pAddNode = dynamic_cast<AddNode*>(pChange))
+ {
+ rtl::Reference< data::TreeSegment > seg(pAddNode->getNewTree());
+ std::auto_ptr<INode> pAddedNode = data::convertTree(seg.is() ? seg->fragment : 0, false);
+ ISubtree* pSubtree = pAddedNode.get() ? pAddedNode->asISubtree() : 0;
+ if (pSubtree)
+ {
+ pSubtree->markAsDefault( _rSubtree.isToDefault() );
+
+ // Now apply _rSubtree to the subtree
+ TreeUpdater aTreeUpdate(pSubtree);
+ aTreeUpdate.applyToChildren(_rSubtree);
+
+ // make a new subtree with the changed data
+ rtl::Reference< data::TreeSegment > aNewTree = data::TreeSegment::create(pAddNode->getNodeName(), pAddedNode);
+
+ std::auto_ptr<AddNode> pNewAdd( new AddNode(aNewTree, pAddNode->getNodeName(), pAddNode->isToDefault()) );
+ if (pAddNode->isReplacing())
+ pNewAdd->setReplacing();
+
+ std::auto_ptr<Change> pNewChange( pNewAdd.release() );
+
+ m_pCurrentParent->removeChange(pAddNode->getNodeName());
+ m_pCurrentParent->addChange( pNewChange );
+ }
+ else
+ {
+ OSL_ENSURE(false, "OMergeChanges: Unexpected node type found in an AddNode.");
+ /* wrong type of node found: böse ASSERTEN/WERFEN */;
+ }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ }
+ else
+ {
+ OSL_ENSURE(false, "OMergeChanges: Unexpected change type found for a subtree.");
+ /* wrong type of node found: böse ASSERTEN/WERFEN */;
+ }
+ }
+
+ // --------------------------------- updateTree ---------------------------------
+ void TreeUpdater::handle(ValueChange const& aValueNode)
+ {
+ // Change a Value
+ OSL_ENSURE(m_pCurrentSubtree,"Cannot apply ValueChange without subtree");
+
+ INode* pBaseNode = m_pCurrentSubtree ? m_pCurrentSubtree->getChild(aValueNode.getNodeName()) : 0;
+ OSL_ENSURE(pBaseNode,"Cannot apply Change: No node to change");
+
+ ValueNode* pValue = pBaseNode ? pBaseNode->asValueNode() : 0;
+ OSL_ENSURE(pValue,"Cannot apply ValueChange: Node is not a value");
+
+ if (pValue)
+ aValueNode.applyChangeNoRecover(*pValue);
+#if OSL_DEBUG_LEVEL > 1
+ else
+ {
+ ::rtl::OString aStr("TreeUpdater: Can't find value with name:=");
+ aStr += rtl::OUStringToOString(aValueNode.getNodeName(),RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(pValue, aStr.getStr());
+ aLog.push_back(aStr);
+ }
+#endif
+ }
+
+ void TreeUpdater::handle(AddNode const& aAddNode)
+ {
+ // Add a new Value
+ if (m_pCurrentSubtree)
+ {
+ if (aAddNode.isReplacing())
+ {
+ std::auto_ptr<INode> aOldNode = m_pCurrentSubtree->removeChild(aAddNode.getNodeName());
+
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE(aOldNode.get(), "TreeUpdater:AddNode: can't recover node being replaced");
+ if (aOldNode.get() == NULL)
+ aLog.push_back(rtl::OString("TreeUpdater: can't recover node being replaced (for AddNode)"));
+#endif
+ }
+
+ rtl::Reference< data::TreeSegment > seg(aAddNode.getNewTree());
+ std::auto_ptr<INode> pNode(data::convertTree(seg.is() ? seg->fragment : 0, true));
+
+ m_pCurrentSubtree->addChild(pNode);
+ }
+#if OSL_DEBUG_LEVEL > 1
+ else
+ aLog.push_back(rtl::OString("TreeUpdater: no CurrentSubtree for AddNode"));
+#endif
+
+ }
+
+ void TreeUpdater::handle(RemoveNode const& aRemoveNode)
+ {
+ // remove a Value
+ if (m_pCurrentSubtree)
+ {
+ std::auto_ptr<INode> aOldNode = m_pCurrentSubtree->removeChild(aRemoveNode.getNodeName());
+
+#if OSL_DEBUG_LEVEL > 1
+ if (NULL == aOldNode.get())
+ {
+ ::rtl::OString aStr("TreeUpdater: Can't remove child with name:=");
+ aStr += rtl::OUStringToOString(aRemoveNode.getNodeName(),RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(false, aStr.getStr());
+ aLog.push_back(aStr);
+ }
+#endif
+ }
+ }
+
+ void TreeUpdater::handle(SubtreeChange const& _aSubtree)
+ {
+ // handle traversion
+ ISubtree *pOldSubtree = m_pCurrentSubtree;
+ rtl::OUString aNodeName = _aSubtree.getNodeName();
+
+ INode* pChild = m_pCurrentSubtree->getChild(aNodeName);
+ OSL_ENSURE(pChild, "TreeUpdater::handle : invalid subtree change ... no child for change !");
+ m_pCurrentSubtree = pChild ? pChild->asISubtree() : NULL;
+
+#if OSL_DEBUG_LEVEL > 1
+ if (!m_pCurrentSubtree)
+ {
+ ::rtl::OString aStr("TreeUpdater: there is no Subtree for name:=");
+ aStr += rtl::OUStringToOString(_aSubtree.getNodeName(),RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(false, aStr.getStr());
+ aLog.push_back(aStr);
+ }
+#endif
+ // recurse
+ if (m_pCurrentSubtree)
+ {
+ m_pCurrentSubtree->markAsDefault( _aSubtree.isToDefault() );
+ _aSubtree.forEachChange(*this);
+ }
+
+ m_pCurrentSubtree = pOldSubtree;
+ }
+
+} // namespace configmgr
diff --git a/configmgr/source/misc/oslstream.cxx b/configmgr/source/misc/oslstream.cxx
new file mode 100644
index 000000000000..3a52329e7c98
--- /dev/null
+++ b/configmgr/source/misc/oslstream.cxx
@@ -0,0 +1,264 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: oslstream.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "oslstream.hxx"
+
+#include "filehelper.hxx"
+
+namespace configmgr
+{
+ static void raiseIOException(osl::File::RC error, staruno::Reference<staruno::XInterface> const & context)
+ {
+ const rtl::OUString message = FileHelper::createOSLErrorString(error);
+ switch (error)
+ {
+ case osl::File::E_NOMEM:
+ throw stario::BufferSizeExceededException(message, context);
+
+ case osl::File::E_BADF:
+ throw stario::NotConnectedException(message, context);
+
+ default:
+ throw stario::IOException(message, context);
+ }
+ }
+//------------------------------------------------------------------
+OSLInputStreamWrapper::OSLInputStreamWrapper( osl::File& _rFile )
+ :m_pFile(&_rFile)
+ ,m_bFileOwner(sal_False)
+{
+}
+
+//------------------------------------------------------------------
+OSLInputStreamWrapper::OSLInputStreamWrapper( osl::File* pStream, sal_Bool bOwner )
+ :m_pFile( pStream )
+ ,m_bFileOwner( bOwner )
+{
+}
+
+//------------------------------------------------------------------
+OSLInputStreamWrapper::~OSLInputStreamWrapper()
+{
+ if( m_bFileOwner )
+ delete m_pFile;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSLInputStreamWrapper::readBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead)
+ throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ if (nBytesToRead < 0)
+ throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ osl::MutexGuard aGuard( m_aMutex );
+
+ aData.realloc(nBytesToRead);
+
+ sal_uInt64 nRead = 0;
+ osl::File::RC eError = m_pFile->read(aData.getArray(), nBytesToRead, nRead);
+ if (eError != osl::File::E_None)
+ throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ // Wenn gelesene Zeichen < MaxLength, staruno::Sequence anpassen
+ if (nRead < (sal_uInt64)nBytesToRead)
+ aData.realloc( sal::static_int_cast<sal_Int32>( nRead ));
+
+ return sal::static_int_cast<sal_Int32>( nRead );
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSLInputStreamWrapper::readSomeBytes(staruno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ if (nMaxBytesToRead < 0)
+ throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ /*
+ if (m_pFile->IsEof())
+ {
+ aData.realloc(0);
+ return 0;
+ }
+ else
+ */
+ return readBytes(aData, nMaxBytesToRead);
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OSLInputStreamWrapper::skipBytes(sal_Int32 nBytesToSkip) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ sal_uInt64 nCurrentPos;
+ m_pFile->getPos(nCurrentPos);
+
+ sal_uInt64 nNewPos = nCurrentPos + nBytesToSkip;
+ osl::File::RC eError = m_pFile->setPos(osl_Pos_Absolut, nNewPos);
+ if (eError != osl::File::E_None)
+ {
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL OSLInputStreamWrapper::available() throw( stario::NotConnectedException, staruno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ sal_uInt64 nPos;
+ osl::File::RC eError = m_pFile->getPos(nPos);
+ if (eError != osl::File::E_None)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ sal_uInt64 nDummy = 0;
+ eError = m_pFile->setPos(Pos_End, nDummy);
+ if (eError != osl::File::E_None)
+ throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ sal_uInt64 nAvailable;
+ eError = m_pFile->getPos(nAvailable);
+ if (eError != osl::File::E_None)
+ throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+
+ nAvailable = nAvailable - nPos;
+ eError = m_pFile->setPos(Pos_Absolut, nPos);
+ if (eError != osl::File::E_None)
+ throw stario::NotConnectedException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+ return sal::static_int_cast<sal_Int32>( nAvailable );
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL OSLInputStreamWrapper::closeInput() throw( stario::NotConnectedException, staruno::RuntimeException )
+{
+ if (!m_pFile)
+ throw stario::NotConnectedException(::rtl::OUString(), static_cast<staruno::XWeak*>(this));
+
+ m_pFile->close();
+ if (m_bFileOwner)
+ delete m_pFile;
+
+ m_pFile = NULL;
+}
+
+/*************************************************************************/
+// stario::XOutputStream
+//------------------------------------------------------------------------------
+void SAL_CALL OSLOutputStreamWrapper::writeBytes(const staruno::Sequence< sal_Int8 >& aData) throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ sal_uInt32 const nLength = sal_uInt32(aData.getLength());
+ if (nLength != 0)
+ {
+ sal_uInt64 nWritten;
+ osl::File::RC eError = rFile.write(aData.getConstArray(),nLength, nWritten);
+ if (eError != osl::File::E_None || nWritten != nLength)
+ {
+ throw stario::BufferSizeExceededException(::rtl::OUString(),static_cast<staruno::XWeak*>(this));
+ }
+ }
+}
+
+
+//------------------------------------------------------------------
+void SAL_CALL OSLOutputStreamWrapper::flush() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+}
+
+//------------------------------------------------------------------
+void SAL_CALL OSLOutputStreamWrapper::closeOutput() throw( stario::NotConnectedException, stario::BufferSizeExceededException, staruno::RuntimeException )
+{
+ rFile.close();
+}
+
+//------------------------------------------------------------------
+//------------------------------------------------------------------
+BufferedFileOutputStream::BufferedFileOutputStream( rtl::OUString const & aFileURL, bool bCreate, sal_uInt32 nBufferSizeHint)
+: m_aFile( aFileURL, nBufferSizeHint )
+{
+ sal_Int32 flags = bCreate ? OpenFlag_Write|OpenFlag_Create : OpenFlag_Write;
+
+ osl::File::RC rc = m_aFile.open(flags);
+ if (rc != osl::File::E_None)
+ raiseIOException(rc,NULL);
+}
+
+//------------------------------------------------------------------
+BufferedFileOutputStream::~BufferedFileOutputStream()
+{
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL BufferedFileOutputStream::writeBytes(const staruno::Sequence< sal_Int8 >& aData)
+ throw( stario::NotConnectedException, stario::BufferSizeExceededException,
+ stario::IOException, staruno::RuntimeException )
+{
+ const sal_uInt64 size = sal_uInt64(aData.getLength());
+ sal_uInt64 written = 0;
+
+ osl::File::RC rc = m_aFile.write(aData.getConstArray(), size, written);
+ if (rc != osl::File::E_None)
+ raiseIOException(rc,*this);
+
+ // we don't support special files where multiple write passes are needed
+ if (written < size)
+ raiseIOException(osl::File::E_IO,*this);
+}
+
+void SAL_CALL BufferedFileOutputStream::flush()
+ throw( stario::NotConnectedException, stario::BufferSizeExceededException,
+ stario::IOException, staruno::RuntimeException )
+{
+ osl::File::RC rc = m_aFile.sync();
+ if (rc != osl::File::E_None)
+ raiseIOException(rc,*this);
+}
+
+void SAL_CALL BufferedFileOutputStream::closeOutput()
+ throw( stario::NotConnectedException, stario::BufferSizeExceededException,
+ stario::IOException, staruno::RuntimeException )
+{
+ osl::File::RC rc = m_aFile.close();
+ if (rc != osl::File::E_None)
+ raiseIOException(rc,*this);
+}
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/misc/propertysethelper.cxx b/configmgr/source/misc/propertysethelper.cxx
new file mode 100644
index 000000000000..7dd706190315
--- /dev/null
+++ b/configmgr/source/misc/propertysethelper.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: propertysethelper.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "propertysethelper.hxx"
+#include <com/sun/star/lang/XTypeProvider.hpp>
+
+#include <cppuhelper/typeprovider.hxx>
+
+//..........................................................................
+namespace configmgr {
+ namespace apihelper {
+//..........................................................................
+ namespace uno = com::sun::star::uno;
+ namespace lang = com::sun::star::lang;
+ namespace beans = com::sun::star::beans;
+//..........................................................................
+PropertySetHelper::PropertySetHelper()
+: BroadcasterBase()
+, cppu::OWeakObject()
+, cppu::OPropertySetHelper( BroadcasterBase::getBroadcastHelper() )
+, m_pHelper(0)
+{
+}
+
+//..........................................................................
+PropertySetHelper::~PropertySetHelper()
+{
+ delete m_pHelper;
+}
+
+//..........................................................................
+// XInterface
+uno::Any SAL_CALL PropertySetHelper::queryInterface( uno::Type const & rType ) throw (uno::RuntimeException)
+{
+ uno::Any aResult = cppu::OPropertySetHelper::queryInterface(rType);
+ if (!aResult.hasValue())
+ aResult = OWeakObject::queryInterface(rType);
+ return aResult;
+}
+
+void SAL_CALL PropertySetHelper::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL PropertySetHelper::release() throw ()
+{
+ if (m_refCount == 1)
+ this->disposing();
+
+ OWeakObject::release();
+}
+
+//..........................................................................
+// XTypeProvider
+uno::Sequence< uno::Type > SAL_CALL PropertySetHelper::getTypes() throw (uno::RuntimeException)
+{
+ // could be static instance
+ cppu::OTypeCollection aTypes(
+ ::getCppuType( static_cast< uno::Reference< beans::XPropertySet > const * >(0) ),
+ ::getCppuType( static_cast< uno::Reference< beans::XMultiPropertySet > const * >(0) ),
+ ::getCppuType( static_cast< uno::Reference< beans::XFastPropertySet > const * >(0) ),
+ ::getCppuType( static_cast< uno::Reference< lang::XTypeProvider > const * >(0) ) );
+
+ return aTypes.getTypes();
+}
+
+//..........................................................................
+// cppu::OPropertySetHelper
+uno::Reference< beans::XPropertySetInfo > SAL_CALL PropertySetHelper::getPropertySetInfo( )
+ throw (uno::RuntimeException)
+{
+ return createPropertySetInfo(getInfoHelper());
+}
+
+//..........................................................................
+cppu::IPropertyArrayHelper & SAL_CALL PropertySetHelper::getInfoHelper()
+{
+ osl::MutexGuard aGuard( getBroadcastMutex() );
+ if (!m_pHelper)
+ m_pHelper = newInfoHelper();
+
+ OSL_ENSURE(m_pHelper,"Derived class did not create new PropertyInfoHelper");
+ if (!m_pHelper)
+ throw uno::RuntimeException(rtl::OUString::createFromAscii("No PropertyArrayHelper available"),*this);
+
+ return *m_pHelper;
+}
+
+//..........................................................................
+sal_Bool SAL_CALL PropertySetHelper::convertFastPropertyValue(
+ uno::Any & rConvertedValue, uno::Any & rOldValue, sal_Int32 nHandle, const uno::Any& rValue )
+ throw (lang::IllegalArgumentException)
+{
+ this->getFastPropertyValue(rOldValue, nHandle);
+ rConvertedValue = rValue;
+ return rValue.isExtractableTo( rOldValue.getValueType() );
+}
+//..........................................................................
+ } // namespace apihelper
+} // namespace configmgr
+//..........................................................................
+
+
diff --git a/configmgr/source/misc/providerfactory.cxx b/configmgr/source/misc/providerfactory.cxx
new file mode 100644
index 000000000000..1cb726742185
--- /dev/null
+++ b/configmgr/source/misc/providerfactory.cxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: providerfactory.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+
+#include "providerfactory.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include "bootstrap.hxx"
+#include "providerwrapper.hxx"
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
+#include <cppuhelper/exc_hlp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <rtl/logfile.hxx>
+
+//---------------------------------------------------------------------------------------
+namespace configmgr
+{
+ //---------------------------------------------------------------------------------------
+ //= OProviderFactory
+ //---------------------------------------------------------------------------------------
+
+ //---------------------------------------------------------------------------------------
+
+ ProviderFactory::ProviderFactory(rtl::OUString const & aImplementationName, bool bAdmin)
+ : m_aImplementationName(aImplementationName)
+ , m_bAdmin(bAdmin)
+ {
+ }
+ //---------------------------------------------------------------------------------------
+
+ ProviderFactory::~ProviderFactory()
+ {
+ }
+ //---------------------------------------------------------------------------------------
+
+ uno::Reference< uno::XInterface > ProviderFactory::getProviderAlways(uno::Reference< uno::XComponentContext > const & xContext)
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::ProviderFactory", "jb99855", "configmgr::ProviderFactory::getProviderAlways()");
+ uno::Reference< uno::XInterface > xResult = getDefaultConfigProviderSingleton(xContext);
+
+ // check for success
+ OSL_ENSURE(xResult.is(), "Context could not create provider, but returned NULL instead of throwing an exception");
+ if (!xResult.is())
+ {
+ static sal_Char const sCannotCreate[] = "Cannot create ConfigurationProvider. Unknown backend or factory error.";
+
+ throw com::sun::star::configuration::CannotLoadConfigurationException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sCannotCreate)), *this );
+ }
+
+ return xResult;
+ }
+ //---------------------------------------------------------------------------------------
+ uno::Reference< uno::XInterface > ProviderFactory::getProviderFromContext(uno::Reference< uno::XComponentContext > const & xContext)
+ {
+ OSL_ENSURE(ContextReader::testAdminService(xContext, this->m_bAdmin),
+ "Creation context admin flag does not match service being created");
+
+ try
+ {
+ return getProviderAlways(xContext);
+ }
+ catch(uno::Exception& e)
+ {
+ ContextReader aContext(xContext);
+
+ uno::Any aError = aContext.getBootstrapError();
+ if (aError.hasValue())
+ {
+ OSL_ASSERT(aError.getValueTypeClass() == uno::TypeClass_EXCEPTION);
+ cppu::throwException(aError);
+ }
+
+ OSL_ASSERT(aContext.isBootstrapValid());
+
+ static const sal_Char sErrContext[] = "Cannot open Configuration: ";
+ rtl::OUString const sContext(RTL_CONSTASCII_USTRINGPARAM(sErrContext));
+ e.Message = sContext.concat(e.Message);
+ throw;
+ }
+ }
+ //---------------------------------------------------------------------------------------
+ uno::Reference< uno::XInterface > ProviderFactory::createProviderWithArguments(uno::Reference< uno::XComponentContext > const & xContext, uno::Sequence < uno::Any > const & _aArguments)
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::ProviderFactory", "jb99855", "configmgr::ProviderFactory::createProviderWithArguments()");
+
+ ContextReader aContext(xContext);
+ ArgumentHelper aParser(aContext.getBootstrapContext());
+
+ uno::Sequence < beans::NamedValue > aValues(_aArguments.getLength() + 2);
+ sal_Int32 nCount = parseArguments(aParser,aValues,_aArguments);
+
+ bool bNeedNewBackend = aParser.hasBackendArguments();
+
+ if (!aContext.testAdminService(aContext.getBaseContext(),m_bAdmin))
+ {
+ bNeedNewBackend = true;
+ OSL_ASSERT( nCount+2 <= aValues.getLength());
+ aValues[nCount++] = ArgumentHelper::makeAdminServiceOverride(m_bAdmin);
+ aValues[nCount++] = BootstrapContext::makePassthroughMarker(sal_False);
+ }
+
+ OSL_ASSERT(nCount <= aValues.getLength());
+ aValues.realloc(nCount);
+
+ if (bNeedNewBackend)
+ {
+ uno::Reference< uno::XComponentContext > xMergedContext = BootstrapContext::createWrapper(xContext,aValues);
+ uno::Reference< uno::XInterface > xResult = getProviderFromContext(xMergedContext);
+
+ return xResult;
+ }
+ else
+ {
+ uno::Reference< uno::XInterface > xBaseProvider = getProviderFromContext(xContext);
+ uno::Reference< uno::XInterface > xResult = ProviderWrapper::create(xBaseProvider,aValues);
+
+ return xResult;
+ }
+ }
+ //---------------------------------------------------------------------------------------
+ uno::Reference< uno::XInterface > ProviderFactory::createProvider(uno::Reference< uno::XComponentContext > const & xContext, bool bAdmin)
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::ProviderFactory", "jb99855", "configmgr::ProviderFactory::createProvider(bAdmin)");
+
+ uno::Sequence < beans::NamedValue > aValues(2);
+ aValues[0] = ArgumentHelper::makeAdminServiceOverride(bAdmin);
+ aValues[1] = BootstrapContext::makePassthroughMarker(sal_False);
+
+ uno::Reference< uno::XComponentContext > xMergedContext = BootstrapContext::createWrapper(xContext,aValues);
+ uno::Reference< uno::XInterface > xResult = getProviderFromContext(xMergedContext);
+
+ return xResult;
+ }
+ //---------------------------------------------------------------------------------------
+ uno::Reference< uno::XInterface > ProviderFactory::createProvider(uno::Reference< uno::XComponentContext > const & xContext)
+ {
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::ProviderFactory", "jb99855", "configmgr::ProviderFactory::createProvider()");
+
+ if (BootstrapContext::isPassthrough(xContext))
+ {
+ // make sure this uses a new BootstrapContext !
+ uno::Reference< uno::XComponentContext > xPatchedContext = BootstrapContext::createWrapper(xContext,uno::Sequence < beans::NamedValue >());
+ return getProviderFromContext(xPatchedContext);
+ }
+ else
+ return getProviderFromContext(xContext);
+ }
+ //---------------------------------------------------------------------------------------
+
+ sal_Int32 ProviderFactory::parseArguments(ArgumentHelper & aParser, uno::Sequence < beans::NamedValue > & rValues, uno::Sequence < uno::Any > const & _aArguments)
+ {
+ OSL_ASSERT(rValues.getLength() >= _aArguments.getLength());
+
+ sal_Int32 nCount = 0;
+ for (sal_Int32 i = 0; i < _aArguments.getLength(); ++i)
+ {
+ if (!aParser.extractArgument(rValues[nCount],_aArguments[i]))
+ {
+ rtl::OUStringBuffer sMsg;
+ sMsg.appendAscii("ProviderFactory: Unexpected Argument Type. ");
+ sMsg.appendAscii("Expected NamedValue or PropertyValue, ");
+ sMsg.appendAscii("found ").append(_aArguments[i].getValueTypeName()).appendAscii(". ");
+ throw lang::IllegalArgumentException(sMsg.makeStringAndClear(),*this,static_cast<sal_Int16>(i));
+ }
+
+ if (aParser.filterAndAdjustArgument(rValues[nCount]))
+ {
+ aParser.checkBackendArgument(rValues[nCount]);
+ ++nCount;
+ }
+ }
+ return nCount;
+ }
+ //---------------------------------------------------------------------------------------
+
+ uno::Reference< uno::XInterface >
+ SAL_CALL ProviderFactory::createInstanceWithContext( const uno::Reference< uno::XComponentContext >& xContext )
+ throw (uno::Exception, ::com::sun::star::uno::RuntimeException)
+ {
+ // default provider ?
+ if (ContextReader::testAdminService(xContext,m_bAdmin))
+ return createProvider( xContext );
+
+ else
+ return createProvider(xContext,m_bAdmin);
+ }
+ //---------------------------------------------------------------------------------------
+
+ uno::Reference< uno::XInterface > SAL_CALL
+ ProviderFactory::createInstanceWithArgumentsAndContext( const uno::Sequence< uno::Any >& aArguments, const uno::Reference< uno::XComponentContext >& xContext )
+ throw (uno::Exception, uno::RuntimeException)
+ {
+ // default request
+ return createProviderWithArguments(xContext, aArguments);
+ }
+
+ //---------------------------------------------------------------------------------------
+ //---------------------------------------------------------------------------------------
+
+ uno::Reference< lang::XSingleComponentFactory > SAL_CALL createProviderFactory(
+ rtl::OUString const & aImplementationName,
+ bool bAdmin
+ )
+ {
+ return new ProviderFactory(aImplementationName, bAdmin);
+ }
+ //---------------------------------------------------------------------------------------
+} // namespace configmgr
+//........................................................................
+
diff --git a/configmgr/source/misc/providerfactory.hxx b/configmgr/source/misc/providerfactory.hxx
new file mode 100644
index 000000000000..ef3e879b7059
--- /dev/null
+++ b/configmgr/source/misc/providerfactory.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: providerfactory.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_PROVIDER_FACTORY_HXX_
+#define _CONFIGMGR_PROVIDER_FACTORY_HXX_
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+/*
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/stl_types.hxx>
+*/
+//------------------------------------------------------------------------
+namespace configmgr
+{
+ //------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace beans = ::com::sun::star::beans;
+ //------------------------------------------------------------------------
+ class ContextReader;
+ class ArgumentHelper;
+ //------------------------------------------------------------------------
+ //= OProviderFactory
+ //------------------------------------------------------------------------
+ /** a special factory for the configuration provider,
+ which maps creation arguments into a context.
+ */
+ class ProviderFactory : public cppu::WeakImplHelper1< lang::XSingleComponentFactory >
+ {
+ rtl::OUString const m_aImplementationName;
+ bool m_bAdmin;
+
+ public:
+ explicit
+ ProviderFactory(rtl::OUString const & aImplementationName, bool bAdmin);
+ ~ProviderFactory();
+
+ virtual uno::Reference< uno::XInterface >
+ SAL_CALL createInstanceWithContext(uno::Reference< uno::XComponentContext > const & xContext )
+ throw (uno::Exception, uno::RuntimeException);
+
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstanceWithArgumentsAndContext( uno::Sequence < uno::Any > const & aArguments, uno::Reference< uno::XComponentContext > const & xContext )
+ throw (uno::Exception, uno::RuntimeException);
+
+ private:
+ uno::Reference< uno::XInterface > getProviderFromContext(uno::Reference< uno::XComponentContext > const & aContext);
+ uno::Reference< uno::XInterface > getProviderAlways(uno::Reference< uno::XComponentContext > const & xContext);
+ uno::Reference< uno::XInterface > createProviderWithArguments(uno::Reference< uno::XComponentContext > const & xContext, uno::Sequence < uno::Any > const & _aArguments);
+ uno::Reference< uno::XInterface > createProvider(uno::Reference< uno::XComponentContext > const & xContext,bool bAdmin);
+ uno::Reference< uno::XInterface > createProvider(uno::Reference< uno::XComponentContext > const & xContext);
+ sal_Int32 parseArguments(ArgumentHelper & aParser, uno::Sequence < beans::NamedValue > & rValues, uno::Sequence < uno::Any > const & _aArguments);
+ };
+//------------------------------------------------------------------------
+} // namespace configmgr
+//------------------------------------------------------------------------
+
+#endif // _CONFIGMGR_PROVIDER_FACTORY_HXX_
+
diff --git a/configmgr/source/misc/providerwrapper.cxx b/configmgr/source/misc/providerwrapper.cxx
new file mode 100644
index 000000000000..b350c3ed5865
--- /dev/null
+++ b/configmgr/source/misc/providerwrapper.cxx
@@ -0,0 +1,196 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: providerwrapper.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "providerwrapper.hxx"
+#include "bootstrap.hxx"
+#include "bootstrapcontext.hxx"
+
+
+#include <com/sun/star/lang/NullPointerException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include <algorithm>
+
+
+namespace configmgr
+{
+ //==========================================================================
+ namespace uno = com::sun::star::uno;
+ namespace lang = com::sun::star::lang;
+ //==========================================================================
+ //= ProviderWrapper
+ //==========================================================================
+
+ uno::Reference< uno::XInterface > ProviderWrapper::create( uno::Reference< uno::XInterface > xDelegate, uno::Sequence< com::sun::star::beans::NamedValue > const & aPresets)
+ {
+ uno::Reference< lang::XMultiServiceFactory > xProvDelegate(xDelegate, uno::UNO_QUERY);
+ if (!xProvDelegate.is())
+ {
+ rtl::OUString sMsg(RTL_CONSTASCII_USTRINGPARAM("ProviderWrapper: Cannot wrap a NULL provider"));
+ throw lang::NullPointerException(sMsg,NULL);
+ }
+ //Strip prefixes
+ uno::Sequence< com::sun::star::beans::NamedValue > aStrippedPresets = aPresets;
+
+ for (sal_Int32 i = 0; i < aPresets.getLength(); ++i)
+ {
+ if(aPresets[i].Name.matchAsciiL(RTL_CONSTASCII_STRINGPARAM(CONTEXT_ITEM_PREFIX_ )))
+ {
+ aStrippedPresets[i].Name = aPresets[i].Name.copy(RTL_CONSTASCII_LENGTH(CONTEXT_ITEM_PREFIX_ ));
+ }
+ }
+
+ uno::Reference< lang::XMultiServiceFactory > xResult( new ProviderWrapper(xProvDelegate,aStrippedPresets) );
+
+ DisposingForwarder::forward( uno::Reference< lang::XComponent >::query(xProvDelegate),uno::Reference< lang::XComponent >::query(xResult) );
+ return uno::Reference< uno::XInterface >( xResult, uno::UNO_QUERY );
+ }
+
+
+ ProviderWrapper::ProviderWrapper(uno::Reference< lang::XMultiServiceFactory > const & xDelegate, uno::Sequence< com::sun::star::beans::NamedValue > const & aPresets)
+ : cppu::WeakComponentImplHelper2< lang::XMultiServiceFactory, lang::XServiceInfo >( PWMutexHolder::mutex )
+ , m_xDelegate(xDelegate)
+ , m_aDefaults(aPresets.getLength())
+ {
+ OSL_ASSERT(m_xDelegate.is());
+
+ for (sal_Int32 i = 0; i<aPresets.getLength(); ++i)
+ {
+ m_aDefaults[i] <<= aPresets[i];
+ }
+ }
+
+ ProviderWrapper::~ProviderWrapper() {}
+
+ void SAL_CALL ProviderWrapper::disposing()
+ {
+ osl::MutexGuard lock(mutex);
+ m_xDelegate.clear();
+ }
+
+ uno::Reference< lang::XMultiServiceFactory > ProviderWrapper::getDelegate()
+ {
+ osl::MutexGuard lock(mutex);
+ if (!m_xDelegate.is())
+ {
+ rtl::OUString sMsg(RTL_CONSTASCII_USTRINGPARAM("ProviderWrapper: Delegate Provider has been disposed"));
+ throw lang::DisposedException(sMsg,*this);
+ }
+ return m_xDelegate;
+ }
+
+
+ uno::Reference<lang::XServiceInfo> ProviderWrapper::getDelegateInfo()
+ {
+ uno::Reference<lang::XServiceInfo> xDelegate( this->getDelegate(), uno::UNO_QUERY );
+ if (!xDelegate.is())
+ {
+ rtl::OUString sMsg(RTL_CONSTASCII_USTRINGPARAM("ProviderWrapper: Delegate Provider has no service info"));
+ throw uno::RuntimeException(sMsg,*this);
+ }
+ return xDelegate;
+ }
+
+ /// XMultiServiceFactory
+ static inline uno::Any const * begin(uno::Sequence< uno::Any > const & aArgs)
+ { return aArgs.getConstArray(); }
+ static inline uno::Any const * end(uno::Sequence< uno::Any > const & aArgs)
+ { return aArgs.getConstArray() + aArgs.getLength(); }
+ static inline uno::Any * begin(uno::Sequence< uno::Any > & aArgs)
+ { return aArgs.getArray(); }
+ static inline uno::Any * end(uno::Sequence< uno::Any > & aArgs)
+ { return aArgs.getArray() + aArgs.getLength(); }
+
+ uno::Sequence< uno::Any > ProviderWrapper::patchArguments(uno::Sequence< uno::Any > const & aArgs) const
+ {
+ // rely on evaluation order front to back
+ if (m_aDefaults.getLength() == 0) return aArgs;
+
+ uno::Sequence< uno::Any > aResult(m_aDefaults.getLength() + aArgs.getLength());
+
+ uno::Any * pNext = std::copy(begin(m_aDefaults),end(m_aDefaults),begin(aResult));
+ pNext = std::copy(begin(aArgs),end(aArgs),pNext);
+
+ OSL_ASSERT(end(aResult) == pNext);
+
+ return aResult;
+ }
+
+ uno::Reference< uno::XInterface > SAL_CALL
+ ProviderWrapper::createInstance( const rtl::OUString& aServiceSpecifier )
+ throw(uno::Exception, uno::RuntimeException)
+ {
+ return getDelegate()->createInstanceWithArguments(aServiceSpecifier,m_aDefaults);
+ }
+
+ uno::Reference< uno::XInterface > SAL_CALL
+ ProviderWrapper::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const uno::Sequence< uno::Any >& rArguments )
+ throw(uno::Exception, uno::RuntimeException)
+ {
+ return getDelegate()->createInstanceWithArguments(ServiceSpecifier,patchArguments(rArguments));
+ }
+
+ uno::Sequence< rtl::OUString > SAL_CALL
+ ProviderWrapper::getAvailableServiceNames( )
+ throw(uno::RuntimeException)
+ {
+ return getDelegate()->getAvailableServiceNames( );
+ }
+
+ /// XServiceInfo
+ rtl::OUString SAL_CALL
+ ProviderWrapper::getImplementationName( )
+ throw(uno::RuntimeException)
+ {
+ return rtl::OUString::createFromAscii("com.sun.star.comp.configuration.ConfigurationProviderWrapper");
+ }
+
+ sal_Bool SAL_CALL
+ ProviderWrapper::supportsService( const ::rtl::OUString& ServiceName )
+ throw(uno::RuntimeException)
+ {
+ return getDelegateInfo()->supportsService( ServiceName );
+ }
+
+ uno::Sequence< rtl::OUString > SAL_CALL
+ ProviderWrapper::getSupportedServiceNames( )
+ throw(uno::RuntimeException)
+ {
+ return getDelegateInfo()->getSupportedServiceNames( );
+ }
+
+
+} // namespace configmgr
+
+
+
diff --git a/configmgr/source/misc/providerwrapper.hxx b/configmgr/source/misc/providerwrapper.hxx
new file mode 100644
index 000000000000..a8848d4cce7c
--- /dev/null
+++ b/configmgr/source/misc/providerwrapper.hxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: providerwrapper.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_API_PROVIDERWRAPPER_HXX_
+#define CONFIGMGR_API_PROVIDERWRAPPER_HXX_
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <cppuhelper/compbase2.hxx>
+#include <osl/mutex.hxx>
+
+namespace configmgr
+{
+ //==========================================================================
+ namespace uno = com::sun::star::uno;
+ namespace lang = com::sun::star::lang;
+ //==========================================================================
+ //= ProviderWrapper
+ //==========================================================================
+ struct PWMutexHolder { osl::Mutex mutex; }; // ad hoc ...
+
+ class ProviderWrapper : private PWMutexHolder, public cppu::WeakComponentImplHelper2< lang::XMultiServiceFactory, lang::XServiceInfo >
+ {
+ private:
+ uno::Reference< lang::XMultiServiceFactory > m_xDelegate;
+ uno::Sequence< uno::Any > m_aDefaults;
+ private:
+ ProviderWrapper(uno::Reference< lang::XMultiServiceFactory > const & xDelegate, uno::Sequence< com::sun::star::beans::NamedValue > const & aPresets);
+
+ public:
+ static uno::Reference< uno::XInterface > create( uno::Reference< uno::XInterface > xDelegate, uno::Sequence< com::sun::star::beans::NamedValue > const & aPresets);
+ ~ProviderWrapper();
+
+ /// XMultiServiceFactory
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstance( const rtl::OUString& aServiceSpecifier )
+ throw(uno::Exception, uno::RuntimeException);
+
+ virtual uno::Reference< uno::XInterface > SAL_CALL
+ createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const uno::Sequence< uno::Any >& Arguments )
+ throw(uno::Exception, uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getAvailableServiceNames( )
+ throw(uno::RuntimeException);
+
+ /// XServiceInfo
+ virtual rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw(uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& ServiceName )
+ throw(uno::RuntimeException);
+
+ virtual uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw(uno::RuntimeException);
+
+ protected:
+ virtual void SAL_CALL disposing();
+ private:
+ uno::Reference< lang::XMultiServiceFactory > getDelegate();
+ uno::Reference<lang::XServiceInfo> getDelegateInfo();
+ uno::Sequence< uno::Any > patchArguments(uno::Sequence< uno::Any > const & aArgs) const;
+ };
+
+
+} // namespace configmgr
+
+#endif // CONFIGMGR_API_CONFPROVIDER2_HXX_
+
+
diff --git a/configmgr/source/misc/requestoptions.cxx b/configmgr/source/misc/requestoptions.cxx
new file mode 100644
index 000000000000..75ed08511edb
--- /dev/null
+++ b/configmgr/source/misc/requestoptions.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: requestoptions.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "requestoptions.hxx"
+#include "matchlocale.hxx"
+#include "tracer.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+
+ rtl::OUString RequestOptions::getIsoLocale() const
+ {
+ return localehelper::makeIsoLocale( m_sLocale );
+ }
+// ---------------------------------------------------------------------------
+
+ bool RequestOptions::isForAllLocales() const
+ {
+ return localehelper::designatesAllLocales( m_sLocale );
+ }
+// ---------------------------------------------------------------------------
+
+ void RequestOptions::setIsoLocale(rtl::OUString const & _sLocale)
+ {
+ setLocale( localehelper::makeLocale( _sLocale ) );
+ }
+// ---------------------------------------------------------------------------
+
+ void RequestOptions::setAllLocales()
+ {
+ m_sLocale = localehelper::getAnyLocale();
+ }
+// ---------------------------------------------------------------------------
+
+ void RequestOptions::ensureLocaleSet()
+ {
+ if (!hasLocale())
+ m_sLocale = localehelper::getDefaultLocale();
+ }
+// ---------------------------------------------------------------------------
+
+ static inline
+ sal_Int32 hashRequestLocale(com::sun::star::lang::Locale const & aLocale)
+ {
+ return aLocale.Language.hashCode() ^ aLocale.Country.hashCode();
+ }
+// ---------------------------------------------------------------------------
+
+ static inline
+ sal_Int32 compareRequestLocale(com::sun::star::lang::Locale const& lhs, com::sun::star::lang::Locale const& rhs)
+ {
+ sal_Int32 nDiff = lhs.Language.compareTo(rhs.Language);
+ if (nDiff == 0)
+ {
+ nDiff = lhs.Country.compareTo(rhs.Country);
+ }
+
+ return nDiff;
+ }
+// ---------------------------------------------------------------------------
+
+ sal_Int32 compareRequestOptions(RequestOptions const& lhs, RequestOptions const& rhs)
+ {
+ sal_Int32 nDiff = lhs.getEntity().compareTo(rhs.getEntity());
+ if (nDiff == 0)
+ {
+ nDiff = compareRequestLocale(lhs.getUnoLocale(),rhs.getUnoLocale());
+ }
+
+ return nDiff;
+ }
+// ---------------------------------------------------------------------------
+} // namespace config
+
+
diff --git a/configmgr/source/misc/serviceinfohelper.cxx b/configmgr/source/misc/serviceinfohelper.cxx
new file mode 100644
index 000000000000..f96e3f548402
--- /dev/null
+++ b/configmgr/source/misc/serviceinfohelper.cxx
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: serviceinfohelper.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "serviceinfohelper.hxx"
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+
+ sal_Int32 ServiceInfoHelper::countServices( ) const
+ {
+ if (m_info == 0)
+ return 0;
+
+ sal_Int32 nCount = 0;
+ if (sal_Char const * const* p= m_info->registeredServiceNames)
+ {
+ while (*p != 0)
+ {
+ ++nCount;
+ ++p;
+ }
+ }
+ if (sal_Char const * const* p= m_info->additionalServiceNames)
+ {
+ while (*p != 0)
+ {
+ ++nCount;
+ ++p;
+ }
+ }
+
+ return nCount;
+ }
+// ---------------------------------------------------------------------------
+
+ rtl::OUString ServiceInfoHelper::getImplementationName( ) const
+ throw(uno::RuntimeException)
+ {
+ sal_Char const * p= m_info ? m_info->implementationName : 0;
+
+ return p ? rtl::OUString::createFromAscii(p) : rtl::OUString();
+ }
+// ---------------------------------------------------------------------------
+
+ sal_Bool ServiceInfoHelper::supportsService( rtl::OUString const & ServiceName ) const
+ throw(uno::RuntimeException)
+ {
+ if (m_info == 0)
+ return false;
+
+ if (sal_Char const * const* p= m_info->registeredServiceNames)
+ {
+ while (*p != 0)
+ {
+ if (ServiceName.equalsAscii(*p))
+ return true;
+ ++p;
+ }
+ }
+ if (sal_Char const * const* p= m_info->additionalServiceNames)
+ {
+ while (*p != 0)
+ {
+ if (ServiceName.equalsAscii(*p))
+ return true;
+ ++p;
+ }
+ }
+
+ return false;
+ }
+// ---------------------------------------------------------------------------
+
+ uno::Sequence< rtl::OUString > ServiceInfoHelper::getSupportedServiceNames( ) const
+ throw(uno::RuntimeException)
+ {
+ sal_Int32 const nCount = countServices();
+
+ uno::Sequence< rtl::OUString > aServices( nCount );
+
+ if (nCount)
+ {
+ OSL_ASSERT(m_info);
+ sal_Int32 i = 0;
+ if (sal_Char const * const* p= m_info->registeredServiceNames)
+ {
+ while (*p != 0)
+ {
+ aServices[i++] = rtl::OUString::createFromAscii(*p++);
+ }
+ }
+ if (sal_Char const * const* p= m_info->additionalServiceNames)
+ {
+ while (*p != 0)
+ {
+ aServices[i++] = rtl::OUString::createFromAscii(*p++);
+ }
+ }
+ OSL_ASSERT( i == nCount );
+ }
+
+ return aServices;
+ }
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+
+ sal_Int32 ServiceRegistrationHelper::countServices( ) const
+ {
+ if (m_info == 0)
+ return 0;
+
+ sal_Int32 nCount = 0;
+ if (sal_Char const * const* p= m_info->registeredServiceNames)
+ {
+ while (*p != 0)
+ {
+ ++nCount;
+ ++p;
+ }
+ }
+
+ return nCount;
+ }
+// ---------------------------------------------------------------------------
+
+ rtl::OUString ServiceRegistrationHelper::getImplementationName( ) const
+ throw(uno::RuntimeException)
+ {
+ sal_Char const * p= m_info ? m_info->implementationName : 0;
+
+ return p ? rtl::OUString::createFromAscii(p) : rtl::OUString();
+ }
+// ---------------------------------------------------------------------------
+
+ uno::Sequence< rtl::OUString > ServiceRegistrationHelper::getRegisteredServiceNames( ) const
+ throw(uno::RuntimeException)
+ {
+ sal_Int32 const nCount = countServices();
+
+ uno::Sequence< rtl::OUString > aServices( nCount );
+
+ if (nCount)
+ {
+ OSL_ASSERT(m_info);
+ sal_Int32 i = 0;
+ if (sal_Char const * const* p= m_info->registeredServiceNames)
+ {
+ while (*p != 0)
+ {
+ aServices[i++] = rtl::OUString::createFromAscii(*p++);
+ }
+ }
+ OSL_ASSERT( i == nCount );
+ }
+
+ return aServices;
+ }
+// ---------------------------------------------------------------------------
+} // namespace config
+
+
diff --git a/configmgr/source/misc/simpleinteractionrequest.cxx b/configmgr/source/misc/simpleinteractionrequest.cxx
new file mode 100644
index 000000000000..254b4165ed2b
--- /dev/null
+++ b/configmgr/source/misc/simpleinteractionrequest.cxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: simpleinteractionrequest.cxx,v $
+ * $Revision: 1.5.18.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "simpleinteractionrequest.hxx"
+
+namespace configmgr { namespace apihelper {
+
+namespace uno = com::sun::star::uno;
+namespace task = com::sun::star::task;
+//=========================================================================
+SimpleInteractionRequest::SimpleInteractionRequest(
+ const uno::Any & rRequest,
+ const sal_uInt32 nContinuations )
+: InteractionRequest( rRequest )
+{
+ // Set continuations.
+ OSL_ENSURE( nContinuations != CONTINUATION_UNKNOWN,
+ "SimpleInteractionRequest - No continuation!" );
+
+ sal_Int32 nLength = 0;
+
+ const sal_uInt32 k_NumContinuationTypes = 4;
+ uno::Reference< task::XInteractionContinuation > xContinuations[ k_NumContinuationTypes ];
+
+ if ( nContinuations & CONTINUATION_ABORT )
+ xContinuations[nLength++] = new InteractionContinuation< task::XInteractionAbort >( this );
+
+ if ( nContinuations & CONTINUATION_RETRY )
+ xContinuations[nLength++] = new InteractionContinuation< task::XInteractionRetry >( this );
+
+ if ( nContinuations & CONTINUATION_APPROVE )
+ xContinuations[nLength++] = new InteractionContinuation< task::XInteractionApprove >( this );
+
+ if ( nContinuations & CONTINUATION_DISAPPROVE )
+ xContinuations[nLength++] = new InteractionContinuation< task::XInteractionDisapprove >( this );
+
+ OSL_ENSURE( nLength > 0,
+ "SimpleInteractionRequest - No continuation!" );
+
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > >
+ aContinuations( xContinuations, nLength );
+
+ this->setContinuations( aContinuations );
+}
+
+//=========================================================================
+sal_uInt32 SimpleInteractionRequest::getResponse() const
+{
+ uno::Reference< task::XInteractionContinuation > xSelection = this->getSelection();
+ if ( xSelection.is() )
+ {
+ if ( uno::Reference< task::XInteractionApprove >::query(xSelection).is() )
+ return CONTINUATION_APPROVE;
+
+ if ( uno::Reference< task::XInteractionDisapprove >::query(xSelection).is() )
+ return CONTINUATION_DISAPPROVE;
+
+ if ( uno::Reference< task::XInteractionRetry >::query(xSelection).is() )
+ return CONTINUATION_RETRY;
+
+ if ( uno::Reference< task::XInteractionAbort >::query(xSelection).is() )
+ return CONTINUATION_ABORT;
+
+ OSL_ENSURE( sal_False,
+ "SimpleInteractionRequest::getResponse - Unknown continuation!" );
+ }
+ return CONTINUATION_UNKNOWN;
+}
+
+} }
diff --git a/configmgr/source/misc/strimpl.cxx b/configmgr/source/misc/strimpl.cxx
new file mode 100644
index 000000000000..3b82f40b850a
--- /dev/null
+++ b/configmgr/source/misc/strimpl.cxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: strimpl.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "strdecl.hxx"
+
+namespace configmgr
+{
+ // simple types names
+ IMPLEMENT_CONSTASCII_USTRING(TYPE_BOOLEAN, "boolean");
+ IMPLEMENT_CONSTASCII_USTRING(TYPE_SHORT, "short");
+ IMPLEMENT_CONSTASCII_USTRING(TYPE_INT, "int");
+ IMPLEMENT_CONSTASCII_USTRING(TYPE_LONG, "long");
+ IMPLEMENT_CONSTASCII_USTRING(TYPE_DOUBLE, "double");
+ IMPLEMENT_CONSTASCII_USTRING(TYPE_STRING, "string");
+ // Type: Sequence<bytes>
+ IMPLEMENT_CONSTASCII_USTRING(TYPE_BINARY, "binary");
+ // Universal type: Any
+ IMPLEMENT_CONSTASCII_USTRING(TYPE_ANY, "any");
+
+ // special template names for native/localized value types
+ IMPLEMENT_CONSTASCII_USTRING(TEMPLATE_MODULE_NATIVE_PREFIX, "cfg:");
+ IMPLEMENT_CONSTASCII_USTRING(TEMPLATE_MODULE_NATIVE_VALUE, "cfg:value");
+ IMPLEMENT_CONSTASCII_USTRING(TEMPLATE_MODULE_LOCALIZED_VALUE, "cfg:localized");
+
+ IMPLEMENT_CONSTASCII_USTRING(TEMPLATE_LIST_SUFFIX, "-list");
+
+
+
+// emacs:
+// create the declare from the implement
+// (fset 'create-declare-from-implement
+// [home M-right ?\C- ?\C-s ?, left right left ?\M-w f12 return up tab ?D ?E ?C ?L ?A ?R ?E ?\C-y ?) ?; home down f12 home down])
+
+} // namespace configmgr
diff --git a/configmgr/source/misc/tracer.cxx b/configmgr/source/misc/tracer.cxx
new file mode 100644
index 000000000000..bb2fe993fb34
--- /dev/null
+++ b/configmgr/source/misc/tracer.cxx
@@ -0,0 +1,474 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tracer.cxx,v $
+ * $Revision: 1.21 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+// SUNPRO5 does not like the following to be done after including stdio.h, that's why it's here at the very
+// beginning of the file
+#undef _TIME_T_DEFINED
+#include <time.h>
+#include <rtl/string.hxx>
+#include <map>
+
+#include "tracer.hxx"
+
+#ifdef CFG_ENABLE_TRACING
+
+#include <cstdarg>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <osl/process.h>
+#include <osl/thread.h>
+#include <osl/diagnose.h>
+#include <rtl/ustring.hxx>
+#include <rtl/instance.hxx>
+
+namespace configmgr
+{
+
+extern "C"
+{
+ static void call_freeThreadData(void*);
+}
+
+struct OTracerSetup
+{
+ enum {
+ INFO = 0x01,
+ WARNING = 0x02,
+ ERROR = 0x04,
+ LEVEL_MASK = 0x0f,
+
+ TIME = 0x10,
+ THREAD = 0x20,
+ DATA_MASK = 0xf0
+ };
+
+ sal_uInt32 m_nTraceMask;
+ FILE* m_pOutputMedium;
+ sal_Bool m_bInitialized;
+ oslThreadKey m_nThreadKey;
+
+ ::std::map< ::rtl::OString, void*, ::std::less< ::rtl::OString > > m_aDevices;
+
+ OTracerSetup()
+ :m_nTraceMask(WARNING | ERROR)
+ ,m_pOutputMedium(NULL)
+ ,m_bInitialized(sal_False)
+ {
+ m_nThreadKey = ::osl_createThreadKey(call_freeThreadData);
+ }
+ ~OTracerSetup()
+ {
+ ::osl_destroyThreadKey(m_nThreadKey);
+ }
+
+ bool isTracing(sal_uInt32 nTraceValue) const
+ { return (nTraceValue & this->m_nTraceMask) == nTraceValue; }
+
+ void setTracing(sal_uInt32 nTraceValue)
+ { this->m_nTraceMask |= nTraceValue; }
+
+ void setTracing(sal_uInt32 nTraceValue, sal_uInt32 nMask)
+ {
+ OSL_ENSURE( (nTraceValue&nMask) == nTraceValue, "Flags being set must be part of mask");
+ this->m_nTraceMask &= ~nMask;
+ this->m_nTraceMask |= nTraceValue;
+ }
+
+ sal_Int32& indentDepth();
+
+ struct ThreadData
+ {
+ ThreadData() : m_nIndentDepth(0) {}
+ sal_Int32 m_nIndentDepth;
+ };
+
+ ThreadData& ensureThreadData();
+ static void freeThreadData(void*p);
+};
+
+//==========================================================================
+//= OConfigTracer
+//==========================================================================
+OTracerSetup* OConfigTracer::s_pImpl = NULL;
+#ifdef WNT
+timeb OConfigTracer::s_aStartTime;
+#else
+timeval OConfigTracer::s_aStartTime;
+#endif
+
+::osl::Mutex & OConfigTracer::getMutex()
+{
+ return rtl::Static<osl::Mutex,OConfigTracer>::get();
+}
+//--------------------------------------------------------------------------
+void OConfigTracer::startGlobalTimer()
+{
+#ifdef WNT
+ ftime( &s_aStartTime );
+#else
+ gettimeofday( &s_aStartTime, NULL );
+#endif
+}
+
+//--------------------------------------------------------------------------
+sal_uInt32 OConfigTracer::getGlobalTimer()
+{
+#ifdef WNT
+ struct timeb currentTime;
+ sal_uInt32 nSeconds;
+ ftime( &currentTime );
+ nSeconds = (sal_uInt32)( currentTime.time - s_aStartTime.time );
+ return ( nSeconds * 1000 ) + (long)( currentTime.millitm - s_aStartTime.millitm );
+#else
+ struct timeval currentTime;
+ sal_uInt32 nSeconds;
+ gettimeofday( &currentTime, NULL );
+ nSeconds = (sal_uInt32)( currentTime.tv_sec - s_aStartTime.tv_sec );
+ return ( nSeconds * 1000 ) + (long)( currentTime.tv_usec - s_aStartTime.tv_usec )/1000;
+#endif
+}
+
+//--------------------------------------------------------------------------
+sal_Int32& OTracerSetup::indentDepth()
+{
+ return ensureThreadData().m_nIndentDepth;
+}
+
+//--------------------------------------------------------------------------
+OTracerSetup::ThreadData& OTracerSetup::ensureThreadData()
+{
+ void * pThreadData = ::osl_getThreadKeyData(m_nThreadKey);
+
+ OTracerSetup::ThreadData* pRet
+ = static_cast< OTracerSetup::ThreadData * >(pThreadData);
+
+ if (pRet == NULL)
+ {
+ pThreadData = pRet = new ThreadData();
+
+ if (!::osl_setThreadKeyData(m_nThreadKey,pThreadData))
+ {
+ OSL_ENSURE(false, "Cannot create per-thread data for tracing");
+ freeThreadData(pThreadData);
+
+ static ThreadData sharedThreadData;
+ pRet = &sharedThreadData;
+ }
+ else
+ OSL_ASSERT( pThreadData == ::osl_getThreadKeyData(m_nThreadKey) );
+
+ OSL_ASSERT( pRet != NULL );
+ }
+
+ return *pRet;
+}
+
+static void call_freeThreadData( void* p )
+{
+ OTracerSetup::freeThreadData( p );
+}
+
+//--------------------------------------------------------------------------
+void OTracerSetup::freeThreadData(void* p)
+{
+ delete static_cast< OTracerSetup::ThreadData * > (p);
+}
+
+//--------------------------------------------------------------------------
+void OConfigTracer::ensureData()
+{
+ if (s_pImpl)
+ return;
+ s_pImpl = new OTracerSetup;
+}
+
+//--------------------------------------------------------------------------
+void OConfigTracer::inc()
+{
+ ::osl::MutexGuard aGuard(getMutex());
+ ensureData();
+ ++s_pImpl->indentDepth();
+}
+
+//--------------------------------------------------------------------------
+void OConfigTracer::dec()
+{
+ ::osl::MutexGuard aGuard(getMutex());
+ ensureData();
+ --s_pImpl->indentDepth();
+}
+
+//--------------------------------------------------------------------------
+void OConfigTracer::traceInfo(const sal_Char* _pFormat, ...)
+{
+ ::osl::MutexGuard aGuard(getMutex());
+ ensureData();
+ ensureInitalized();
+ if (s_pImpl->isTracing(OTracerSetup::INFO) )
+ {
+
+
+ va_list args;
+ va_start(args, _pFormat);
+ implTrace("info", _pFormat, args);
+ va_end(args);
+ }
+}
+#if OSL_DEBUG_LEVEL > 0
+//--------------------------------------------------------------------------
+void OConfigTracer::traceWarning(const sal_Char* _pFormat, ...)
+{
+ ::osl::MutexGuard aGuard(getMutex());
+ ensureData();
+ ensureInitalized();
+ if (s_pImpl->isTracing(OTracerSetup::WARNING))
+ {
+ va_list args;
+ va_start(args, _pFormat);
+ implTrace("warning", _pFormat, args);
+ va_end(args);
+ }
+}
+
+//--------------------------------------------------------------------------
+void OConfigTracer::traceError(const sal_Char* _pFormat, ...)
+{
+ ::osl::MutexGuard aGuard(getMutex());
+ ensureData();
+ ensureInitalized();
+ if (s_pImpl->isTracing(OTracerSetup::ERROR))
+ {
+ va_list args;
+ va_start(args, _pFormat);
+ implTrace("error", _pFormat, args);
+ va_end(args);
+ }
+}
+#endif
+//--------------------------------------------------------------------------
+void OConfigTracer::indent()
+{
+ sal_Int32 nIndent = s_pImpl->indentDepth();
+ for (sal_Int32 i=0; i<nIndent; ++i)
+ fprintf(s_pImpl->m_pOutputMedium, " ");
+}
+
+//--------------------------------------------------------------------------
+FILE* disambiguate(const ::rtl::OString& _rFileName)
+{
+ FILE* pExistenceCheck = NULL;
+ sal_Int32 i = 1;
+ ::rtl::OString sLoop;
+ while (i <= 256)
+ {
+ sLoop = _rFileName;
+ sLoop += ".";
+ sLoop += ::rtl::OString::valueOf(i);
+
+ pExistenceCheck = fopen(sLoop.getStr(), "r");
+ if (!pExistenceCheck)
+ // does not exist
+ return fopen(sLoop.getStr(), "w+");
+
+ // already exists, try the next name
+ fclose(pExistenceCheck);
+ ++i;
+ }
+
+ // could not open such a file
+ return NULL;
+}
+
+//--------------------------------------------------------------------------
+void OConfigTracer::ensureInitalized()
+{
+ if (s_pImpl->m_bInitialized)
+ return;
+
+ s_pImpl->m_bInitialized = sal_True;
+
+ char* pSettings = getenv("ENVCFGFLAGS");
+ if (!pSettings)
+ return;
+
+ /* currently recognized structure :
+ + switches have to be separated by whitespaces
+ + valid switches are:
+ -m[e|o|f<file>] - output to stderr (e), stdout (o) or a file (f). In the latter case the whole rest
+ of the param ('til the next one, means 'til the next whitespace) is the filename
+ -t{i,w,e,p,d}* - type of output : i includes infos, w includes warnings, e includes errors
+ content : p includes timestamp, d includes thread-id
+ */
+
+ s_pImpl->m_pOutputMedium = stderr;
+ s_pImpl->setTracing(0, OTracerSetup::LEVEL_MASK);
+ s_pImpl->setTracing(0, OTracerSetup::DATA_MASK);
+
+ char* pParamLoop = pSettings;
+ while (*pParamLoop)
+ {
+ while (!isspace(*pParamLoop) && *pParamLoop)
+ ++pParamLoop;
+
+ sal_Int32 nLen = pParamLoop - pSettings;
+ if ((nLen > 1) && (*pSettings == '-'))
+ {
+ ++pSettings;
+ switch (*pSettings)
+ {
+ case 'm':
+ case 'w':
+ if (nLen > 2)
+ {
+ ++pSettings;
+ switch (*pSettings)
+ {
+ case 'e':
+ s_pImpl->m_pOutputMedium = stderr;
+ break;
+ case 'o':
+ s_pImpl->m_pOutputMedium = stdout;
+ break;
+ case 'f':
+ {
+ ++pSettings;
+ // copy the filename into an own buffer
+ ::rtl::OString sFileName(pSettings, pParamLoop - pSettings);
+
+ // open the file
+ s_pImpl->m_pOutputMedium = disambiguate(sFileName);
+
+ break;
+ }
+ }
+ }
+ break;
+ case 'd':
+ { // assign a virtual device
+ // copy the device assingment description
+ ::rtl::OString sDescription(pSettings + 1, pParamLoop - pSettings - 1);
+ sal_Int32 nSep = sDescription.indexOf(':');
+ if (-1 == nSep)
+ break; // invalid format
+
+ ::rtl::OString sVirtualDeviceName, sFileName;
+ sVirtualDeviceName = sDescription.copy(0, nSep);
+ sFileName = sDescription.copy(nSep + 1);
+
+ FILE* pVirtualDevice = disambiguate(sFileName);
+ if (pVirtualDevice)
+ s_pImpl->m_aDevices[sVirtualDeviceName] = pVirtualDevice;
+ }
+ case 't':
+ {
+ ++pSettings;
+ while (pSettings != pParamLoop)
+ {
+ switch (*pSettings)
+ {
+ case 'i': s_pImpl->setTracing( OTracerSetup::INFO ); break;
+ case 'w': s_pImpl->setTracing( OTracerSetup::WARNING ); break;
+ case 'e': s_pImpl->setTracing( OTracerSetup::ERROR ); break;
+ case 'p': s_pImpl->setTracing( OTracerSetup::TIME );
+ startGlobalTimer();
+ break;
+ case 'd': s_pImpl->setTracing( OTracerSetup::THREAD ); break;
+ }
+ ++pSettings;
+ }
+ }
+ }
+ }
+
+ if (!*pParamLoop)
+ break;
+
+ ++pParamLoop;
+ pSettings = pParamLoop;
+ }
+
+ // trace some initial information
+ CFG_TRACE_INFO_NI("initialization: process id: 0x%08X", osl_getProcess(0));
+ ::rtl::OUString sExecutable;
+ osl_getExecutableFile(&sExecutable.pData);
+ CFG_TRACE_INFO_NI("initialization: executable file name: %s", OUSTRING2ASCII(sExecutable));
+}
+
+//--------------------------------------------------------------------------
+//-----------------------------------------------------------
+// need raw unsigned int to safely printf a value
+static inline
+unsigned int getThreadID()
+{
+ oslThreadIdentifier nRealThreadID = ::osl_getThreadIdentifier(NULL);
+
+ return nRealThreadID; // if this loses data, we can still hope that lsb is changing between thraeds
+}
+
+//--------------------------------------------------------------------------
+void OConfigTracer::implTrace(const sal_Char* _pType, const sal_Char* _pFormat, va_list args)
+{
+ ensureInitalized();
+ if (!s_pImpl->m_pOutputMedium)
+ // no tracing enabled
+ return;
+
+ if (_pType && strlen(_pType))
+ {
+ if (s_pImpl->isTracing(OTracerSetup::THREAD))
+ {
+ fprintf(s_pImpl->m_pOutputMedium, "[%04x] ", getThreadID());
+ }
+
+ fprintf(s_pImpl->m_pOutputMedium, "%s ", _pType);
+
+ if (s_pImpl->isTracing(OTracerSetup::TIME))
+ {
+ fprintf(s_pImpl->m_pOutputMedium, "(%06" SAL_PRIuUINT32 ")", getGlobalTimer());
+ }
+ }
+ fprintf(s_pImpl->m_pOutputMedium, ": ");
+
+ indent();
+
+ vfprintf(s_pImpl->m_pOutputMedium, _pFormat, args);
+ fprintf(s_pImpl->m_pOutputMedium,"\n");
+ fflush(s_pImpl->m_pOutputMedium);
+}
+
+} // namespace configmgr
+
+#endif // CFG_ENABLE_TRACING
+
diff --git a/configmgr/source/platformbe/componentdefn.cxx b/configmgr/source/platformbe/componentdefn.cxx
new file mode 100644
index 000000000000..61666ad38e64
--- /dev/null
+++ b/configmgr/source/platformbe/componentdefn.cxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: componentdefn.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "systemintegrationmanager.hxx"
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif // _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+
+//==============================================================================
+
+static com::sun::star::uno::Reference<com::sun::star::uno::XInterface> SAL_CALL createSystemIntegrationManager(
+ const com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext>& aContext) {
+ return * new configmgr::backend::SystemIntegrationManager(aContext) ;
+}
+//==============================================================================
+
+//------------------------------------------------------------------------------
+
+static const cppu::ImplementationEntry kImplementations_entries[] =
+{
+ {
+ createSystemIntegrationManager,
+ configmgr::backend::SystemIntegrationManager::getSystemIntegrationManagerName,
+ configmgr::backend::SystemIntegrationManager::getServiceNames,
+ cppu::createSingleComponentFactory,
+ NULL,
+ 0
+ },
+ { NULL, NULL, NULL, NULL, NULL, 0 }
+} ;
+//------------------------------------------------------------------------------
+
+extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL
+component_getImplementationEnvironment(
+ const sal_Char **ppEnvTypeName,
+ uno_Environment ** /* ppEnv */
+ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//------------------------------------------------------------------------------
+
+extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo(
+ void *aServiceManager, void *aRegistryKey)
+{
+ return cppu::component_writeInfoHelper(aServiceManager,
+ aRegistryKey,
+ kImplementations_entries) ;
+}
+//------------------------------------------------------------------------------
+
+extern "C" SAL_DLLPUBLIC_EXPORT void *component_getFactory(
+ const sal_Char *aImplementationName, void *aServiceManager,
+ void *aRegistryKey)
+{
+ return cppu::component_getFactoryHelper(aImplementationName,
+ aServiceManager,
+ aRegistryKey,
+ kImplementations_entries) ;
+}
+//------------------------------------------------------------------------------
+
diff --git a/configmgr/source/platformbe/exports.dxp b/configmgr/source/platformbe/exports.dxp
new file mode 100644
index 000000000000..9630d7e06768
--- /dev/null
+++ b/configmgr/source/platformbe/exports.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
diff --git a/configmgr/source/platformbe/makefile.mk b/configmgr/source/platformbe/makefile.mk
new file mode 100644
index 000000000000..19796b2442c2
--- /dev/null
+++ b/configmgr/source/platformbe/makefile.mk
@@ -0,0 +1,74 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJINC=$(PRJ)$/source
+PRJNAME=configmgr
+TARGET=sysmgr
+ENABLE_EXCEPTIONS=TRUE
+
+# Version
+SYSMGR_MAJOR=1
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+DLLPRE =
+
+# --- Files ---
+
+
+SLOFILES=\
+ $(SLO)$/systemintegrationmanager.obj \
+ $(SLO)$/componentdefn.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+SHL1TARGET=$(TARGET)$(SYSMGR_MAJOR).uno
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+SHL1IMPLIB=i$(SHL1TARGET)
+SHL1STDLIBS= \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+DEF1DES=Configuration: System Integration Manager
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/platformbe/sysmgr1.uno.xml b/configmgr/source/platformbe/sysmgr1.uno.xml
new file mode 100644
index 000000000000..7f1767b3a351
--- /dev/null
+++ b/configmgr/source/platformbe/sysmgr1.uno.xml
@@ -0,0 +1,49 @@
+c<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice/DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name>sysmgr1</module-name>
+ <component-description>
+ <author>Sarah Smith</author>
+ <name>com.sun.star.comp.configuration.backend.SystemIntegration</name>
+ <description>The SystemIntegration backend co-ordinates access to a number of configured backends.Each Backend access configuration data from a configured data source</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>C++</language>
+ <status value="final"/>
+ <supported-service>com.sun.star.configuration.backend.SystemIntegration</supported-service>
+ <type>com.sun.star.configuration.CannotLoadConfigurationException</type>
+ <type>com.sun.star.configuration.backend.BackendAccessException</type>
+ <type>com.sun.star.configuration.backend.BackendSetupException</type>
+ <type>com.sun.star.configuration.backend.XBackend</type>
+ <type>com.sun.star.configuration.backend.XLayer</type>
+ <type>com.sun.star.configuration.backend.XUpdateHandler</type>
+ <type>com.sun.star.configuration.backend.XSingleLayerStratum</type>
+ <type>com.sun.star.configuration.backend.XBackendChangesNotifier</type>
+ <type>com.sun.star.configuration.backend.XBackendChangesListener</type>
+ <type>com.sun.star.uno.XComponentContext</type>
+ <type>com.sun.star.container.XContentEnumerationAccess</type>
+ <type>com.sun.star.container.XEnumeration</type>
+ <type>com.sun.star.beans.XPropertySet</type>
+ <type>com.sun.star.lang.IllegalArgumentException</type>
+ <type>com.sun.star.lang.XInitialization</type>
+ <type>com.sun.star.lang.XMultiServiceFactory</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XSingleServiceFactory</type>
+ <type>com.sun.star.lang.XSingleComponentFactory</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.registry.XRegistryKey</type>
+ <type>com.sun.star.uno.Any</type>
+ <type>com.sun.star.uno.Sequence</type>
+ </component-description>
+ <project-build-dependency> comphelper </project-build-dependency>
+ <project-build-dependency> vos </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> salhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> comphelp2$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> vos2$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> salhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+</module-description>
diff --git a/configmgr/source/platformbe/systemintegrationmanager.cxx b/configmgr/source/platformbe/systemintegrationmanager.cxx
new file mode 100644
index 000000000000..90fab141ccbb
--- /dev/null
+++ b/configmgr/source/platformbe/systemintegrationmanager.cxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: systemintegrationmanager.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "systemintegrationmanager.hxx"
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+namespace configmgr { namespace backend {
+
+
+//==============================================================================
+#define OU2A( oustr ) (rtl::OUStringToOString( oustr, RTL_TEXTENCODING_ASCII_US ).getStr())
+//==============================================================================
+uno::Reference<backenduno::XSingleLayerStratum> BackendRef::getBackend(uno::Reference<uno::XComponentContext> const & xContext)
+{
+ if (!mBackend.is() && mFactory.is())
+ try
+ {
+ mBackend.set( mFactory->createInstanceWithContext(xContext), uno::UNO_QUERY_THROW );
+ }
+ catch(uno::Exception& e)
+ {
+ OSL_TRACE("SystemIntegration::getSupportingBackend - could not create platform Backend: %s",
+ OU2A(e.Message) );
+ }
+ return mBackend;
+}
+//------------------------------------------------------------------------------
+void BackendRef::disposeBackend()
+{
+ uno::Reference< lang::XComponent> xComp( mBackend, uno::UNO_QUERY );
+ if (xComp.is())
+ try
+ {
+ xComp->dispose();
+ }
+ catch(uno::Exception &)
+ {}
+ mBackend.clear();
+}
+//==============================================================================
+SystemIntegrationManager::SystemIntegrationManager(const uno::Reference<uno::XComponentContext>& xContext)
+: cppu::WeakComponentImplHelper4< backenduno::XBackend, backenduno::XBackendChangesNotifier, lang::XInitialization, lang::XServiceInfo>(mMutex)
+, mMutex()
+, mContext(xContext)
+, mPlatformBackends()
+{
+}
+//------------------------------------------------------------------------------
+SystemIntegrationManager::~SystemIntegrationManager()
+{
+}
+//------------------------------------------------------------------------------
+void SAL_CALL SystemIntegrationManager::initialize(
+ const uno::Sequence<uno::Any>& /*aParameters*/)
+ throw (uno::RuntimeException, uno::Exception,
+ lang::IllegalArgumentException,
+ backenduno::BackendSetupException)
+{
+ buildLookupTable();
+}
+//------------------------------------------------------------------------------
+static const rtl::OUString getAllComponentsName()
+{
+ sal_Unicode const kStar = '*';
+ return rtl::OUString(&kStar,1);
+}
+
+//------------------------------------------------------------------------------
+
+void SystemIntegrationManager::buildLookupTable()
+{
+ static const rtl::OUString kPlatformServiceName(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.PlatformBackend")) ;
+
+ //Build platform backend map componentName -> servicefactory
+ uno::Reference<css::container::XContentEnumerationAccess> xEnumAccess
+ (mContext->getServiceManager(),uno::UNO_QUERY_THROW);
+
+ uno::Reference<css::container::XEnumeration> xEnum =
+ xEnumAccess->createContentEnumeration(kPlatformServiceName);
+ if (xEnum.is())
+ {
+ osl::MutexGuard lock(mMutex);
+ while (xEnum->hasMoreElements())
+ {
+ uno::Reference<lang::XSingleComponentFactory> xServiceFactory( xEnum->nextElement(),uno::UNO_QUERY);
+ if (xServiceFactory.is())
+ {
+ uno::Sequence<rtl::OUString> aKeys = getSupportedComponents(xServiceFactory);
+
+ for (sal_Int32 i = 0 ; i < aKeys.getLength() ; ++i)
+ {
+ BackendRef aBackendRef(xServiceFactory);
+ //OSL_TRACE("SystemInteg -Adding Factory Backend to map for key %s",
+ //rtl::OUStringToOString(aKeys[i], RTL_TEXTENCODING_ASCII_US).getStr() );
+ mPlatformBackends.insert( std::multimap<rtl::OUString, BackendRef>::value_type(aKeys[i],aBackendRef));
+ }
+ }
+ }
+ }
+}
+//---------------------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString>
+SystemIntegrationManager::getSupportedComponents(const uno::Reference<lang::XSingleComponentFactory>& xFactory)
+{
+ static const rtl::OUString kProperSubkeyName( RTL_CONSTASCII_USTRINGPARAM("/DATA/SupportedComponents")) ;
+ static const rtl::OUString kImplKeyPropertyName( RTL_CONSTASCII_USTRINGPARAM("ImplementationKey")) ;
+
+ uno::Reference<css::beans::XPropertySet> xSMProp(xFactory,uno::UNO_QUERY);
+ if (xSMProp.is())
+ {
+ try
+ {
+ uno::Reference< css::registry::XRegistryKey > xImplKey(
+ xSMProp->getPropertyValue(kImplKeyPropertyName), uno::UNO_QUERY);
+
+ if (xImplKey.is())
+ {
+ uno::Reference< css::registry::XRegistryKey > xKey(
+ xImplKey->openKey(kProperSubkeyName));
+ if(xKey.is())
+ return xKey->getAsciiListValue();
+ }
+ }
+ catch(css::beans::UnknownPropertyException&){}
+ catch(css::registry::InvalidValueException&){}
+ catch(css::registry::InvalidRegistryException&){}
+ }
+ static const rtl::OUString kAllComponentsName = getAllComponentsName();
+ return uno::Sequence<rtl::OUString>(&kAllComponentsName, 1);
+}
+//---------------------------------------------------------------------------------------------
+
+uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ SystemIntegrationManager::listOwnLayers(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ return listLayers(aComponent, rtl::OUString() ) ;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ SystemIntegrationManager::getOwnUpdateHandler(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::NoSupportException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+
+ return getUpdateHandler(aComponent, rtl::OUString()) ;
+}
+//------------------------------------------------------------------------------
+
+std::vector< uno::Reference<backenduno::XSingleLayerStratum> > SystemIntegrationManager::getSupportingBackends(const rtl::OUString& aComponent)
+{
+ std::vector< uno::Reference<backenduno::XSingleLayerStratum> > backends;
+
+ osl::MutexGuard lock(mMutex);
+ std::pair<std::multimap<rtl::OUString, BackendRef>::iterator, std::multimap<rtl::OUString, BackendRef>::iterator> aRange = mPlatformBackends.equal_range(aComponent);
+ for (std::multimap<rtl::OUString, BackendRef>::iterator it=aRange.first; it != aRange.second; )
+ {
+ std::multimap<rtl::OUString, BackendRef>::iterator cur = it++; // increment here, as erase() may invalidate cur
+ uno::Reference<backenduno::XSingleLayerStratum> xBackend = cur->second.getBackend(mContext);
+ if (xBackend.is())
+ backends.push_back(xBackend);
+
+ else // prevent repeated attempts to create
+ mPlatformBackends.erase(cur);
+ }
+ return backends;
+}
+//------------------------------------------------------------------------------
+uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ SystemIntegrationManager::listLayers(const rtl::OUString& aComponent,
+ const rtl::OUString& /*aEntity*/)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+ std::vector< uno::Reference<backenduno::XSingleLayerStratum> > const aUniversalBackends = getSupportingBackends(getAllComponentsName());
+ std::vector< uno::Reference<backenduno::XSingleLayerStratum> > const aSpecialBackends = getSupportingBackends(aComponent);
+
+ uno::Sequence< uno::Reference<backenduno::XLayer> > aLayers(aUniversalBackends.size() + aSpecialBackends.size());
+
+ uno::Reference<backenduno::XLayer> * pLayer = aLayers.getArray();
+
+ for (std::vector< uno::Reference<backenduno::XSingleLayerStratum> >::size_type i=0 ; i< aUniversalBackends.size(); ++i, ++pLayer)
+ *pLayer = aUniversalBackends[i]->getLayer(aComponent, rtl::OUString());
+
+ for (std::vector< uno::Reference<backenduno::XSingleLayerStratum> >::size_type j=0 ; j< aSpecialBackends.size(); ++j, ++pLayer)
+ *pLayer = aSpecialBackends[j]->getLayer(aComponent, rtl::OUString());
+
+ OSL_ASSERT( aLayers.getConstArray()+aLayers.getLength() == pLayer );
+ return aLayers;
+}
+//------------------------------------------------------------------------------
+
+uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ SystemIntegrationManager::getUpdateHandler(const rtl::OUString& /*aComponent*/,
+ const rtl::OUString& /*aEntity*/)
+ throw (backenduno::BackendAccessException,
+ lang::NoSupportException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException)
+{
+
+ throw lang::NoSupportException(
+ rtl::OUString::createFromAscii(
+ "SystemIntegrationManager: No Update Operation allowed, Read Only access"),
+ *this) ;
+}
+// ---------------------------------------------------------------------------
+// ComponentHelper
+void SAL_CALL SystemIntegrationManager::disposing()
+{
+ osl::MutexGuard lock(mMutex);
+ for (std::multimap<rtl::OUString, BackendRef>::iterator it = mPlatformBackends.begin(); it != mPlatformBackends.end(); ++it)
+ it->second.disposeBackend();
+
+ mPlatformBackends.clear();
+ mContext.clear();
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL SystemIntegrationManager::
+ getSystemIntegrationManagerName(void)
+{
+ static const rtl::OUString kImplementationName(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.configuration.backend.SystemIntegration")) ;
+
+ return kImplementationName ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL SystemIntegrationManager::getImplementationName(void)
+ throw (uno::RuntimeException)
+{
+ return getSystemIntegrationManagerName() ;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString> SAL_CALL SystemIntegrationManager::
+ getServiceNames(void)
+{
+ uno::Sequence<rtl::OUString> aServices(2) ;
+ aServices[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.SystemIntegration")) ;
+ aServices[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.Backend")) ;
+
+ return aServices ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL SystemIntegrationManager::supportsService(
+ const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< rtl::OUString > const svc = getServiceNames();
+
+ for(sal_Int32 i = 0; i < svc.getLength(); ++i )
+ if(svc[i] == aServiceName)
+ return true;
+ return false;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString>
+SAL_CALL SystemIntegrationManager::getSupportedServiceNames(void)
+ throw (uno::RuntimeException)
+{
+ return getServiceNames() ;
+}
+//------------------------------------------------------------------------------
+
+void SAL_CALL SystemIntegrationManager::addChangesListener(
+ const uno::Reference<backenduno::XBackendChangesListener>& xListener,
+ const rtl::OUString& aComponent)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+
+ // FIXME: we really need our own InterfaceContainer plus a helper object
+ // that listens on the backends and forwards notifications
+
+ //Simply forward listener to platform backend that support listening
+ {
+ std::vector< uno::Reference<backenduno::XSingleLayerStratum> > aUniversalBackends = getSupportingBackends(getAllComponentsName());
+ for (sal_uInt32 i=0; i< aUniversalBackends.size(); i++)
+ {
+ uno::Reference<backenduno::XBackendChangesNotifier> xBackend( aUniversalBackends[i], uno::UNO_QUERY) ;
+ if (xBackend.is())
+ xBackend->addChangesListener(xListener, aComponent);
+ }
+ }
+ {
+ std::vector< uno::Reference<backenduno::XSingleLayerStratum> > aSpecialBackends = getSupportingBackends(aComponent);
+ for (sal_uInt32 i=0; i< aSpecialBackends.size(); i++)
+ {
+ uno::Reference<backenduno::XBackendChangesNotifier> xBackend( aSpecialBackends[i], uno::UNO_QUERY) ;
+ if (xBackend.is())
+ xBackend->addChangesListener(xListener, aComponent);
+ }
+ }
+}
+//------------------------------------------------------------------------------
+void SAL_CALL SystemIntegrationManager::removeChangesListener(
+ const uno::Reference<backenduno::XBackendChangesListener>& xListener,
+ const rtl::OUString& aComponent)
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(mMutex);
+ {
+ std::vector< uno::Reference<backenduno::XSingleLayerStratum> > aUniversalBackends = getSupportingBackends(getAllComponentsName());
+ for (sal_uInt32 i=0; i< aUniversalBackends.size(); i++)
+ {
+ uno::Reference<backenduno::XBackendChangesNotifier> xBackend( aUniversalBackends[i], uno::UNO_QUERY) ;
+ if (xBackend.is())
+ xBackend->removeChangesListener(xListener, aComponent);
+ }
+ }
+ {
+ std::vector< uno::Reference<backenduno::XSingleLayerStratum> > aSpecialBackends = getSupportingBackends(aComponent);
+ for (sal_uInt32 i=0; i< aSpecialBackends.size(); i++)
+ {
+ uno::Reference<backenduno::XBackendChangesNotifier> xBackend( aSpecialBackends[i], uno::UNO_QUERY) ;
+ if (xBackend.is())
+ xBackend->removeChangesListener(xListener, aComponent);
+ }
+ }
+}
+//------------------------------------------------------------------------------
+
+
+} } // configmgr.backend
diff --git a/configmgr/source/platformbe/systemintegrationmanager.hxx b/configmgr/source/platformbe/systemintegrationmanager.hxx
new file mode 100644
index 000000000000..b42d902a912c
--- /dev/null
+++ b/configmgr/source/platformbe/systemintegrationmanager.hxx
@@ -0,0 +1,161 @@
+#ifndef CONFIGMGR_BACKEND_SYSTEMINTEGRATIONMANAGER_HXX_
+#define CONFIGMGR_BACKEND_SYSTEMINTEGRATIONMANAGER_HXX_
+
+#include <com/sun/star/configuration/backend/XBackend.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/configuration/backend/BackendSetupException.hpp>
+#include <com/sun/star/configuration/backend/XBackendChangesNotifier.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+#include <com/sun/star/configuration/backend/XSingleLayerStratum.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <cppuhelper/compbase4.hxx>
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+namespace configmgr { namespace backend {
+
+namespace css = com::sun::star ;
+namespace uno = css::uno ;
+namespace lang = css::lang ;
+namespace backenduno = css::configuration::backend ;
+
+/* Class containing a reference to a service factory(XSingleComponentFactory)
+ object and a platform backend (XSingleLayerStratum).
+ The reference to the platform backend will be NULL until the platform backend
+ is initialised
+ */
+class BackendRef
+{
+ uno::Reference<lang::XSingleComponentFactory> mFactory;
+ uno::Reference<backenduno::XSingleLayerStratum> mBackend;
+public:
+ explicit
+ BackendRef(const uno::Reference<lang::XSingleComponentFactory>& aFactory)
+ :mFactory(aFactory)
+ ,mBackend()
+ {}
+
+ uno::Reference<backenduno::XSingleLayerStratum> getBackend(uno::Reference<uno::XComponentContext> const & xContext);
+ void disposeBackend();
+};
+
+/**
+ Class implementing the Backend service for system integration backend access.
+ It creates the required backends and coordinates access to them.
+ */
+class SystemIntegrationManager : public cppu::WeakComponentImplHelper4< backenduno::XBackend, backenduno::XBackendChangesNotifier, lang::XInitialization, lang::XServiceInfo>
+{
+public:
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ explicit
+ SystemIntegrationManager( const uno::Reference<uno::XComponentContext>& xContext) ;
+
+ /** Destructor */
+ ~SystemIntegrationManager() ;
+
+ // XBackend
+ virtual uno::Sequence<uno::Reference<backenduno::XLayer> >
+ SAL_CALL listOwnLayers(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Reference<backenduno::XUpdateHandler>
+ SAL_CALL getOwnUpdateHandler(const rtl::OUString& aComponent)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+
+ virtual uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
+ listLayers(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ uno::RuntimeException) ;
+
+ virtual uno::Reference<backenduno::XUpdateHandler> SAL_CALL
+ getUpdateHandler(const rtl::OUString& aComponent,
+ const rtl::OUString& aEntity)
+ throw (backenduno::BackendAccessException,
+ lang::IllegalArgumentException,
+ lang::NoSupportException,
+ uno::RuntimeException) ;
+
+ // XInitialize
+ virtual void SAL_CALL initialize(const uno::Sequence<uno::Any>& aParameters)
+ throw (uno::RuntimeException, uno::Exception,
+ lang::IllegalArgumentException,
+ backenduno::BackendSetupException) ;
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (uno::RuntimeException) ;
+
+ virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException) ;
+
+ virtual uno::Sequence<rtl::OUString> SAL_CALL
+ getSupportedServiceNames(void) throw (uno::RuntimeException) ;
+
+ // XBackendChangesNotifier
+ virtual void SAL_CALL addChangesListener( const uno::Reference<backenduno::XBackendChangesListener>& xListner,
+ const rtl::OUString& aComponent)
+ throw (uno::RuntimeException);
+
+
+ virtual void SAL_CALL removeChangesListener( const uno::Reference<backenduno::XBackendChangesListener>& xListner,
+ const rtl::OUString& aComponent)
+ throw (uno::RuntimeException);
+
+ /**
+ Provides the implementation name.
+
+ @return implementation name
+ */
+ static rtl::OUString SAL_CALL getSystemIntegrationManagerName(void) ;
+ /**
+ Provides the list of supported services.
+
+ @return list of service names
+ */
+ static uno::Sequence<rtl::OUString> SAL_CALL getServiceNames(void) ;
+protected:
+// ComponentHelper
+ virtual void SAL_CALL disposing();
+private :
+ /** build lookup up table
+ */
+ void buildLookupTable();
+
+ /** get list of supported components
+ */
+ uno::Sequence<rtl::OUString> getSupportedComponents(const uno::Reference<lang::XSingleComponentFactory>& xFactory);
+
+ /**
+ get supporting backends from lookup table
+ */
+ std::vector< uno::Reference<backenduno::XSingleLayerStratum> > getSupportingBackends(const rtl::OUString& aComponent);
+
+private :
+ /** Mutex for resource protection */
+ osl::Mutex mMutex ;
+ /** Component Context */
+ uno::Reference<uno::XComponentContext> mContext ;
+
+ std::multimap<rtl::OUString, BackendRef> mPlatformBackends;
+} ;
+
+} } // configmgr.backend
+
+#endif // CONFIGMGR_BACKEND_SYSTEMINTEGRATIONMANAGER_HXX_
diff --git a/configmgr/source/registry/cfgregistrykey.cxx b/configmgr/source/registry/cfgregistrykey.cxx
new file mode 100644
index 000000000000..3c5242a960c6
--- /dev/null
+++ b/configmgr/source/registry/cfgregistrykey.cxx
@@ -0,0 +1,1482 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgregistrykey.cxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "cfgregistrykey.hxx"
+#include "datalock.hxx"
+#include "typeconverter.hxx"
+#include <osl/diagnose.h>
+#include <cppuhelper/extract.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XProperty.hpp>
+#include <com/sun/star/util/XStringEscape.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <typelib/typedescription.hxx>
+
+#include <limits>
+
+#define THISREF() static_cast< ::cppu::OWeakObject* >(this)
+#define UNISTRING(c) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(c) )
+
+//..........................................................................
+namespace configmgr
+{
+//..........................................................................
+
+//--------------------------------------------------------------------------
+namespace {
+ inline
+ com::sun::star::uno::Type getBinaryDataType()
+ {
+ com::sun::star::uno::Sequence<sal_Int8> const * const p= 0;
+ return ::getCppuType(p);
+ }
+ inline
+ bool isAscii(sal_Unicode ch)
+ {
+ return 0 < ch && ch < 128;
+ }
+ inline
+ bool isAscii(sal_Unicode const * ps, sal_Int32 nLen )
+ {
+ for (int i= 0; i< nLen; ++i)
+ if ( !isAscii( ps[i] ) )
+ return false;
+ return true;
+ }
+ inline
+ bool isAscii(rtl::OUString const& str)
+ {
+ return isAscii(str.getStr(),str.getLength());
+ }
+ inline
+ bool isAscii(com::sun::star::uno::Sequence< rtl::OUString > const& strList)
+ {
+ for (int i= 0; i< strList.getLength(); ++i)
+ if ( !isAscii( strList[i] ) )
+ return false;
+ return true;
+ }
+}
+// temporary helper
+inline static void checkNullable() {}
+
+//==========================================================================
+//= OConfigurationRegistryKey
+//==========================================================================
+
+static
+rtl::OUString getNodeName(const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& _xNode)
+{
+ com::sun::star::uno::Reference< com::sun::star::container::XNamed > xName( _xNode, com::sun::star::uno::UNO_QUERY );
+ if (xName.is())
+ return xName->getName();
+
+ OSL_ENSURE( !_xNode.is(), "Cannot get name of node");
+ return rtl::OUString();
+}
+//--------------------------------------------------------------------------
+
+static bool splitPath(const rtl::OUString& _sPath, rtl::OUString& _rsParentPath, rtl::OUString& _rsLocalName);
+//--------------------------------------------------------------------------
+
+OConfigurationRegistryKey::OConfigurationRegistryKey
+ (const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& _rxRootNode
+ ,sal_Bool _bWriteable
+ ,SubtreeRoot
+ )
+ :m_bReadOnly(!_bWriteable)
+ ,m_xNode(_rxRootNode)
+ ,m_xParentNode()
+ ,m_sLocalName() // this will be treated as root - maybe use hierarchical name (ß)
+{
+ OSL_ENSURE(m_xNode.is(), "OConfigurationRegistryKey::OConfigurationRegistryKey : invalid config node param !");
+}
+
+//--------------------------------------------------------------------------
+OConfigurationRegistryKey::OConfigurationRegistryKey
+ (const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& _rxNode
+ ,sal_Bool _bWriteable
+ )
+ :m_bReadOnly(!_bWriteable)
+ ,m_xNode(_rxNode)
+ ,m_xParentNode()
+ ,m_sLocalName( getNodeName(_rxNode) ) // this will not be treated as root
+{
+ OSL_ENSURE(m_xNode.is(), "OConfigurationRegistryKey::OConfigurationRegistryKey : invalid config node param !");
+}
+
+//--------------------------------------------------------------------------
+OConfigurationRegistryKey::OConfigurationRegistryKey(
+ com::sun::star::uno::Any _rCurrentValue,
+ const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& _rxParentNode,
+ const ::rtl::OUString& _rLocalName,
+ sal_Bool _bWriteable)
+ :m_bReadOnly(!_bWriteable)
+ ,m_xNode()
+ ,m_xParentNode(_rxParentNode)
+ ,m_sLocalName(_rLocalName)
+{
+ OSL_ENSURE(m_xParentNode.is(), "OConfigurationRegistryKey::OConfigurationRegistryKey : invalid parent node param !");
+ OSL_ENSURE(m_sLocalName.getLength(), "OConfigurationRegistryKey::OConfigurationRegistryKey : invalid relative name !");
+ OSL_ENSURE(m_xParentNode->hasByName( m_sLocalName ), "OConfigurationRegistryKey::OConfigurationRegistryKey : key not found in parent node !" ); //
+ OSL_ENSURE(m_xParentNode->getByName( m_sLocalName ) == _rCurrentValue, "OConfigurationRegistryKey::OConfigurationRegistryKey : wrong value parameter !" ); //
+
+ _rCurrentValue >>= m_xNode; // we don't care if that fails
+}
+//--------------------------------------------------------------------------
+
+com::sun::star::uno::Reference<com::sun::star::beans::XPropertySetInfo> OConfigurationRegistryKey::implGetParentPropertyInfo() throw(com::sun::star::uno::RuntimeException)
+{
+ if (!m_xParentNode.is())
+ {
+ com::sun::star::uno::Reference< com::sun::star::container::XChild > xChild(m_xNode, com::sun::star::uno::UNO_QUERY);
+ if (xChild.is())
+ m_xParentNode = m_xParentNode.query(xChild->getParent());
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xParentInfo; // the result
+
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xParentProperties(m_xParentNode, com::sun::star::uno::UNO_QUERY);
+ if (xParentProperties.is())
+ {
+ xParentInfo = xParentProperties->getPropertySetInfo();
+ if (xParentInfo.is() && !xParentInfo->hasPropertyByName(m_sLocalName))
+ {
+ OSL_ENSURE(false, "OConfigurationRegistryKey: This key is unknown in the parent node's PropertySetInfo !");
+ xParentInfo.clear(); // this key is unknow, so don't return the info
+ }
+ }
+
+ return xParentInfo;
+}
+//--------------------------------------------------------------------------
+
+static
+sal_Bool isNodeReadOnly(com::sun::star::uno::Reference< com::sun::star::uno::XInterface > const& _xNode) throw(com::sun::star::uno::RuntimeException)
+{
+ OSL_ASSERT( _xNode.is() );
+
+ com::sun::star::uno::Reference< com::sun::star::beans::XProperty > xProperty(_xNode, com::sun::star::uno::UNO_QUERY);
+ if (xProperty.is())
+ {
+ com::sun::star::beans::Property aProperty = xProperty->getAsProperty();
+
+ return (aProperty.Attributes & com::sun::star::beans::PropertyAttribute::READONLY) != 0;
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::lang::XServiceInfo > xServiceInfo( _xNode, com::sun::star::uno::UNO_QUERY );
+ if (xServiceInfo.is())
+ {
+ // does it announce update capability ?
+ if (xServiceInfo->supportsService(UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess")))
+ return false;
+
+ // else does it announce the expected service at all ?
+ else if (xServiceInfo->supportsService(UNISTRING("com.sun.star.configuration.ConfigurationAccess")))
+ return true;
+ }
+
+ // no XProperty, no (meaningful) ServiceInfo - what can we do
+ return false;
+}
+
+//--------------------------------------------------------------------------
+
+sal_Bool OConfigurationRegistryKey::implIsReadOnly() throw (com::sun::star::uno::RuntimeException)
+{
+ sal_Bool bResult = m_bReadOnly;;
+
+ // do checks only if this was requested to be writable
+ if (m_bReadOnly)
+ {
+ // nothing to check
+ }
+
+ // try to ask the node itself
+ else if (m_xNode.is())
+ {
+ bResult = m_bReadOnly = isNodeReadOnly( m_xNode );
+ }
+
+ // else use the parent
+ else if (m_xParentNode.is())
+ {
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xParentInfo = implGetParentPropertyInfo();
+
+ if (xParentInfo.is())
+ {
+ com::sun::star::beans::Property aProperty = xParentInfo->getPropertyByName(m_sLocalName);
+
+ bResult = m_bReadOnly = ((aProperty.Attributes & com::sun::star::beans::PropertyAttribute::READONLY) != 0);
+ }
+ else
+ {
+ // no property info about this key ? - check if the parent itself is writable
+
+ // NOTE: do not set m_bReadOnly here, as we haven't really found out about this object
+ bResult = isNodeReadOnly( m_xParentNode );
+ }
+ }
+ else
+ {
+ // no data at all
+ OSL_ENSURE(false, "implIsReadOnly called for invalid object");
+ bResult = true; // no object is certainly not writable ;-)
+ }
+
+ return bResult;
+}
+//--------------------------------------------------------------------------
+
+sal_Bool OConfigurationRegistryKey::implEnsureNode() throw (com::sun::star::registry::InvalidRegistryException,com::sun::star::uno::RuntimeException)
+{
+ if (!m_xNode.is())
+ {
+ OSL_ENSURE( m_xParentNode.is(), "implEnsureNode called for invalid registry key");
+ if (m_xParentNode.is())
+ {
+ try
+ {
+ com::sun::star::uno::Any aNode = m_xParentNode->getByName( m_sLocalName );
+
+ if ( !(aNode >>= m_xNode) )
+ OSL_ENSURE( ! (aNode.hasValue() && aNode.getValueTypeClass() == com::sun::star::uno::TypeClass_INTERFACE),
+ "OConfigurationRegistryKey: Node object does not implement expected interface");
+ }
+ catch (com::sun::star::container::NoSuchElementException& e)
+ {
+ m_xParentNode.clear();
+
+ rtl::OUString sMessage = UNISTRING("Invalid OConfigurationRegistryKey. The node \"");
+ sMessage += m_sLocalName;
+ sMessage += UNISTRING("\" was not found in the parent. Parent error message: \n");
+ sMessage += e.Message;
+
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ }
+ }
+ return m_xNode.is();
+}
+//--------------------------------------------------------------------------
+
+com::sun::star::uno::Type OConfigurationRegistryKey::implGetUnoType() throw (com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Type aType;
+ if (m_xNode.is())
+ {
+ aType = getCppuType(&m_xNode); // Its just an interface type
+ }
+ else if (m_xParentNode.is())
+ {
+
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xParentInfo = implGetParentPropertyInfo();
+ if (xParentInfo.is())
+ {
+ aType = xParentInfo->getPropertyByName( m_sLocalName ).Type;
+ }
+ else
+ {
+ aType = m_xParentNode->getElementType();
+ }
+ }
+ else
+ {
+ OSL_ASSERT( aType.getTypeClass() == com::sun::star::uno::TypeClass_VOID );
+ OSL_ENSURE( false, "implGetUnoType called for invalid registry key");
+ }
+ return aType;
+}
+//--------------------------------------------------------------------------
+
+sal_Bool OConfigurationRegistryKey::implEnsureValue() throw (com::sun::star::uno::RuntimeException)
+{
+ if (m_xNode.is())
+ return false;
+
+ OSL_ENSURE( m_xParentNode.is(), "implEnsureValue called for invalid registry key");
+ if (!m_xParentNode.is())
+ return false;
+
+ switch (implGetUnoType().getTypeClass())
+ {
+ case com::sun::star::uno::TypeClass_INTERFACE:
+ return false;
+
+ case com::sun::star::uno::TypeClass_BYTE:
+ case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
+ case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
+ case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
+ case com::sun::star::uno::TypeClass_FLOAT:
+ OSL_ENSURE(false, "Unexpected (UNSIGNED INTERGRAL or FLOAT) type found for configuration node");
+
+ case com::sun::star::uno::TypeClass_STRING:
+ case com::sun::star::uno::TypeClass_BOOLEAN:
+ case com::sun::star::uno::TypeClass_SHORT:
+ case com::sun::star::uno::TypeClass_LONG:
+ case com::sun::star::uno::TypeClass_HYPER:
+ case com::sun::star::uno::TypeClass_DOUBLE:
+ case com::sun::star::uno::TypeClass_SEQUENCE:
+ return true;
+
+ case com::sun::star::uno::TypeClass_ANY:
+ return true;
+
+ case com::sun::star::uno::TypeClass_VOID:
+ OSL_ENSURE(false, "OConfigurationRegistryKey: Key does not exist or has VOID type");
+ return false;
+
+ default:
+ OSL_ENSURE(false, "OConfigurationRegistryKey: Key has unexpected UNO type (class)");
+ return false;
+ }
+}
+//--------------------------------------------------------------------------
+
+sal_Bool OConfigurationRegistryKey::implIsValid() throw ()
+{
+ return m_xNode.is() || (m_xParentNode.is() && m_xParentNode->hasByName( m_sLocalName ) );
+}
+//--------------------------------------------------------------------------
+
+void OConfigurationRegistryKey::checkValid(KEY_ACCESS_TYPE _eIntentedAccess) throw (com::sun::star::registry::InvalidRegistryException,com::sun::star::uno::RuntimeException)
+{
+ if (!implIsValid())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The registry is not bound to a configuration node anymore."), THISREF());
+ // "anymore", because at the moment the ctor was called it probably was bound ....
+
+ switch (_eIntentedAccess)
+ {
+ case KAT_VALUE_WRITE:
+ if (implIsReadOnly())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration node is not writeable."), THISREF());
+
+ // !!! NO !!! BREAK !!!
+ case KAT_VALUE:
+ if (m_xNode.is())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration node is not a value, but an internal container."), THISREF());
+
+ if (!m_xParentNode.is())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration node is invalid. It has no parent."), THISREF());
+
+ if (!implEnsureValue())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration does not have a legal value type."), THISREF());
+ break;
+
+ case KAT_CHILD:
+ if (!implEnsureNode())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This configuration node does not have children, it is a value node."), THISREF());
+ break;
+
+ case KAT_META:
+ break;
+ }
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Any OConfigurationRegistryKey::implCreateDefaultElement(com::sun::star::uno::Type const& _aValueType) throw (com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aReturn;
+
+ switch (_aValueType.getTypeClass())
+ {
+ case com::sun::star::uno::TypeClass_STRING:
+ aReturn <<= rtl::OUString();
+ break;
+
+ // we don't distinguish between the different integer types or boolean
+ // (the RegistryKeyType is not granular enough),
+ // but we can't handle them all the same way here
+ case com::sun::star::uno::TypeClass_BYTE:
+ case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
+ case com::sun::star::uno::TypeClass_SHORT:
+ aReturn <<= (sal_Int16)0;
+ break;
+
+ case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
+ case com::sun::star::uno::TypeClass_LONG:
+ aReturn <<= (sal_Int32)0;
+ break;
+
+ case com::sun::star::uno::TypeClass_BOOLEAN:
+ aReturn <<= sal_Bool(false);
+ break;
+
+ // we cannot really handle 64-bit ints in the registry (but here we can)
+ case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
+ case com::sun::star::uno::TypeClass_HYPER:
+ OSL_ENSURE(false, "Warning: cannot handle 64-bit values correctly in registry");
+ aReturn <<= (sal_Int64)0;
+ break;
+
+ // we cannot really handle doubles in the registry (but here we can)
+ case com::sun::star::uno::TypeClass_FLOAT:
+ case com::sun::star::uno::TypeClass_DOUBLE:
+ OSL_ENSURE(false, "Warning: cannot handle DOUBLE correctly in registry");
+ aReturn <<= (double)0;
+ break;
+
+ // we really want to leave an Any as NULL - hopefully this is acceptable to the set
+ case com::sun::star::uno::TypeClass_ANY:
+ break;
+
+ case com::sun::star::uno::TypeClass_SEQUENCE:
+ if (_aValueType == getBinaryDataType())
+ aReturn <<= com::sun::star::uno::Sequence< sal_Int8 >();
+
+ else
+ {
+ com::sun::star::uno::Type aElementType = getSequenceElementType(_aValueType);
+ switch (aElementType.getTypeClass())
+ {
+ case com::sun::star::uno::TypeClass_STRING:
+ aReturn <<= com::sun::star::uno::Sequence< rtl::OUString >();
+ break;
+
+ case com::sun::star::uno::TypeClass_BYTE:
+ case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
+ case com::sun::star::uno::TypeClass_SHORT:
+ aReturn <<= com::sun::star::uno::Sequence< sal_Int16 >();
+ break;
+
+ case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
+ case com::sun::star::uno::TypeClass_LONG:
+ aReturn <<= com::sun::star::uno::Sequence< sal_Int32 >();
+ break;
+
+ case com::sun::star::uno::TypeClass_BOOLEAN:
+ aReturn <<= com::sun::star::uno::Sequence< sal_Bool >();
+ break;
+
+ case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
+ case com::sun::star::uno::TypeClass_HYPER:
+ aReturn <<= com::sun::star::uno::Sequence< sal_Int64 >();
+ break;
+
+ case com::sun::star::uno::TypeClass_FLOAT:
+ case com::sun::star::uno::TypeClass_DOUBLE:
+ aReturn <<= com::sun::star::uno::Sequence< double >();
+ break;
+
+ case com::sun::star::uno::TypeClass_SEQUENCE:
+ OSL_ENSURE(false, "Warning: cannot handle Sequence< BINARY > correctly in registry");
+ if (aElementType == getBinaryDataType())
+ {
+ OSL_ENSURE(false, "Warning: cannot handle Sequence< BINARY > correctly in registry");
+ aReturn <<= com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< sal_Int8 > >();
+ break;
+ }
+
+ // else FALL THRU to default
+ default:
+ OSL_ENSURE(false, "Unexpected sequence element type for configuration node - returning NULL");
+ // throw here ??
+ break;
+ }
+ }
+ break;
+
+ case com::sun::star::uno::TypeClass_INTERFACE:
+ OSL_ENSURE(false, "Invalid call to OConfigurationRegistryKey::implCreateDefaultElement. Inner nodes must be created by a factory");
+ break;
+
+ default:
+ OSL_ENSURE(false, "Unexpected value type for configuration node - returning NULL");
+ // throw here ??
+ break;
+ }
+
+ OSL_ENSURE( aReturn.getValueType() == _aValueType || (_aValueType.getTypeClass() == com::sun::star::uno::TypeClass_ANY && !aReturn.hasValue()),
+ "Warning: Unexpected data type found in Registry - returning similar value or NULL");
+ return aReturn;
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Any OConfigurationRegistryKey::implGetDescendant(const rtl::OUString& _rDescendantName) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aElementReturn;
+
+ try
+ {
+ if (!m_xNode.is())
+ {
+ // implEnsureNode should have been called before this method
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::getDescendant : invalid call !");
+
+ // this method should not be called if the object does not represent a container node ...
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("invalid object."), THISREF());
+ }
+
+ try
+ {
+ // look for a local member first
+ aElementReturn = m_xNode->getByName(_rDescendantName);
+ }
+ catch(com::sun::star::container::NoSuchElementException&)
+ {
+ // is it a (possibly) hierarchical name ?
+ if ( _rDescendantName.indexOf('/') <0 ) throw;
+
+ // Yes, so try deep access
+ com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xDeepAccess( m_xNode, com::sun::star::uno::UNO_QUERY );
+ if (!xDeepAccess.is())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Nested element access not supported by this node."), THISREF());
+
+ aElementReturn = xDeepAccess->getByHierarchicalName(_rDescendantName);
+ }
+ }
+ catch(com::sun::star::container::NoSuchElementException&)
+ { // not allowed to leave the method, wrap it
+ rtl::OUString sMessage(UNISTRING("There is no element named "));
+ sMessage += _rDescendantName;
+ sMessage += UNISTRING(".");
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ catch(com::sun::star::lang::WrappedTargetException& wte)
+ { // allowed to be thrown by XNameAccess::getByName, but not allowed to leave this method
+ rtl::OUString sMessage(UNISTRING("The configuration node could not provide an element for "));
+ sMessage += _rDescendantName;
+ sMessage += UNISTRING(". Original Error: ");
+ sMessage += wte.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+
+ return aElementReturn;
+}
+
+//--------------------------------------------------------------------------
+void OConfigurationRegistryKey::implSetValue(const com::sun::star::uno::Any& _rValue) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ checkValid(KAT_VALUE_WRITE);
+
+ // one possible interface
+ com::sun::star::uno::Reference< com::sun::star::container::XNameReplace > xParentValueAccess(m_xParentNode, com::sun::star::uno::UNO_QUERY);
+ if (xParentValueAccess.is())
+ {
+ try
+ {
+ xParentValueAccess->replaceByName(m_sLocalName, _rValue);
+ }
+ catch(com::sun::star::lang::IllegalArgumentException& iae)
+ {
+ rtl::OUString sMessage = UNISTRING("Unable to replace the old value. The configuration node threw an ");
+ sMessage += UNISTRING("IllegalArgumentException: ");
+ sMessage += iae.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ catch(com::sun::star::container::NoSuchElementException& nse)
+ {
+ OSL_ENSURE(false, "OConfigurationRegistryKey::writeValueNode : a NoSuchElementException should be impossible !");
+
+ rtl::OUString sMessage = UNISTRING("Unable to replace the old value. The configuration node threw an ");
+ sMessage += UNISTRING("NoSuchElementException: ");
+ sMessage += nse.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ catch(com::sun::star::lang::WrappedTargetException& wte)
+ {
+ rtl::OUString sMessage = UNISTRING("Unable to replace the old value. The configuration node threw an ");
+ sMessage += UNISTRING("WrappedTargetException: ");
+ sMessage += wte.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ return;
+ }
+
+ // not found - try other interface
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xParentPropertySet(m_xParentNode, com::sun::star::uno::UNO_QUERY);
+ if (xParentPropertySet.is())
+ {
+ try
+ {
+ xParentPropertySet->setPropertyValue(m_sLocalName, _rValue);
+ }
+ catch(com::sun::star::lang::IllegalArgumentException& iae)
+ {
+ rtl::OUString sMessage = UNISTRING("Unable to set a new value. The configuration node threw an ");
+ sMessage += UNISTRING("IllegalArgumentException: ");
+ sMessage += iae.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ catch(com::sun::star::beans::UnknownPropertyException& upe)
+ {
+ OSL_ENSURE(false, "OConfigurationRegistryKey::writeValueNode : a UnknownPropertyException should be impossible !");
+
+ rtl::OUString sMessage = UNISTRING("Unable to set a new value. The configuration node threw an ");
+ sMessage += UNISTRING("UnknownPropertyException: ");
+ sMessage += upe.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ catch(com::sun::star::beans::PropertyVetoException& pve)
+ {
+ rtl::OUString sMessage = UNISTRING("Unable to set a new value. The configuration node threw an ");
+ sMessage += UNISTRING("PropertyVetoException: ");
+ sMessage += pve.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ catch(com::sun::star::lang::WrappedTargetException& wte)
+ {
+ rtl::OUString sMessage = UNISTRING("Unable to set a new value. The configuration node threw an ");
+ sMessage += UNISTRING("WrappedTargetException: ");
+ sMessage += wte.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+ return;
+ }
+
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("No interface found on parent node for writing to configuration value node."), THISREF());
+}
+
+//--------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OConfigurationRegistryKey::getKeyName() throw(com::sun::star::uno::RuntimeException)
+{
+ return m_sLocalName;
+}
+
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL OConfigurationRegistryKey::isReadOnly() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ OSL_ASSERT(UnoApiLock::isHeld());
+ checkValid(KAT_META);
+ return m_bReadOnly;
+}
+
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL OConfigurationRegistryKey::isValid() throw(com::sun::star::uno::RuntimeException)
+{
+ OSL_ASSERT(UnoApiLock::isHeld());
+ // TODO : perhaps if the registry we're a part of is closed ....
+ return implIsValid();
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::registry::RegistryKeyType SAL_CALL OConfigurationRegistryKey::getKeyType( const ::rtl::OUString& /*_rKeyName*/ ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ OSL_ASSERT(UnoApiLock::isHeld());
+
+ // no further checks are made (for performance reasons) ...
+ // Maybe we should check only KAT_META for consistency ?
+ checkValid(KAT_CHILD);
+
+ return com::sun::star::registry::RegistryKeyType_KEY;
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::registry::RegistryValueType SAL_CALL OConfigurationRegistryKey::getValueType() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ checkValid(KAT_META);
+
+ const com::sun::star::uno::Type aUnoType = implGetUnoType();
+
+ switch (aUnoType.getTypeClass())
+ {
+ case com::sun::star::uno::TypeClass_INTERFACE: // this is really a case of 'no value type'
+ return com::sun::star::registry::RegistryValueType_NOT_DEFINED;
+
+ case com::sun::star::uno::TypeClass_ANY: // this is really a case of 'all value types allowed'
+ return com::sun::star::registry::RegistryValueType_NOT_DEFINED;
+
+ case com::sun::star::uno::TypeClass_STRING:
+ return com::sun::star::registry::RegistryValueType_STRING;
+
+ case com::sun::star::uno::TypeClass_BYTE:
+ case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
+ case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
+ OSL_ENSURE(false, "Unexpected UNSIGNED type found for configuration node");
+ // FALL THRU
+
+ case com::sun::star::uno::TypeClass_BOOLEAN:
+ case com::sun::star::uno::TypeClass_SHORT:
+ case com::sun::star::uno::TypeClass_LONG:
+ return com::sun::star::registry::RegistryValueType_LONG;
+
+ case com::sun::star::uno::TypeClass_FLOAT:
+ case com::sun::star::uno::TypeClass_DOUBLE:
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::getValueType : registry does not support floating point numbers !");
+ return com::sun::star::registry::RegistryValueType_LONG;
+
+ case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
+ case com::sun::star::uno::TypeClass_HYPER:
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::getValueType : registry does not support 64-bit integer numbers !");
+ return com::sun::star::registry::RegistryValueType_LONG;
+
+ case com::sun::star::uno::TypeClass_SEQUENCE:
+ if ( aUnoType.equals( getBinaryDataType() ) )
+ return com::sun::star::registry::RegistryValueType_BINARY;
+
+ else
+ {
+ com::sun::star::uno::Type aElementType = getSequenceElementType(aUnoType);
+
+ switch (aElementType.getTypeClass())
+ {
+ case com::sun::star::uno::TypeClass_STRING:
+ return com::sun::star::registry::RegistryValueType_STRINGLIST;
+
+ case com::sun::star::uno::TypeClass_BYTE:
+ OSL_ASSERT(false); // this is caught by the 'binary' case
+
+ case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
+ case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
+ OSL_ENSURE(false, "Unexpected UNSIGNED-List type found for configuration node");
+ // FALL THRU
+
+ case com::sun::star::uno::TypeClass_BOOLEAN:
+ case com::sun::star::uno::TypeClass_SHORT:
+ case com::sun::star::uno::TypeClass_LONG:
+ return com::sun::star::registry::RegistryValueType_LONGLIST;
+
+ case com::sun::star::uno::TypeClass_FLOAT:
+ case com::sun::star::uno::TypeClass_DOUBLE:
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::getValueType : registry does not support floating point number lists !");
+ return com::sun::star::registry::RegistryValueType_LONGLIST;
+
+ case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
+ case com::sun::star::uno::TypeClass_HYPER:
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::getValueType : registry does not support 64-bit integer number lists !");
+ return com::sun::star::registry::RegistryValueType_LONGLIST;
+
+ case com::sun::star::uno::TypeClass_ANY:
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::getValueType : Unexpected: Any as sequence element type !");
+ return com::sun::star::registry::RegistryValueType_NOT_DEFINED;
+
+ default:
+ if (aElementType.equals(getBinaryDataType()))
+ OSL_ENSURE(sal_False,"OConfigurationRegistryKey::getValueType : Registry cannot support LIST of BINARY");
+ else
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::getValueType : unknown sequence element type !");
+
+ return com::sun::star::registry::RegistryValueType_NOT_DEFINED;
+ }
+ }
+
+ default:
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::getValueType : unknown entry type !");
+ return com::sun::star::registry::RegistryValueType_NOT_DEFINED;
+ }
+}
+
+//--------------------------------------------------------------------------
+
+com::sun::star::uno::Any OConfigurationRegistryKey::implGetValue() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ checkValid(KAT_VALUE);
+
+ return m_xParentNode->getByName( m_sLocalName );
+}
+
+//--------------------------------------------------------------------------
+sal_Int32 SAL_CALL OConfigurationRegistryKey::getLongValue() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::registry::InvalidValueException, com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aValue = implGetValue();
+
+ sal_Int32 nLongValue(0);
+ switch (aValue.getValueTypeClass())
+ {
+ // integral types that are small enough are straightforward
+ case com::sun::star::uno::TypeClass_BYTE : { sal_Int8 nNativeValue = 0; aValue >>= nNativeValue; nLongValue = nNativeValue; } break;
+ case com::sun::star::uno::TypeClass_BOOLEAN : { sal_Bool nNativeValue = false; aValue >>= nNativeValue; nLongValue = nNativeValue; } break;
+ case com::sun::star::uno::TypeClass_SHORT : { sal_Int16 nNativeValue; aValue >>= nNativeValue; nLongValue = nNativeValue; } break;
+ case com::sun::star::uno::TypeClass_UNSIGNED_SHORT : { sal_uInt16 nNativeValue; aValue >>= nNativeValue; nLongValue = nNativeValue; } break;
+ case com::sun::star::uno::TypeClass_LONG : { sal_Int32 nNativeValue; aValue >>= nNativeValue; nLongValue = nNativeValue; } break;
+
+ // this is lossless, but not value-preserving - use cast to avoid warnings
+ case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 nNativeValue;
+ aValue >>= nNativeValue;
+ nLongValue = sal_Int32(nNativeValue);
+ }
+ break;
+
+ // the following are larger than Long - check for loss and throw if applicable
+ case com::sun::star::uno::TypeClass_HYPER:
+ {
+ sal_Int64 nNativeValue;
+ aValue >>= nNativeValue;
+ nLongValue = sal_Int32(nNativeValue);
+
+ // check for data loss
+ if (sal_Int64(nLongValue) != nNativeValue)
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("Unsigned Hyper value too large for long; Value cannot be retrieved using registry."), THISREF());
+ }
+ break;
+
+ case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
+ {
+ sal_uInt64 nNativeValue;
+ aValue >>= nNativeValue;
+ nLongValue = sal_Int32(nNativeValue);
+
+ // check for data loss
+ if (sal_uInt64(sal_uInt32(nLongValue)) != nNativeValue)
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("Unsigned Hyper value too large for long; Value cannot be retrieved using registry."), THISREF());
+ }
+ break;
+
+ // for floating point types we need a limit for loss checking
+ case com::sun::star::uno::TypeClass_FLOAT:
+ OSL_ENSURE(false, "Unexpected type FLOAT in configuration node");
+ {
+ // treat as double
+ float fNativeValue = 0;
+ if (aValue >>= fNativeValue)
+ aValue <<= double(fNativeValue);
+ }
+ // fall thru
+
+ case com::sun::star::uno::TypeClass_DOUBLE:
+ {
+ double fNativeValue = 0;
+ aValue >>= fNativeValue;
+
+ // find a reasonable allowed imprecision
+ const double fEps = (2.*fNativeValue + 5.) * std::numeric_limits<double>::epsilon();
+
+ // should be rounding here
+ nLongValue = sal_Int32(fNativeValue);
+
+ // check for data loss
+ bool bRecheck = false;
+
+ double diff = fNativeValue-double(nLongValue);
+ if ( diff > fEps)
+ {
+ // substitute for rounding here
+ if (diff > .5)
+ {
+ ++nLongValue;
+ diff = fNativeValue-double(nLongValue);
+ }
+ bRecheck = true;
+ }
+ else if ( diff < -fEps)
+ {
+ // substitute for rounding here
+ if (diff < -.5)
+ {
+ --nLongValue;
+ diff = fNativeValue-double(nLongValue);
+ }
+ bRecheck = true;
+ }
+
+ if (bRecheck)
+ {
+ if (diff > fEps || diff < -fEps)
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("Double value cannot fit in Long; Value cannot be retrieved using registry."), THISREF());
+ }
+ }
+ break;
+
+ case com::sun::star::uno::TypeClass_VOID:
+ // allow NULL values, if we maybe advertise this node as long
+ if (this->getValueType() == com::sun::star::registry::RegistryValueType_LONG)
+ break;
+ // else FALL THRU to exception
+
+ default:
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("This node does not contain a long (or a compatible) value."), THISREF());
+ }
+ return nLongValue;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::setLongValue( sal_Int32 _nValue ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ implSetValue(com::sun::star::uno::makeAny(_nValue));
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL OConfigurationRegistryKey::getLongListValue() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::registry::InvalidValueException, com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aValue = implGetValue();
+
+ com::sun::star::uno::Sequence< sal_Int32 > aReturn;
+ if (!aValue.hasValue())
+ checkNullable();// let NULL values pass
+
+ else if (!(aValue >>= aReturn))
+ {
+ // TODO : maybe it's a sequence of sal_Int8 or anything like that which we're able to convert ....
+
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node does not contain a list of longs !"), THISREF());
+ }
+
+ return aReturn;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::setLongListValue( const com::sun::star::uno::Sequence< sal_Int32 >& _seqValue ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ implSetValue(com::sun::star::uno::makeAny(_seqValue));
+}
+
+//--------------------------------------------------------------------------
+rtl::OUString SAL_CALL OConfigurationRegistryKey::getAsciiValue() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::registry::InvalidValueException, com::sun::star::uno::RuntimeException)
+{
+ rtl::OUString sReturn = getStringValue();
+
+ if (!isAscii(sReturn))
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node value (a string) is not pure ASCII !"), THISREF());
+
+ return sReturn;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::setAsciiValue( const ::rtl::OUString& _rValue ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ OSL_ENSURE( isAscii(_rValue), "The string passesd to OConfigurationRegistryKey::setAsciiValue is not pure ASCII");
+
+ setStringValue(_rValue);
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL OConfigurationRegistryKey::getAsciiListValue() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::registry::InvalidValueException, com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Sequence<rtl::OUString> aReturn = getStringListValue();
+
+ if (!isAscii(aReturn))
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node value (a string list) is not pure ASCII !"), THISREF());
+
+ return aReturn;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::setAsciiListValue( const com::sun::star::uno::Sequence< ::rtl::OUString >& _seqValue ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ OSL_ENSURE( isAscii(_seqValue), "The string passesd to OConfigurationRegistryKey::setAsciiValue is not pure ASCII");
+
+ setStringListValue(_seqValue);
+}
+
+//--------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OConfigurationRegistryKey::getStringValue() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::registry::InvalidValueException, com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aValue = implGetValue();
+
+ rtl::OUString sReturn;
+ if (!aValue.hasValue())
+ checkNullable();// let NULL values pass
+
+ else if (!(aValue >>= sReturn))
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("This node does not contain a string value."), THISREF());
+
+ return sReturn;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::setStringValue( const ::rtl::OUString& _rValue ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ implSetValue(com::sun::star::uno::makeAny(_rValue));
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OConfigurationRegistryKey::getStringListValue() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::registry::InvalidValueException, com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aValue = implGetValue();
+
+ com::sun::star::uno::Sequence< rtl::OUString > aReturn;
+ if (!aValue.hasValue())
+ checkNullable();// let NULL values pass
+
+ else if (!(aValue >>= aReturn))
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node does not contain a list of strings !"), THISREF());
+
+ return aReturn;
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::setStringListValue( const com::sun::star::uno::Sequence< ::rtl::OUString >& _seqValue ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ implSetValue(com::sun::star::uno::makeAny(_seqValue));
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL OConfigurationRegistryKey::getBinaryValue() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::registry::InvalidValueException, com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aValue = implGetValue();
+
+ com::sun::star::uno::Sequence< sal_Int8 > aReturn;
+ if (!aValue.hasValue())
+ checkNullable();// let NULL values pass
+
+ else if (!(aValue >>= aReturn))
+ return aReturn;
+
+ throw com::sun::star::registry::InvalidValueException(UNISTRING("This configuration node does not contain a list of strings !"), THISREF());
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::setBinaryValue( const com::sun::star::uno::Sequence< sal_Int8 >& _rValue ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ implSetValue(com::sun::star::uno::makeAny(_rValue));
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > OConfigurationRegistryKey::implGetKey( const ::rtl::OUString& _rKeyName )
+ throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aDescendant = implGetDescendant(_rKeyName);
+ if (aDescendant.getValueType().getTypeClass() == com::sun::star::uno::TypeClass_INTERFACE)
+ {
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xNode;
+ ::cppu::extractInterface(xNode, aDescendant);
+ if (!xNode.is())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("invalid descendant node. No XNameAccess found."), THISREF());
+ return new OConfigurationRegistryKey(xNode, !m_bReadOnly);
+ }
+ else
+ {
+#if OSL_DEBUG_LEVEL > 1
+ switch (aDescendant.getValueType().getTypeClass())
+ {
+ case com::sun::star::uno::TypeClass_STRING:
+ case com::sun::star::uno::TypeClass_SHORT:
+ case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
+ case com::sun::star::uno::TypeClass_BYTE:
+ case com::sun::star::uno::TypeClass_LONG:
+ case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
+ case com::sun::star::uno::TypeClass_BOOLEAN:
+ case com::sun::star::uno::TypeClass_SEQUENCE:
+ break;
+ case com::sun::star::uno::TypeClass_VOID: // NULL value found
+ break;
+ default:
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::openKey : unknown, invalid or unhandled descendant value type !");
+ }
+#endif
+
+ OSL_ASSERT(m_xNode.is());
+
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xDescParent(m_xNode); // the parent config node of the descandent
+ rtl::OUString sDescRelativeName( _rKeyName ); // local name of the descendant within xDescParent
+
+ if (!m_xNode->hasByName(_rKeyName)) // it is a hierarchical Path -> more work
+ {
+ rtl::OUString sParentLocation;
+
+ if ( !splitPath(_rKeyName, sParentLocation, sDescRelativeName) )
+ {
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Cannot split path for value. The internal registry structure seems to be corrupt."), THISREF());
+ }
+
+ if (sParentLocation.getLength())
+ {
+ com::sun::star::uno::Any aDescParent = implGetDescendant(sParentLocation);
+ ::cppu::extractInterface(xDescParent, aDescParent);
+ if (!xDescParent.is())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The internal registry structure seems to be corrupt."), THISREF());
+ }
+ }
+
+ OSL_ENSURE(xDescParent.is(), "No Parent Node found for value ?");
+ OSL_ENSURE(xDescParent->hasByName(sDescRelativeName), "Parent Node does not contain found value ?");
+
+ return new OConfigurationRegistryKey(aDescendant, xDescParent, sDescRelativeName, !m_bReadOnly);
+ }
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > SAL_CALL OConfigurationRegistryKey::openKey( const ::rtl::OUString& _rKeyName ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ checkValid(KAT_CHILD);
+
+ return implGetKey(_rKeyName);
+}
+//--------------------------------------------------------------------------
+bool OConfigurationRegistryKey::checkRelativeKeyName(rtl::OUString& _rKeyName) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ // no empty names allowed
+ if (!_rKeyName.getLength())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid."), THISREF());
+
+ bool bCleanPath = true;
+
+ // cut trailing slashes
+ sal_Int32 nCleanEnd = _rKeyName.getLength();
+ while (nCleanEnd > 0 && _rKeyName[nCleanEnd - 1] == '/' )
+ --nCleanEnd;
+
+ if (m_xNode.is())
+ {
+ if (m_xNode-> hasByName(_rKeyName))
+ {
+ bCleanPath = false;
+ }
+
+ else
+ {
+ com::sun::star::uno::Reference< com::sun::star::util::XStringEscape > xSE(m_xNode, com::sun::star::uno::UNO_QUERY);
+
+ sal_Bool bPreferLocal = xSE.is();
+
+ if (!bPreferLocal)
+ {
+ com::sun::star::uno::Reference< com::sun::star::lang::XServiceInfo > xSI(m_xNode, com::sun::star::uno::UNO_QUERY);
+ if (xSI.is() && xSI->supportsService(rtl::OUString::createFromAscii("com.sun.star.configuration.SetAccess")))
+ bPreferLocal = true;
+ }
+
+ if (bPreferLocal)
+ {
+ com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xHA(m_xNode, com::sun::star::uno::UNO_QUERY);
+ rtl::OUString sCleanName = _rKeyName.copy(0, nCleanEnd);
+
+ if (xHA.is() && xHA->hasByHierarchicalName(sCleanName))
+ bPreferLocal = false;
+ }
+
+ if (bPreferLocal && xSE.is())
+ {
+ _rKeyName = xSE->escapeString(_rKeyName);
+ }
+ bCleanPath = !bPreferLocal;
+ }
+ }
+
+ if (bCleanPath)
+ {
+ // no absolute names ("/...") allowed
+ if (_rKeyName.getStr()[0] == '/')
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid. It must be a relative, not an absolute name."), THISREF());
+
+ if (nCleanEnd <= 0)
+ // the original name consists of slashes only
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid."), THISREF());
+
+
+ _rKeyName = _rKeyName.copy(0, nCleanEnd);
+ }
+ return bCleanPath;
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > SAL_CALL OConfigurationRegistryKey::createKey( const ::rtl::OUString& _rKeyName ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ checkValid(KAT_CHILD);
+
+ if (m_bReadOnly)
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key is read only."), THISREF());
+
+ OSL_ENSURE(m_xNode.is(), "OConfigurationRegistryKey::createKey : somebody changed the checkValid(KAT_CHILD) behaviour !");
+
+ rtl::OUString sKeyName(_rKeyName);
+ if (checkRelativeKeyName(sKeyName))
+ {
+ rtl::OUString sParentName, sLocalName;
+
+ if (!splitPath(sKeyName,sParentName, sLocalName))
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid."), THISREF());
+
+ if (sParentName.getLength()) // it's a nested key name
+ {
+ // check if we have the key already
+ com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xDeepAccess(m_xNode, com::sun::star::uno::UNO_QUERY);
+ if (xDeepAccess.is() && xDeepAccess->hasByHierarchicalName(sKeyName))
+ {
+ // already there - just open it
+ return implGetKey(sKeyName);
+ }
+
+ // deep access, but not found. delegate it to a registry key which is one level above the to-be-created one
+ com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > xSetNode = implGetKey(sParentName);
+ if (!xSetNode.is())
+ {
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::createKey : somebody changed the implGetKey behaviour !");
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("An internal error occured."), THISREF());
+ }
+ return xSetNode->createKey(sLocalName); // problem: request for a/['b/c'] might find a/b/c
+ }
+ else
+ sKeyName = sLocalName;
+ }
+
+ // The requested new key is one level below ourself. Can't delegate the creation.
+ if (m_xNode->hasByName(sKeyName) )
+ {
+ // already there - just open it
+ return implGetKey(sKeyName);
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xContainer(m_xNode, com::sun::star::uno::UNO_QUERY);
+ if (!xContainer.is())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The configuration node represented by this key is not a set node, you can't insert keys."), THISREF());
+
+ com::sun::star::uno::Any aValueToInsert;
+
+ com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xChildFactory(xContainer, com::sun::star::uno::UNO_QUERY);
+ if (xChildFactory.is())
+ {
+ // In the configuration API, the creation of a new child is two-stage process : first you create a child which
+ // is "floating", i.e. does not belong to the configuration tree, yet. After filling it with values, you insert
+ // it into the container node which was used for the creation.
+ // We can't map this behaviour with the registry API, so we have to combine both steps
+
+ // create a new floating child for the container node
+ try
+ {
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > xFloatingChild = xChildFactory->createInstance();
+ OSL_ENSURE( xFloatingChild.is(), "The newly created element is NULL !");
+
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xInsertedChild(xFloatingChild, com::sun::star::uno::UNO_QUERY);
+ OSL_ENSURE( xInsertedChild.is(), "The newly created element does not provide the required interface");
+
+ if (!xInsertedChild.is())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("An internal error occured. The objects provided by the configuration API are invalid."), THISREF());
+
+ aValueToInsert <<= xInsertedChild; // xFloatingChild;
+ }
+ catch (com::sun::star::uno::RuntimeException&)
+ { // allowed to leave this method
+ throw;
+ }
+ catch (com::sun::star::uno::Exception& e)
+ { // not allowed to leave this method
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Unable to create a new child for the configuration node. Original error message as provided by the configuration API : ") += e.Message,
+ THISREF());
+ }
+ OSL_ENSURE(aValueToInsert.hasValue(), "New Child node did not get into the Any ?");
+ }
+ else
+ {
+ // If the elements of the set are simple values, we need to create a matching value
+ com::sun::star::uno::Type aElementType = xContainer->getElementType();
+ aValueToInsert = implCreateDefaultElement(aElementType);
+
+ OSL_ENSURE(aValueToInsert.hasValue() || aElementType.getTypeClass() == com::sun::star::uno::TypeClass_ANY, "Internal error: NULL value created for new value element ?");
+ }
+
+ // and immediately insert it into the container
+ try
+ {
+ xContainer->insertByName(sKeyName, aValueToInsert);
+ }
+ catch (com::sun::star::lang::IllegalArgumentException& e)
+ {
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("illegal argument to InsertByName: ") += e.Message, THISREF());
+ }
+ catch (com::sun::star::container::ElementExistException& e)
+ {
+ OSL_ENSURE(false, "There was an element of the same name inserted just now");
+
+ // try to return that one
+ try { return implGetKey(sKeyName); }
+ catch (com::sun::star::uno::Exception&) { OSL_ENSURE(false, "But the other element cannot be retrieved"); }
+
+
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Inserting raised a NoSuchElementException for an unavailable element ! Original error message : ") += e.Message, THISREF());
+ }
+ catch (com::sun::star::lang::WrappedTargetException& e)
+ {
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Inserting raised a WrappedTargetException. Original error message : ") += e.Message, THISREF());
+ }
+
+ return new OConfigurationRegistryKey(aValueToInsert, m_xNode, sKeyName, !m_bReadOnly);
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::closeKey() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ OSL_ASSERT(UnoApiLock::isHeld());
+ checkValid(KAT_META);
+
+ bool bRoot = (m_sLocalName.getLength() == 0);
+
+ if (!bRoot) // don't close, if this is the root key ..
+ {
+ m_xNode.clear();
+ m_xParentNode.clear();
+// m_sLocalName = rtl::OUString(); - local name is const ...
+ }
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::deleteKey( const rtl::OUString& _rKeyName ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ checkValid(KAT_CHILD);
+ if (m_bReadOnly)
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key is read only."), THISREF());
+
+ rtl::OUString sKeyName(_rKeyName);
+ if (checkRelativeKeyName(sKeyName))
+ {
+ rtl::OUString sParentName, sLocalName;
+
+ if (!splitPath(sKeyName,sParentName, sLocalName))
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The key name is invalid."), THISREF());
+
+ if (sParentName.getLength()) // it's a nested key name
+ {
+ com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > xSetNode = implGetKey(sParentName);
+ if (!xSetNode.is())
+ {
+ OSL_ENSURE(sal_False, "OConfigurationRegistryKey::createKey : somebody changed the implGetKey behaviour !");
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("An internal error occured."), THISREF());
+ }
+ xSetNode->deleteKey(sLocalName);
+ return;
+ }
+ else
+ sKeyName = sLocalName;
+ }
+
+ // The requested new key is one level below ourself. Can't delegate the creation.
+ com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xContainer(m_xNode, com::sun::star::uno::UNO_QUERY);
+ if (!xContainer.is())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The configuration node represented by this key is not a set node, you can't remove keys."), THISREF());
+
+ // and immediately remove it from the container
+ try
+ {
+ xContainer->removeByName(sKeyName);
+ }
+ catch (com::sun::star::container::NoSuchElementException& e)
+ {
+ if (e.Message.getLength())
+ throw com::sun::star::registry::InvalidRegistryException(e.Message, THISREF());
+ else
+ throw com::sun::star::registry::InvalidRegistryException((UNISTRING("There is no element named ") += sKeyName) += UNISTRING(" to remove."), THISREF());
+ }
+ catch (com::sun::star::lang::WrappedTargetException& e)
+ {
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("Removing a node caused a WrappedTargetException. Original error message : ") += e.Message, THISREF());
+ }
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > > SAL_CALL OConfigurationRegistryKey::openKeys() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ checkValid(KAT_CHILD);
+
+ com::sun::star::uno::Sequence< ::rtl::OUString > aNames(m_xNode->getElementNames());
+
+ sal_Int32 const nCount = aNames.getLength();
+
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > > aReturn(nCount);
+
+ for (sal_Int32 i=0; i<nCount; ++i)
+ aReturn[i] = implGetKey(aNames[i]);
+
+ return aReturn;
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OConfigurationRegistryKey::getKeyNames() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ checkValid(KAT_CHILD);
+ return m_xNode->getElementNames();
+}
+
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL OConfigurationRegistryKey::createLink( const ::rtl::OUString& /*aLinkName*/, const ::rtl::OUString& /*aLinkTarget*/ ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry, which is base on a configuration tree, does not support links."), THISREF());
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistryKey::deleteLink( const ::rtl::OUString& /*rLinkName*/ ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry, which is base on a configuration tree, does not support links."), THISREF());
+}
+
+//--------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OConfigurationRegistryKey::getLinkTarget( const ::rtl::OUString& /*rLinkName*/ ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry, which is base on a configuration tree, does not support links."), THISREF());
+}
+
+//--------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OConfigurationRegistryKey::getResolvedName( const ::rtl::OUString& /*aKeyName*/ ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry, which is base on a configuration tree, does not support links."), THISREF());
+}
+//--------------------------------------------------------------------------
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+// split path
+#include "configpath.hxx"
+#include "configexcept.hxx"
+
+bool configmgr::splitPath(const rtl::OUString& _sPath, rtl::OUString& _rsParentPath, rtl::OUString& _rsLocalName)
+{
+ bool bResult = false;
+ try
+ {
+ bool bAbsolute = configmgr::configuration::Path::isAbsolutePath(_sPath);
+ configmgr::configuration::Path::Rep aPath ;
+
+ if (bAbsolute)
+ {
+ configmgr::configuration::AbsolutePath parsedPath = configmgr::configuration::AbsolutePath::parse(_sPath) ;
+
+ aPath = parsedPath.rep() ;
+ }
+ else
+ {
+ configmgr::configuration::RelativePath parsedPath = configmgr::configuration::RelativePath::parse(_sPath) ;
+
+ aPath = parsedPath.rep() ;
+ }
+ //configmgr::configuration::Path::Rep aPath = bAbsolute ? configmgr::configuration::AbsolutePath::parse(_sPath).rep() : configmgr::configuration::RelativePath::parse(_sPath).rep();
+
+ OSL_ENSURE(!aPath.isEmpty(), "Trying to split an empty or root path");
+ std::vector<configuration::Path::Component>::const_reverse_iterator aFirst = aPath.begin(), aLast = aPath.end();
+
+ if (aFirst != aLast)
+ {
+ --aLast;
+
+ _rsLocalName = aLast->getName();
+ _rsParentPath = configmgr::configuration::Path::Rep(aFirst,aLast).toString(bAbsolute);
+
+ bResult = true;
+ }
+ // else go on to fail
+ }
+ catch (configuration::Exception&)
+ {
+ }
+ return bResult;
+}
+//..........................................................................
+
+
diff --git a/configmgr/source/registry/cfgregistrykey.hxx b/configmgr/source/registry/cfgregistrykey.hxx
new file mode 100644
index 000000000000..4129d0bcaabf
--- /dev/null
+++ b/configmgr/source/registry/cfgregistrykey.hxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgregistrykey.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_REGISTRY_CFGREGISTRYKEY_HXX_
+#define _CONFIGMGR_REGISTRY_CFGREGISTRYKEY_HXX_
+
+#include <cppuhelper/implbase1.hxx>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+
+//..........................................................................
+namespace configmgr
+{
+//..........................................................................
+
+//==========================================================================
+//= OConfigurationRegistryKey
+//==========================================================================
+/** wraps the registry-like access to a single node of a configuration sub tree
+*/
+class OConfigurationRegistryKey
+ :public cppu::WeakImplHelper1< com::sun::star::registry::XRegistryKey >
+{
+ sal_Bool m_bReadOnly; /// is the key readonly ?
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
+ m_xNode; /// the config node object, if it is a container
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
+ m_xParentNode; /// if the key is not the root, this is it's parent.
+
+ const ::rtl::OUString m_sLocalName; /** the name of the element relative to the parent, which is
+ m_xParentNode if that is present
+ */
+
+ // TODO : the current concept does not recognize when config keys are disposed (e.g. when the registry is closed)
+ //
+ // Possible solutions:
+ // 1. each registry key is a listener on the component containing its node
+ // may be is expensive ?.
+ //
+ // At the moment we ignore this restriction, but perhaps we can't do that forever ....
+
+public:
+ /// when used as ctor parameter, this indicates that the key wraps a config tree subtree root
+ struct SubtreeRoot { };
+
+ /** builds an registry key which wraps the root of a configuration registry
+ */
+ OConfigurationRegistryKey(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxRootNode
+ ,sal_Bool _bWriteable
+ ,SubtreeRoot
+ );
+
+ /** builds an registry key for a configuration node
+ @param _rxContainerNode the node the key should represent
+ @param _bWriteable should the key be writeable ?
+ */
+ OConfigurationRegistryKey(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxNode
+ ,sal_Bool _bWriteable
+ );
+
+ /** builds an registry key for a configuration value container node.
+ @param _rCurrentValue the current value of the node. Must be the same as _rxParentNode->getByName(_rRelativeName) would provide
+ @param _rxParentNode the parent of the value node. Used for update access and for obtaining the initial value.
+ @param _rRelativeName te relative name within the parent
+ @param _bWriteable should the key be writeable ?
+ */
+ OConfigurationRegistryKey(
+ ::com::sun::star::uno::Any _rCurrentValue
+ ,const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxParentNode
+ ,const ::rtl::OUString& _rRelativeName
+ ,sal_Bool _bWriteable
+ );
+
+ // XRegistryKey
+ virtual ::rtl::OUString SAL_CALL getKeyName() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isReadOnly( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isValid( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::registry::RegistryKeyType SAL_CALL getKeyType( const ::rtl::OUString& rKeyName ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::registry::RegistryValueType SAL_CALL getValueType( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getLongValue( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::registry::InvalidValueException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setLongValue( sal_Int32 value ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::registry::InvalidValueException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setLongListValue( const ::com::sun::star::uno::Sequence< sal_Int32 >& seqValue ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getAsciiValue( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::registry::InvalidValueException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setAsciiValue( const ::rtl::OUString& value ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAsciiListValue( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::registry::InvalidValueException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setAsciiListValue( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& seqValue ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getStringValue( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::registry::InvalidValueException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setStringValue( const ::rtl::OUString& value ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getStringListValue( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::registry::InvalidValueException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setStringListValue( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& seqValue ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::registry::InvalidValueException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBinaryValue( const ::com::sun::star::uno::Sequence< sal_Int8 >& value ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey > SAL_CALL openKey( const ::rtl::OUString& aKeyName ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey > SAL_CALL createKey( const ::rtl::OUString& aKeyName ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeKey( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deleteKey( const ::rtl::OUString& rKeyName ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey > > SAL_CALL openKeys( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getKeyNames( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL createLink( const ::rtl::OUString& aLinkName, const ::rtl::OUString& aLinkTarget ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deleteLink( const ::rtl::OUString& rLinkName ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getLinkTarget( const ::rtl::OUString& rLinkName ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getResolvedName( const ::rtl::OUString& aKeyName ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ /** specifies the kind of access to the key.
+ */
+ enum KEY_ACCESS_TYPE
+ {
+ KAT_META, /// access on a meta level, e.g. asking for the read-onyl flag
+ KAT_VALUE, /// read access to the value the node represents
+ KAT_VALUE_WRITE, /// write access to the value the node represents
+ KAT_CHILD /// access to one of the (grand-)children of the node
+ };
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
+ implGetParentPropertyInfo()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ sal_Bool implIsReadOnly()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ sal_Bool implEnsureNode()
+ throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+ ::com::sun::star::uno::Type implGetUnoType()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ sal_Bool implEnsureValue()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ sal_Bool implIsValid() throw ();
+
+ /** check if the registry key is valid
+ @param _eIntentedAccess type of access which the caller wants to perform on the object
+ @throws <type scope="com.sun.star.registry">InvalidRegistryException</type> if the key is invalid
+ */
+ void checkValid(KEY_ACCESS_TYPE _eIntentedAccess)
+ throw (::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+ /** return an child element.
+ @param _rDescendantName the name of the descendant to open. May have a depth of more than 1, if
+ the node container support XHierarchicalNameAccess
+ @return the requested element. The caller can assume that the returned
+ <type scope="com.sun.star.uno">Any</type> always contains an object, all other cases are
+ handled with exceptions
+ @throws <type scope="com.sun.star.registry">InvalidRegistryException</type> if the key is invalid,
+ the element refered by _rName does not exist, the configuration node threw an exception, or
+ the name has a depth of more than one and the config node does not support this.
+ */
+ ::com::sun::star::uno::Any
+ implGetDescendant(const ::rtl::OUString& _rDescendantName)
+ throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+ /** write the given value into the configuration node the object represents.
+ @throws <type scope="com.sun.star.registry">InvalidRegistryException</type> if the key is invalid,
+ not opened for write access or the configurations parent is not able to provide a value access
+ @throws <type scope="com.sun.star.uno">RuntimeException</type> if a fatal runtime error occurs
+ */
+ void implSetValue(const ::com::sun::star::uno::Any& _rValue)
+ throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+ ::com::sun::star::uno::Any implGetValue()
+ throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+ /** open the sub key (depth 1 or more) determined by the given name
+ @param _rKeyName the name of the descendant node
+ @return a XRegistryKey wrapper for the requested configuration node
+ @throws <type scope="com.sun.star.registry">InvalidRegistryException</type> if the key is invalid,
+ the element refered by _rName does not exist, the configuration node threw an exception, or
+ the name has a depth of more than one and the config node does not support this.
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey >
+ implGetKey( const ::rtl::OUString& _rKeyName )
+ throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+ /** check the given (relative) key name syntactically.
+
+ <p>In particular, this means that no checks are made if a node with the given name exists or something like
+ that ...<br/>
+ In addition, the given name will be normalized. Basically, this means that it does not contain trailing slashes.
+ </p>
+ @returns
+ <TRUE/> if the name is a valid relative path
+ <FALSE/> if the name is a local name only
+ @throws InvalidRegistryException
+ if the name is invalid or not relative (i.e. if it starts with an slash)
+ */
+ bool checkRelativeKeyName(::rtl::OUString& _rKeyName)
+ throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+ /** get a default value for a value of a given type
+
+ <p>Creates an Any with an empty or zero value of the given type.</p>
+
+ @param _rType the type of the element to create
+ @return
+ an <type scope="com::sun::star::uno">Any</type> representing a default for the node value type. If the
+ return value is still VOID, the node has a nullable type (e.g. any) or is of unsupported type
+
+ */
+ ::com::sun::star::uno::Any
+ implCreateDefaultElement(::com::sun::star::uno::Type const& _rType)
+ throw(::com::sun::star::uno::RuntimeException);
+};
+
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+#endif // _CONFIGMGR_REGISTRY_CFGREGISTRYKEY_HXX_
+
+
diff --git a/configmgr/source/registry/configregistry.cxx b/configmgr/source/registry/configregistry.cxx
new file mode 100644
index 000000000000..73711feb9c5f
--- /dev/null
+++ b/configmgr/source/registry/configregistry.cxx
@@ -0,0 +1,379 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configregistry.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+
+#include "configregistry.hxx"
+#include "cfgregistrykey.hxx"
+#include "confapifactory.hxx"
+#include "datalock.hxx"
+#include "utility.hxx"
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <osl/diagnose.h>
+#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#define THISREF() static_cast< ::cppu::OWeakObject* >(this)
+#define UNISTRING(c) makeUniString(c)
+
+//..........................................................................
+namespace configmgr
+{
+//..........................................................................
+
+namespace beans = ::com::sun::star::beans;
+
+//==========================================================================
+//= OConfigurationRegistry
+//==========================================================================
+ inline
+ static
+ rtl::OUString makeUniString(char const* c)
+ {
+ return rtl::OUString::createFromAscii(c);
+ }
+
+
+ // #99130# Don't export SimpleRegistry service
+ static sal_Char const * const aExportedConfigRegistryServices[] =
+ {
+ "com.sun.star.configuration.ConfigurationRegistry",
+ NULL
+ };
+ static sal_Char const * const aAdditionalConfigRegistryServices[] =
+ {
+ "com.sun.star.registry.SimpleRegistry",
+ NULL
+ };
+
+ sal_Char const * const aConfigRegistryImplementationName = "com.sun.star.comp.configuration.OConfigurationRegistry";
+
+ const ServiceImplementationInfo OConfigurationRegistry::s_aServiceInfo =
+ {
+ aConfigRegistryImplementationName,
+ aExportedConfigRegistryServices,
+ aAdditionalConfigRegistryServices
+ };
+
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL instantiateConfigRegistry(uno::Reference< uno::XComponentContext > const& xContext )
+ {
+ OSL_ASSERT( xContext.is() );
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xServiceManager( xContext->getServiceManager(), com::sun::star::uno::UNO_QUERY );
+ ::cppu::OWeakObject * pNewInstance = new OConfigurationRegistry(xServiceManager);
+ return pNewInstance;
+ }
+
+ const ServiceRegistrationInfo* getConfigurationRegistryServiceInfo()
+ {
+ return getRegistrationInfo(& OConfigurationRegistry::s_aServiceInfo);
+ }
+
+//--------------------------------------------------------------------------
+OConfigurationRegistry::OConfigurationRegistry(const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& _rORB) throw(com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException)
+ :ServiceComponentImpl(&s_aServiceInfo)
+ ,m_xORB(_rORB)
+{
+ // create the configuration provider used for accessing the configuration
+ OSL_ENSURE(m_xORB.is(), "OConfigurationRegistry::OConfigurationRegistry : invalid service factory !");
+ if (m_xORB.is())
+ {
+ m_xConfigurationProvider =
+ m_xConfigurationProvider.query(
+ m_xORB->createInstance(UNISTRING("com.sun.star.configuration.ConfigurationProvider"))
+ );
+ }
+
+ if (!m_xConfigurationProvider.is())
+ {
+ // it's heavily needed ...
+ throw com::sun::star::lang::ServiceNotRegisteredException(UNISTRING("Failed to instantiate the mandatory service com.sun.star.configuration.ConfigurationProvider."),
+ THISREF());
+ }
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Any SAL_CALL OConfigurationRegistry::queryInterface( const com::sun::star::uno::Type& _rType ) throw(com::sun::star::uno::RuntimeException)
+{
+ com::sun::star::uno::Any aReturn = ServiceComponentImpl::queryInterface(_rType);
+ if (!aReturn.hasValue())
+ aReturn = cppu::ImplHelper2< com::sun::star::registry::XSimpleRegistry, com::sun::star::util::XFlushable >::queryInterface(_rType);
+ return aReturn;
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Sequence< com::sun::star::uno::Type > SAL_CALL OConfigurationRegistry::getTypes( ) throw(com::sun::star::uno::RuntimeException)
+{
+ return ::comphelper::concatSequences(
+ ServiceComponentImpl::getTypes(),
+ cppu::ImplHelper2< com::sun::star::registry::XSimpleRegistry, com::sun::star::util::XFlushable >::getTypes());
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL OConfigurationRegistry::getImplementationId( ) throw(com::sun::star::uno::RuntimeException)
+{
+ static cppu::OImplementationId aId;
+ return aId.getImplementationId();
+}
+
+//--------------------------------------------------------------------------
+::rtl::OUString OConfigurationRegistry::getNodePathFromURL(const ::rtl::OUString& _rURL)
+{
+ // TODO
+ return _rURL;
+}
+
+//--------------------------------------------------------------------------
+::rtl::OUString SAL_CALL OConfigurationRegistry::getURL() throw(com::sun::star::uno::RuntimeException)
+{
+ UnoApiLock aLock;
+ return m_sLocation;
+}
+
+//--------------------------------------------------------------------------
+
+// Not guarded !
+void OConfigurationRegistry::implCheckOpen() throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ if (!implIsOpen())
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The registry is not bound to a configuration node."), THISREF());
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistry::open( const ::rtl::OUString& _rURL, sal_Bool _bReadOnly, sal_Bool /*_bCreate*/ ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ if (implIsOpen())
+ close();
+
+ ::rtl::OUString sNodePath = getNodePathFromURL(_rURL);
+
+ if (!m_xConfigurationProvider.is())
+ throw com::sun::star::lang::DisposedException(UNISTRING("invalid object. configuration provider is already disposed."), THISREF());
+
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > xNodeAccess;
+ try
+ {
+ char const * const sAccessType = _bReadOnly ?
+ "com.sun.star.configuration.ConfigurationAccess" :
+ "com.sun.star.configuration.ConfigurationUpdateAccess";
+
+ // prepare parameters for creating the config access : the node path
+ beans::PropertyValue aArgValue;
+ aArgValue.Handle = -1;
+
+ // currently theres is one parameter: the node path
+ com::sun::star::uno::Sequence< com::sun::star::uno::Any > aArguments(1);
+
+ aArgValue.Name = UNISTRING("nodepath");
+ aArgValue.Value <<= sNodePath;
+
+ aArguments[0] <<= aArgValue;
+
+
+ xNodeAccess = m_xConfigurationProvider->createInstanceWithArguments(UNISTRING(sAccessType), aArguments);
+ }
+ catch (com::sun::star::uno::RuntimeException&)
+ { // allowed to leave this method
+ throw;
+ }
+ catch (com::sun::star::uno::Exception& e)
+ { // not allowed to leave this method
+ ::rtl::OUString sMessage = UNISTRING("The configuration provider does not supply a registry access for the requested Node.");
+ sMessage += UNISTRING(" original error message of the provider : ");
+ sMessage += e.Message;
+ throw com::sun::star::registry::InvalidRegistryException(sMessage, THISREF());
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xReadRoot(xNodeAccess, com::sun::star::uno::UNO_QUERY);
+ if (!_bReadOnly)
+ m_xUpdateRoot = m_xUpdateRoot.query(xReadRoot);
+
+ if (!xReadRoot.is() || (!_bReadOnly && !m_xUpdateRoot.is()))
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("The object supplied the by configuration provider is invalid."), THISREF());
+
+ m_xRootKey = new OConfigurationRegistryKey(xReadRoot, !_bReadOnly, OConfigurationRegistryKey::SubtreeRoot());
+ m_xSubtreeRoot = xNodeAccess;
+}
+
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL OConfigurationRegistry::isValid( ) throw(com::sun::star::uno::RuntimeException)
+{
+ UnoApiLock aLock;
+ return implIsOpen();
+}
+
+//--------------------------------------------------------------------------
+sal_Bool OConfigurationRegistry::implIsOpen( ) throw(com::sun::star::uno::RuntimeException)
+{
+ return m_xRootKey.is();
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistry::close( ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ UnoApiLock aLock;
+
+ com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > xRootKey(m_xRootKey);
+ m_xRootKey = NULL;
+
+ com::sun::star::uno::Reference< XComponent > xRootComponent(m_xSubtreeRoot, com::sun::star::uno::UNO_QUERY);
+ m_xSubtreeRoot = NULL;
+ m_xUpdateRoot = NULL;
+
+ m_sLocation = ::rtl::OUString();
+
+ if (xRootKey.is())
+ xRootKey->closeKey();
+
+ if (xRootComponent.is())
+ xRootComponent->dispose();
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistry::disposing()
+{
+ close();
+
+ {
+ UnoApiLock aLock;
+
+ m_xConfigurationProvider.clear();
+ m_xORB.clear();
+ }
+
+ ServiceComponentImpl::disposing();
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistry::destroy( ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ UnoApiLock aLock;
+ implCheckOpen();
+
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("This registry is a wrapper for a configuration access. It can not be destroyed."), THISREF());
+}
+
+//--------------------------------------------------------------------------
+com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > SAL_CALL OConfigurationRegistry::getRootKey( ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ UnoApiLock aLock;
+ implCheckOpen();
+
+ return m_xRootKey;
+}
+
+//--------------------------------------------------------------------------
+sal_Bool SAL_CALL OConfigurationRegistry::isReadOnly( ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::uno::RuntimeException)
+{
+ UnoApiLock aLock;
+ implCheckOpen();
+
+ return !m_xUpdateRoot.is();
+ // if we don't have the update root, we're readonly
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistry::mergeKey( const ::rtl::OUString& /*aKeyName*/, const ::rtl::OUString& /*aUrl*/ ) throw(com::sun::star::registry::InvalidRegistryException, com::sun::star::registry::MergeConflictException, com::sun::star::uno::RuntimeException)
+{
+ UnoApiLock aLock;
+ implCheckOpen();
+
+ // not supported. but we can't throw an NoSupportException here ...
+ throw com::sun::star::registry::InvalidRegistryException(UNISTRING("You can't merge into this registry. It's just a wrapper for a configuration node, which has a fixed structure which can not be modified"), THISREF());
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistry::flush( ) throw(com::sun::star::uno::RuntimeException)
+{
+ {
+ UnoApiLock aLock;
+ if (m_xUpdateRoot.is())
+ {
+ try
+ {
+ m_xUpdateRoot->commitChanges();
+ }
+ catch (com::sun::star::lang::WrappedTargetException& e)
+ { // not allowed to leave this method
+
+ ::rtl::OUString sMessage;
+ sMessage = UNISTRING("The changes made could not be committed. Orginal exception message : ");
+ sMessage += e.Message;
+
+ // TODO : the specification of XFlushable has to be changed !!!!!
+ OSL_ENSURE(sal_False, "OConfigurationRegistry::flush : caught an exception, could not flush the data !");
+ // return;
+
+ throw com::sun::star::lang::WrappedTargetRuntimeException(sMessage, THISREF(), e.TargetException);
+ }
+ }
+ }
+
+ com::sun::star::uno::Reference< com::sun::star::util::XFlushListener > const * const pSelector = 0;
+ if (cppu::OInterfaceContainerHelper* pContainer = this->rBHelper.getContainer(::getCppuType(pSelector)) )
+ {
+ ::cppu::OInterfaceIteratorHelper aIter( *pContainer );
+
+ com::sun::star::lang::EventObject aFlushed(THISREF());
+ while (aIter.hasMoreElements())
+ try
+ {
+ static_cast< com::sun::star::util::XFlushListener* >(aIter.next())->flushed(aFlushed);
+ }
+ catch (uno::Exception & )
+ {}
+ }
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistry::addFlushListener( const com::sun::star::uno::Reference< com::sun::star::util::XFlushListener >& _rxListener ) throw(com::sun::star::uno::RuntimeException)
+{
+ this->rBHelper.addListener(::getCppuType(&_rxListener),_rxListener);
+}
+
+//--------------------------------------------------------------------------
+void SAL_CALL OConfigurationRegistry::removeFlushListener( const com::sun::star::uno::Reference< com::sun::star::util::XFlushListener >& _rxListener ) throw(com::sun::star::uno::RuntimeException)
+{
+ this->rBHelper.removeListener(::getCppuType(&_rxListener),_rxListener);
+}
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+
diff --git a/configmgr/source/registry/configregistry.hxx b/configmgr/source/registry/configregistry.hxx
new file mode 100644
index 000000000000..7fba457b8f69
--- /dev/null
+++ b/configmgr/source/registry/configregistry.hxx
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configregistry.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONFIGMGR_REGISTRY_CONFIGREGISTRY_HXX_
+#define _CONFIGMGR_REGISTRY_CONFIGREGISTRY_HXX_
+
+#include <cppuhelper/implbase2.hxx>
+#include "confsvccomponent.hxx"
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+//..........................................................................
+namespace configmgr
+{
+//..........................................................................
+
+//==========================================================================
+//= OConfigurationRegistry
+//==========================================================================
+/** an object implmenting the <service scope="com.sun.star.configuration">ConfigurationRegistry</service>
+ service.
+*/
+class OConfigurationRegistry
+ :public ServiceComponentImpl
+ ,public cppu::ImplHelper2< com::sun::star::registry::XSimpleRegistry, com::sun::star::util::XFlushable >
+{
+public:
+ static const ServiceImplementationInfo s_aServiceInfo;
+
+protected:
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
+ m_xORB; /// the service provider used for creating the instance
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
+ m_xConfigurationProvider; /// the configuration provider used for creating configuration accesses
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey >
+ m_xRootKey; /// the root key for the registry-like configuration access
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ m_xSubtreeRoot; /// the root of the sub tree the object wraps
+ ::com::sun::star::uno::Reference< ::com::sun::star::util::XChangesBatch >
+ m_xUpdateRoot; /// the update access to the root of the sub tree, valid if opened for writing
+ ::rtl::OUString m_sLocation; /// URL of the configuration node we're representing, if any
+
+
+public:
+ OConfigurationRegistry(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rORB)
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire( ) throw() { ServiceComponentImpl::acquire(); }
+ virtual void SAL_CALL release( ) throw() { ServiceComponentImpl::release(); }
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XSimpleRegistry
+ virtual ::rtl::OUString SAL_CALL getURL() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL open( const ::rtl::OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isValid( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL close( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL destroy( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey > SAL_CALL getRootKey( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isReadOnly( ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL mergeKey( const ::rtl::OUString& aKeyName, const ::rtl::OUString& aUrl ) throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::registry::MergeConflictException, ::com::sun::star::uno::RuntimeException);
+
+ // XFlushable
+ virtual void SAL_CALL flush( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL addFlushListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XFlushListener >& l ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeFlushListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XFlushListener >& l ) throw(::com::sun::star::uno::RuntimeException);
+
+protected:
+ virtual void SAL_CALL disposing();
+ /// translates the given URL into a nodepath which may be used with the configuration provider
+ ::rtl::OUString getNodePathFromURL(const ::rtl::OUString& _rURL);
+
+ void implCheckOpen() throw(::com::sun::star::registry::InvalidRegistryException, ::com::sun::star::uno::RuntimeException);
+
+ sal_Bool implIsOpen()
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+#endif // _CONFIGMGR_REGISTRY_CONFIGREGISTRY_HXX_
+
+
diff --git a/configmgr/source/registry/makefile.mk b/configmgr/source/registry/makefile.mk
new file mode 100644
index 000000000000..3a8c12c8f573
--- /dev/null
+++ b/configmgr/source/registry/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source$/inc
+PRJNAME=configmgr
+TARGET=registry
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+# --- Files -------------------------------------
+
+SLOFILES=\
+ $(SLO)$/configregistry.obj \
+ $(SLO)$/cfgregistrykey.obj \
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/tree/builddata.cxx b/configmgr/source/tree/builddata.cxx
new file mode 100644
index 000000000000..9fc78aa7fc97
--- /dev/null
+++ b/configmgr/source/tree/builddata.cxx
@@ -0,0 +1,1137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: builddata.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "sal/types.h"
+
+#include "builddata.hxx"
+#include "nodevisitor.hxx"
+#include "node.hxx"
+#include "treefragment.hxx"
+#include "valuenode.hxx"
+#include "treenodefactory.hxx"
+#include "utility.hxx"
+
+#ifndef INCLUDED_CSTDDEF
+#include <cstddef>
+#define INCLUDED_CSTDDEF
+#endif
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+#include <vector>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace data
+ {
+//-----------------------------------------------------------------------------
+
+ static
+ inline
+ sharable::Node * offsetNodeBy(sharable::Node * _aNode, sal_uInt16 _nOffset)
+ {
+ sharable::Node *pNode = _aNode;
+ pNode += _nOffset;
+ return (sharable::Node *)(pNode);
+ }
+
+ static
+ inline
+ sharable::Node * addressOfNodeAt(sharable::TreeFragment * _aTree, sal_uInt16 _nOffset)
+ {
+ sharable::TreeFragment *pRaw = _aTree;
+ return &pRaw->nodes[_nOffset];
+ }
+
+//-----------------------------------------------------------------------------
+
+ class TreeNodeBuilder
+ {
+ sharable::TreeFragmentHeader m_header;
+ std::vector< sharable::Node > m_nodes;
+ sal_uInt16 m_parent;
+ public:
+ TreeNodeBuilder() : m_header(), m_nodes(), m_parent() {}
+
+ sharable::TreeFragmentHeader & header() { return m_header; }
+
+ sharable::Node & nodeAt(sal_uInt16 _pos) { checkOffset(_pos); return m_nodes[_pos]; }
+ sharable::NodeInfo & nodeInfoAt(sal_uInt16 _pos) { checkOffset(_pos); return m_nodes[_pos].info; }
+
+ sharable::Node & lastNode() { checkOffset(0); return m_nodes.back(); }
+ sharable::NodeInfo & lastNodeInfo() { checkOffset(0); return m_nodes.back().info; }
+
+ void resetTreeFragment(rtl_uString * _treeName, sal_uInt8 _state);
+
+ sharable::TreeFragment * createTreeFragment();
+
+ sal_uInt16 startGroup( rtl_uString * _aName, sal_uInt8 _aFlags );
+ void endGroup( sal_uInt16 _nPos );
+
+ void addSet( rtl_uString * _aName, sal_uInt8 _aFlags, sal_uInt8 * _aElementType );
+
+ void addValue( rtl_uString * _aName, sal_uInt8 _aFlags,
+ sal_uInt8 _aValueType,
+ sharable::AnyData _aUserValue,
+ sharable::AnyData _aDefaultName );
+ public:
+ class CollectSetElements;
+ class LinkSetNodes;
+
+ private:
+ sharable::TreeFragment * allocTreeFragment();
+ void linkTreeFragment(sharable::TreeFragment * _aTreeAddr);
+
+ sal_uInt16 addNode(rtl_uString * _aName, sal_uInt8 _aFlags, sal_uInt8 _aType);
+ void checkOffset(sal_uInt16 _pos);
+ };
+//-----------------------------------------------------------------------------
+
+ class TreeNodeBuilder::CollectSetElements
+ {
+ sharable::TreeFragment * m_head;
+ public:
+ explicit
+ CollectSetElements() : m_head(NULL) {}
+
+ void resetElementList();
+ void addElement(sharable::TreeFragment * _aNewElement);
+ sharable::TreeFragment * getElementListAndClear();
+ };
+//-----------------------------------------------------------------------------
+
+ class TreeNodeBuilder::LinkSetNodes: private SetVisitor {
+ sharable::Node * m_parent;
+ public:
+ LinkSetNodes(): m_parent(0) {}
+
+ void linkTree(sharable::TreeFragment * tree);
+
+ private:
+ using SetVisitor::handle;
+
+ virtual bool handle(sharable::SetNode * node);
+
+ virtual bool handle(sharable::TreeFragment * tree);
+ };
+//-----------------------------------------------------------------------------
+
+ class BasicDataTreeBuilder
+ {
+ public:
+ explicit
+ BasicDataTreeBuilder() {}
+
+ sharable::TreeFragment * createTree() { return m_builder.createTreeFragment(); }
+
+ protected:
+ TreeNodeBuilder& builder() { return m_builder; }
+ private:
+ TreeNodeBuilder m_builder;
+ };
+//-----------------------------------------------------------------------------
+
+ class ConvertingDataTreeBuilder : private NodeAction, public BasicDataTreeBuilder
+ {
+ rtl::OUString m_sRootName;
+ bool m_bWithDefaults;
+ public:
+ explicit
+ ConvertingDataTreeBuilder() : BasicDataTreeBuilder() {}
+
+ sharable::TreeFragment * buildTree(rtl::OUString const & _aTreeName, INode const& _aNode, bool _bWithDefault);
+ sharable::TreeFragment * buildElement(INode const& _aNode, rtl::OUString const & _aTypeName, bool _bWithDefault);
+ private:
+ class ElementListBuilder;
+
+ virtual void handle(ISubtree const & _aNode);
+ virtual void handle(ValueNode const & _aNode);
+
+ sal_uInt8 * makeTemplateData(rtl::OUString const & _aTemplateName, rtl::OUString const & _aTemplateModule);
+
+ rtl_uString * allocName(INode const & _aNode);
+ sal_uInt8 makeState(node::Attributes const & _aAttributes);
+ sal_uInt8 makeFlags(node::Attributes const & _aAttributes);
+ };
+//-----------------------------------------------------------------------------
+
+ class ConvertingDataTreeBuilder::ElementListBuilder : private NodeAction
+ {
+ TreeNodeBuilder::CollectSetElements m_aCollector;
+
+ rtl::OUString m_sTypeName;
+ bool m_bWithDefaults;
+ public:
+ explicit
+ ElementListBuilder()
+ : m_aCollector()
+ , m_sTypeName()
+ , m_bWithDefaults()
+ {}
+
+ sharable::TreeFragment *buildElementList(ISubtree const & _aSet, bool _bWithDefaults);
+ private:
+ void handleNode(INode const & _aSourceNode);
+
+ void handle(ValueNode const & _aSourceNode);
+ void handle(ISubtree const & _aSourceNode);
+ };
+//-----------------------------------------------------------------------------
+
+ class CopyingDataTreeBuilder : private NodeVisitor, public BasicDataTreeBuilder
+ {
+ public:
+ explicit
+ CopyingDataTreeBuilder() : BasicDataTreeBuilder() {}
+
+ sharable::TreeFragment * buildTree(sharable::TreeFragment * sourceTree);
+
+ private:
+ class ElementListBuilder;
+
+ using NodeVisitor::handle;
+ virtual bool handle(sharable::ValueNode * node);
+ virtual bool handle(sharable::GroupNode * node);
+ virtual bool handle(sharable::SetNode * node);
+
+ sal_uInt8 * makeTemplateData(sal_uInt8 * _aSourceTemplate);
+ };
+//-----------------------------------------------------------------------------
+
+ class CopyingDataTreeBuilder::ElementListBuilder : private SetVisitor
+ {
+ TreeNodeBuilder::CollectSetElements m_aCollector;
+ public:
+ explicit
+ ElementListBuilder() : m_aCollector() {}
+
+ sharable::TreeFragment * buildElementList(sharable::SetNode * set);
+
+ private:
+ using SetVisitor::handle;
+ virtual bool handle(sharable::TreeFragment * tree);
+ };
+//-----------------------------------------------------------------------------
+
+ class ConvertingNodeBuilder : private NodeVisitor
+ {
+ OTreeNodeFactory & m_rNodeFactory;
+
+ std::auto_ptr<INode> m_pNode;
+ public:
+ ConvertingNodeBuilder(OTreeNodeFactory & _rNodeFactory)
+ : m_rNodeFactory(_rNodeFactory)
+ , m_pNode()
+ {
+ }
+
+ std::auto_ptr<INode> buildNode(sharable::TreeFragment * tree, bool _bUseTreeName);
+ std::auto_ptr<INode> buildNode(sharable::Node * tree);
+
+ std::auto_ptr<ISubtree> buildNodeTree(sharable::GroupNode * groupNode) const;
+ std::auto_ptr<ISubtree> buildNodeTree(sharable::SetNode * setNode) const;
+ std::auto_ptr<ValueNode> buildNodeTree(sharable::ValueNode * valueNode) const
+ { return convertNode(valueNode); }
+
+ static node::Attributes convertAttributes(sharable::Node * node)
+ { return node->getAttributes(); }
+
+ private:
+ std::auto_ptr<ISubtree> convertNode(sharable::GroupNode * groupNode) const;
+ std::auto_ptr<ISubtree> convertNode(sharable::SetNode * setNode) const;
+ std::auto_ptr<ValueNode> convertNode(sharable::ValueNode * valueNode) const;
+
+ using NodeVisitor::handle;
+ virtual bool handle(sharable::ValueNode * node);
+ virtual bool handle(sharable::GroupNode * node);
+ virtual bool handle(sharable::SetNode * node);
+ };
+//-----------------------------------------------------------------------------
+
+ class ConvertingSubnodeBuilder : private SetVisitor
+ {
+ ConvertingNodeBuilder m_aSubnodeBuilder;
+ ISubtree & m_rParentNode;
+ public:
+ ConvertingSubnodeBuilder(OTreeNodeFactory & _rNodeFactory, ISubtree & _rParentNode)
+ : m_aSubnodeBuilder(_rNodeFactory)
+ , m_rParentNode(_rParentNode)
+ {
+ }
+
+ void addElements(sharable::SetNode * set) { visitElements(set); }
+ void addChildren(sharable::GroupNode * group) { visitChildren(group); }
+
+ private:
+ using SetVisitor::handle;
+ virtual bool handle(sharable::Node * node);
+ virtual bool handle(sharable::TreeFragment * tree);
+ };
+//-----------------------------------------------------------------------------
+
+ class DataTreeDefaultMerger : private NodeAction
+ {
+ public:
+ explicit
+ DataTreeDefaultMerger() {}
+
+ void mergeDefaults(sharable::TreeFragment * _aBaseAddress, INode const& _aDefaultNode);
+ private:
+ void handle(ValueNode const & _aNode);
+ void handle(ISubtree const & _aNode);
+ };
+
+//-----------------------------------------------------------------------------
+
+ class DataTreeCleanup
+ {
+ public:
+ explicit
+ DataTreeCleanup() {}
+
+ sharable::TreeFragment * destroyTree(sharable::TreeFragment * _aBaseAddress);
+ private:
+ void destroyNode(sharable::Node * _aNodeAddress);
+
+ void destroyData(sharable::TreeFragmentHeader * _pHeader);
+ void destroyData(sharable::NodeInfo * _pNodeInfo);
+
+ void destroyData(sharable::GroupNode * _pNode);
+ void destroyData(sharable::ValueNode * _pNode);
+ void destroyData(sharable::SetNode * _pNode);
+ };
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * buildTree(sharable::TreeFragment * tree)
+{
+ return CopyingDataTreeBuilder().buildTree(tree);
+}
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * buildTree(rtl::OUString const & _aTreeName, INode const& _aNode, bool _bWithDefaults)
+{
+ ConvertingDataTreeBuilder aBuilder;
+
+ sharable::TreeFragment * aResult = aBuilder.buildTree(_aTreeName, _aNode,_bWithDefaults);
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * buildElementTree(INode const& _aNode, rtl::OUString const & _aTypeName, bool _bWithDefaults)
+{
+ ConvertingDataTreeBuilder aBuilder;
+
+ sharable::TreeFragment * aResult = aBuilder.buildElement(_aNode, _aTypeName, _bWithDefaults);
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+void mergeDefaults(sharable::TreeFragment * _aBaseAddress, INode const& _aDefaultNode)
+{
+ DataTreeDefaultMerger aMergeHelper;
+
+ aMergeHelper.mergeDefaults(_aBaseAddress, _aDefaultNode);
+}
+//-----------------------------------------------------------------------------
+
+void destroyTree(sharable::TreeFragment * _aBaseAddress)
+{
+ DataTreeCleanup aCleaner;
+
+ aCleaner.destroyTree(_aBaseAddress);
+}
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<INode> convertTree(sharable::TreeFragment * tree, bool _bUseTreeName)
+{
+ ConvertingNodeBuilder aBuilder( configmgr::getDefaultTreeNodeFactory() );
+
+ return aBuilder.buildNode(tree, _bUseTreeName);
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+inline
+void TreeNodeBuilder::CollectSetElements::resetElementList()
+{
+ OSL_ENSURE(m_head == NULL, "Joining to a element list that was forgotten");
+}
+//-----------------------------------------------------------------------------
+
+inline
+sharable::TreeFragment * TreeNodeBuilder::CollectSetElements::getElementListAndClear()
+{
+ sharable::TreeFragment * aResult = m_head;
+ m_head = NULL;
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+void TreeNodeBuilder::CollectSetElements::addElement(sharable::TreeFragment * _aNewElement)
+{
+ if (sharable::TreeFragment * pNewFragment = _aNewElement)
+ {
+ pNewFragment->header.parent = 0; // data not available here
+ pNewFragment->header.next = m_head;
+
+ m_head = _aNewElement;
+ }
+ else
+ OSL_ENSURE(false, "Cannot add NULL element");
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+void TreeNodeBuilder::LinkSetNodes::linkTree(sharable::TreeFragment * tree) {
+ sharable::Node * old = m_parent;
+ m_parent = 0;
+ sal_uInt16 n = tree->header.count;
+ for (sal_uInt16 i = 0; i < n; ++i) {
+ if (visitNode(tree->nodes + i)) {
+ break;
+ }
+ }
+ m_parent = old;
+}
+
+bool TreeNodeBuilder::LinkSetNodes::handle(sharable::SetNode * node)
+{
+ OSL_ASSERT(m_parent == 0);
+ m_parent = sharable::node(node);
+ bool done = visitElements(node);
+ m_parent = 0;
+ return done;
+}
+
+bool TreeNodeBuilder::LinkSetNodes::handle(sharable::TreeFragment * tree)
+{
+ OSL_ASSERT(m_parent != 0);
+ tree->header.parent = m_parent;
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+
+inline void TreeNodeBuilder::checkOffset(sal_uInt16 _pos)
+{
+ { (void)_pos; }
+ OSL_ENSURE(_pos < m_nodes.size(), "TreeNodeBuilder: Node access past end.");
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt16 TreeNodeBuilder::addNode(rtl_uString * _aName, sal_uInt8 _aFlags, sal_uInt8 _aType)
+{
+ OSL_PRECOND(_aName, "TreeNodeBuilder: Unexpected NULL name");
+
+ // TODO: consistencý checks for flags
+ OSL_ENSURE(m_nodes.size() == m_header.count, "TreeNodeBuilder: node count mismatch");
+
+ sal_uInt16 nNewOffset = m_header.count++;
+
+ m_nodes.push_back( sharable::Node() );
+
+ OSL_ASSERT( &lastNode() == &nodeAt(nNewOffset) );
+
+ sharable::NodeInfo & rInfo = lastNode().info;
+
+ rInfo.name = _aName;
+ rInfo.flags = _aFlags;
+ rInfo.type = _aType;
+
+ OSL_ENSURE( m_parent <= nNewOffset, "ERROR - TreeNodeBuilder: invalid parent");
+ OSL_ENSURE( (nNewOffset == 0) == (nNewOffset == m_parent), "ERROR - TreeNodeBuilder: node is own parent");
+
+ rInfo.parent = nNewOffset - m_parent;
+
+ return nNewOffset;
+}
+//-----------------------------------------------------------------------------
+
+void TreeNodeBuilder::resetTreeFragment(rtl_uString * _name, sal_uInt8 _state)
+{
+ m_header.next = 0;
+ m_header.name = _name;
+
+ m_header.parent = 0;
+
+ m_header.count = 0;
+ m_header.state = _state;
+
+ m_nodes.clear();
+ m_parent = 0;
+}
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * TreeNodeBuilder::allocTreeFragment()
+{
+ OSL_ENSURE(m_nodes.size() == m_header.count, "TreeNodeBuilder: node count mismatch");
+
+ sharable::TreeFragment *pFragment = sharable::TreeFragment::allocate(m_header.count);
+ pFragment->header = m_header;
+ std::copy(m_nodes.begin(),m_nodes.end(),pFragment->nodes);
+
+ return (sharable::TreeFragment *)( pFragment );
+}
+//-----------------------------------------------------------------------------
+
+void TreeNodeBuilder::linkTreeFragment(sharable::TreeFragment * _aTreeFragment)
+{
+ LinkSetNodes().linkTree(_aTreeFragment);
+}
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * TreeNodeBuilder::createTreeFragment()
+{
+ sharable::TreeFragment * aResult = allocTreeFragment();
+
+ if (aResult != NULL)
+ {
+ linkTreeFragment(aResult);
+
+ m_nodes.clear(); // ownership of indirect data has gone ...
+ }
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt16 TreeNodeBuilder::startGroup( rtl_uString * _aName, sal_uInt8 _aFlags )
+{
+ sal_uInt16 nNewIndex = addNode(_aName,_aFlags,Type::nodetype_group);
+
+ lastNode().group.numDescendants = 0;
+
+ m_parent = nNewIndex;
+
+ return nNewIndex;
+}
+//-----------------------------------------------------------------------------
+
+void TreeNodeBuilder::endGroup( sal_uInt16 _nPos )
+{
+ // while (_nPos < m_parent) endGroup(m_parent);
+ OSL_PRECOND(_nPos == m_parent, "TreeNodeBuilder: Group being closed is not the current parent");
+
+ OSL_ENSURE(nodeAt(_nPos).isGroup(), "TreeNodeBuilder: Group being closed is not a group");
+
+ OSL_ENSURE(m_nodes.size() == m_header.count, "TreeNodeBuilder: node count mismatch");
+
+ sharable::GroupNode & rGroup = nodeAt(_nPos).group;
+
+ rGroup.numDescendants = sal_uInt16( m_nodes.size() - static_cast< ::std::size_t >(_nPos) - 1 );
+ m_parent = m_parent - rGroup.info.parent;
+}
+//-----------------------------------------------------------------------------
+
+void TreeNodeBuilder::addSet( rtl_uString * _aName, sal_uInt8 _aFlags, sal_uInt8 * _aElementType )
+{
+ addNode(_aName,_aFlags,Type::nodetype_set);
+
+ lastNode().set.elementType = _aElementType;
+ lastNode().set.elements = 0;
+}
+
+//-----------------------------------------------------------------------------
+
+void TreeNodeBuilder::addValue( rtl_uString * _aName, sal_uInt8 _aFlags,
+ sal_uInt8 _aValueType,
+ sharable::AnyData _aUserValue,
+ sharable::AnyData _aDefaultValue )
+{
+ OSL_PRECOND(_aValueType == (_aValueType & Type::mask_valuetype), "TreeNodeBuilder: invalid value type");
+
+ addNode(_aName,_aFlags,sal_uInt8(Type::nodetype_value | _aValueType));
+
+ lastNode().value.value = _aUserValue;
+ lastNode().value.defaultValue = _aDefaultValue;
+}
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * CopyingDataTreeBuilder::buildTree(sharable::TreeFragment * sourceTree)
+{
+ OSL_ENSURE(sourceTree != 0, "Trying to build a tree from NULL data");
+
+ rtl_uString * aTreeName = acquireString( sourceTree->getName());
+ this->builder().resetTreeFragment(aTreeName, sourceTree->header.state);
+
+ this->visitNode(sourceTree->getRootNode());
+
+ return this->createTree();
+}
+//-----------------------------------------------------------------------------
+
+bool CopyingDataTreeBuilder::handle(sharable::ValueNode * node)
+{
+ rtl_uString * aNodeName = acquireString( node->info.getName());
+ sal_uInt8 aFlags = node->info.flags;
+
+ sal_uInt8 aType = sal_uInt8( node->info.type & Type::mask_valuetype );
+
+ sharable::AnyData aNewValue, aNewDefault;
+ if (aFlags & Flags::valueAvailable)
+ aNewValue = sharable::allocData(aType, node->getUserValue());
+ else
+ aNewValue.data = 0;
+
+ if (aFlags & Flags::defaultAvailable)
+ aNewDefault = sharable::allocData(aType, node->getDefaultValue());
+ else
+ aNewDefault.data = 0;
+
+ this->builder().addValue(aNodeName,aFlags,aType,aNewValue,aNewDefault);
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+bool CopyingDataTreeBuilder::handle(sharable::GroupNode * node)
+{
+ rtl_uString * aNodeName = acquireString( node->info.getName());
+ sal_uInt8 aFlags = node->info.flags;
+
+ sal_uInt16 nGroupOffset = this->builder().startGroup(aNodeName,aFlags);
+ this->visitChildren(node);
+ this->builder().endGroup(nGroupOffset);
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+bool CopyingDataTreeBuilder::handle(sharable::SetNode * node)
+{
+ rtl_uString * aNodeName = acquireString( node->info.getName());
+ sal_uInt8 aFlags = node->info.flags;
+ sal_uInt8 * aTemplate = this->makeTemplateData(node->elementType);
+
+ this->builder().addSet(aNodeName,aFlags,aTemplate);
+
+ OSL_ASSERT( this->builder().lastNode().isSet() );
+ sharable::SetNode& _aNewSet = this->builder().lastNode().set;
+
+ _aNewSet.elements = ElementListBuilder().buildElementList(node);
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt8 * CopyingDataTreeBuilder::makeTemplateData(sal_uInt8 * _aSourceTemplate)
+{
+ return sharable::SetNode::copyTemplateData(_aSourceTemplate);
+}
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * CopyingDataTreeBuilder::ElementListBuilder::buildElementList(sharable::SetNode * set)
+{
+ OSL_ASSERT(set != 0);
+
+ m_aCollector.resetElementList();
+
+ this->visitElements(set);
+
+ return m_aCollector.getElementListAndClear();
+}
+//-----------------------------------------------------------------------------
+
+bool CopyingDataTreeBuilder::ElementListBuilder::handle(sharable::TreeFragment * tree)
+{
+ sharable::TreeFragment * aNewElement = CopyingDataTreeBuilder().buildTree(tree);
+
+ m_aCollector.addElement(aNewElement);
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+rtl_uString * ConvertingDataTreeBuilder::allocName(INode const & _aNode)
+{
+ rtl::OUString sNextName = _aNode.getName();
+
+ if (m_sRootName.getLength())
+ {
+ sNextName = m_sRootName;
+ m_sRootName = rtl::OUString();
+ }
+
+ return acquireString( sNextName);
+}
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * ConvertingDataTreeBuilder::buildElement(INode const& _aNode, rtl::OUString const & _aTypeName, bool _bWithDefaults)
+{
+ m_sRootName = _aTypeName;
+ m_bWithDefaults = _bWithDefaults;
+
+ rtl_uString * aTreeName = acquireString( _aNode.getName());
+ this->builder().resetTreeFragment(aTreeName, makeState(_aNode.getAttributes()));
+
+
+ this->applyToNode(_aNode);
+
+ return this->createTree();
+}
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * ConvertingDataTreeBuilder::buildTree(rtl::OUString const & _aTreeName, INode const& _aNode, bool _bWithDefaults)
+{
+ m_sRootName = rtl::OUString();
+ m_bWithDefaults = _bWithDefaults;
+
+ rtl_uString * aTreeName = acquireString( _aTreeName );
+ this->builder().resetTreeFragment(aTreeName, makeState(_aNode.getAttributes()));
+
+
+ this->applyToNode(_aNode);
+
+ return this->createTree();
+}
+//-----------------------------------------------------------------------------
+
+void ConvertingDataTreeBuilder::handle(ISubtree const & _aNode)
+{
+ rtl_uString * aNodeName = allocName( _aNode );
+ sal_uInt8 aFlags = makeFlags(_aNode.getAttributes());
+
+ if (_aNode.isSetNode())
+ {
+ sal_uInt8 * aTemplate = this->makeTemplateData(_aNode.getElementTemplateName(),
+ _aNode.getElementTemplateModule());
+
+ this->builder().addSet(aNodeName,aFlags,aTemplate);
+
+ OSL_ASSERT( this->builder().lastNode().isSet() );
+ sharable::SetNode& _aNewSet = this->builder().lastNode().set;
+
+ _aNewSet.elements = ElementListBuilder().buildElementList(_aNode, m_bWithDefaults);
+ }
+ else
+ {
+ sal_uInt16 nGroupOffset = this->builder().startGroup(aNodeName,aFlags);
+ this->applyToChildren(_aNode);
+ this->builder().endGroup(nGroupOffset);
+ }
+}
+//-----------------------------------------------------------------------------
+
+void ConvertingDataTreeBuilder::handle(ValueNode const & _aNode)
+{
+ rtl_uString * aNodeName = allocName( _aNode );
+ sal_uInt8 aFlags = makeFlags(_aNode.getAttributes());
+
+ sal_uInt8 aType = sharable::getTypeCode(_aNode.getValueType());
+
+ sharable::AnyData aNewValue; aNewValue.data = 0;
+ sharable::AnyData aNewDefault; aNewDefault.data = 0;
+
+ OSL_ASSERT( !(aFlags & (Flags::valueAvailable | Flags::defaultAvailable)) );
+
+ if (!_aNode.isDefault())
+ {
+ uno::Any aValue = _aNode.getValue();
+ if (aValue.hasValue())
+ {
+ aNewValue = sharable::allocData(aType, aValue);
+ aFlags |= Flags::valueAvailable;
+ }
+ }
+
+ if (_aNode.hasUsableDefault())
+ {
+ uno::Any aDefault = _aNode.getDefault();
+ if (aDefault.hasValue())
+ {
+ aNewDefault = sharable::allocData(aType, aDefault);
+ aFlags |= Flags::defaultAvailable;
+ }
+ }
+
+ this->builder().addValue(aNodeName,aFlags,aType,aNewValue,aNewDefault);
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt8 ConvertingDataTreeBuilder::makeState(node::Attributes const & _aAttributes)
+{
+ sal_uInt8 state;
+
+ switch (_aAttributes.state())
+ {
+ case node::isDefault: state = State::defaulted; m_bWithDefaults = true; break;
+ case node::isMerged: state = State::merged; break;
+ case node::isReplaced: state = State::replaced; m_bWithDefaults = false; break;
+ case node::isAdded: state = State::added; m_bWithDefaults = false; break;
+
+ default: OSL_ASSERT(false); state = 0; break;
+ }
+
+ if (_aAttributes.isReadonly())
+ state |= State::flag_readonly;
+ //Map mandatory and Removable
+ if (_aAttributes.isMandatory())
+ state |= State::flag_mandatory;
+
+ if (_aAttributes.isRemovable())
+ state |= State::flag_removable;
+
+ if ( m_bWithDefaults )
+ state |= State::flag_default_avail;
+
+ return state;
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt8 ConvertingDataTreeBuilder::makeFlags(node::Attributes const & _aAttributes)
+{
+ sal_uInt8 flags = 0;
+
+ if ( _aAttributes.isReadonly())
+ flags |= Flags::readonly;
+
+ if ( _aAttributes.isFinalized())
+ flags |= Flags::finalized;
+
+ if ( _aAttributes.isNullable())
+ flags |= Flags::nullable;
+
+ if ( _aAttributes.isLocalized())
+ flags |= Flags::localized;
+
+ if (_aAttributes.isDefault())
+ flags |= Flags::defaulted; // somewhat redundant with State
+
+ if (!_aAttributes.isReplacedForUser())
+ flags |= Flags::defaultable; // redundant with State (merged || defaulted)
+
+ return flags;
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt8 * ConvertingDataTreeBuilder::makeTemplateData(rtl::OUString const & _aTemplateName, rtl::OUString const & _aTemplateModule)
+{
+ return sharable::SetNode::allocTemplateData(_aTemplateName, _aTemplateModule );
+}
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * ConvertingDataTreeBuilder::ElementListBuilder::buildElementList(ISubtree const & _aSet, bool _bWithDefaults)
+{
+ OSL_PRECOND(_aSet.isSetNode(), "Node must be a set");
+
+ m_aCollector.resetElementList();
+
+ m_sTypeName = _aSet.getElementTemplateName();
+ m_bWithDefaults = _bWithDefaults;
+
+ this->applyToChildren(_aSet);
+
+ return m_aCollector.getElementListAndClear();
+}
+//-----------------------------------------------------------------------------
+
+void ConvertingDataTreeBuilder::ElementListBuilder::handleNode(INode const & _aSourceNode)
+{
+ sharable::TreeFragment * aNewElement = ConvertingDataTreeBuilder()
+ .buildElement(_aSourceNode,m_sTypeName,m_bWithDefaults);
+
+ m_aCollector.addElement(aNewElement);
+}
+//-----------------------------------------------------------------------------
+
+void ConvertingDataTreeBuilder::ElementListBuilder::handle(ValueNode const & _aSourceNode)
+{
+ handleNode(_aSourceNode);
+}
+//-----------------------------------------------------------------------------
+
+void ConvertingDataTreeBuilder::ElementListBuilder::handle(ISubtree const & _aSourceNode)
+{
+ handleNode(_aSourceNode);
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<INode> ConvertingNodeBuilder::buildNode(sharable::TreeFragment * sourceTree, bool _bUseTreeName)
+{
+ std::auto_ptr<INode> pResult = this->buildNode(sourceTree == 0 ? 0 : sourceTree->getRootNode());
+ if (pResult.get() != NULL)
+ {
+ // use the element name !
+ if (_bUseTreeName) pResult->setName( sourceTree->getName() );
+
+ // do something about attributes here ?
+ }
+ return pResult;
+}
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<INode> ConvertingNodeBuilder::buildNode(sharable::Node * sourceNode)
+{
+ OSL_ENSURE( !m_pNode.get(), "Old node tree will be dropped");
+ visitNode(sourceNode);
+ return m_pNode;
+}
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ConvertingNodeBuilder::buildNodeTree(sharable::GroupNode * groupNode) const
+{
+ std::auto_ptr<ISubtree> pResult = convertNode(groupNode);
+
+ if (pResult.get() != NULL)
+ {
+ ConvertingSubnodeBuilder aCollector(m_rNodeFactory, *pResult);
+ aCollector.addChildren(groupNode);
+ }
+
+ return pResult;
+}
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ConvertingNodeBuilder::buildNodeTree(sharable::SetNode * setNode) const
+{
+ std::auto_ptr<ISubtree> pResult = convertNode(setNode);
+
+ if (pResult.get() != NULL)
+ {
+ ConvertingSubnodeBuilder aCollector(m_rNodeFactory, *pResult);
+ aCollector.addElements(setNode);
+ }
+
+ return pResult;
+}
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ConvertingNodeBuilder::convertNode(sharable::GroupNode * groupNode) const
+{
+ return m_rNodeFactory.createGroupNode( groupNode->info.getName(),
+ convertAttributes(sharable::node(groupNode)));
+}
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ConvertingNodeBuilder::convertNode(sharable::SetNode * setNode) const
+{
+ return m_rNodeFactory.createSetNode(setNode->info.getName(),
+ setNode->getElementTemplateName(),
+ setNode->getElementTemplateModule(),
+ convertAttributes(sharable::node(setNode)));
+}
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<ValueNode> ConvertingNodeBuilder::convertNode(sharable::ValueNode * valueNode) const
+{
+ uno::Any aUserValue = valueNode->getUserValue();
+ uno::Any aDefValue = valueNode->getDefaultValue();
+
+ if (aUserValue.hasValue() || aDefValue.hasValue())
+ {
+ return m_rNodeFactory.createValueNode(valueNode->info.getName(),
+ aUserValue, aDefValue,
+ convertAttributes(sharable::node(valueNode)));
+ }
+ else
+ {
+ return m_rNodeFactory.createNullValueNode(valueNode->info.getName(),
+ valueNode->getValueType(),
+ convertAttributes(sharable::node(valueNode)));
+ }
+}
+//-----------------------------------------------------------------------------
+
+bool ConvertingNodeBuilder::handle(sharable::ValueNode * node)
+{
+ m_pNode = base_ptr(buildNodeTree(node));
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+bool ConvertingNodeBuilder::handle(sharable::GroupNode * node)
+{
+ m_pNode = base_ptr(buildNodeTree(node));
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+bool ConvertingNodeBuilder::handle(sharable::SetNode * node)
+{
+ m_pNode = base_ptr(buildNodeTree(node));
+ return true;
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+bool ConvertingSubnodeBuilder::handle(sharable::TreeFragment * tree)
+{
+ OSL_ASSERT(m_rParentNode.isSetNode());
+ m_rParentNode.addChild(m_aSubnodeBuilder.buildNode(tree, true));
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+bool ConvertingSubnodeBuilder::handle(sharable::Node * node)
+{
+ OSL_ASSERT(!m_rParentNode.isSetNode());
+ m_rParentNode.addChild(m_aSubnodeBuilder.buildNode(node));
+ return false;
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+void DataTreeDefaultMerger::mergeDefaults(sharable::TreeFragment * /*_aBaseAddress*/, INode const& /*_aDefaultNode*/)
+{
+}
+//-----------------------------------------------------------------------------
+
+void DataTreeDefaultMerger::handle(ISubtree const & /*_aNode*/)
+{
+}
+//-----------------------------------------------------------------------------
+
+void DataTreeDefaultMerger::handle(ValueNode const & /*_aNode*/)
+{
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+sharable::TreeFragment * DataTreeCleanup::destroyTree(sharable::TreeFragment * _aBaseAddress)
+{
+ sharable::TreeFragment *pData = _aBaseAddress;
+
+ sharable::TreeFragment *pNext = pData->header.next;
+
+ sal_uInt16 const nCount = pData->header.count;
+
+ destroyData( & pData->header );
+
+ for (sal_uInt16 i = 0; i< nCount; ++i)
+ {
+ destroyNode( addressOfNodeAt(_aBaseAddress,i) );
+ }
+
+ sharable::TreeFragment::free_shallow( pData );
+
+ return (sharable::TreeFragment *)( pNext );
+}
+//-----------------------------------------------------------------------------
+
+void DataTreeCleanup::destroyNode(sharable::Node * _aNodeAddress)
+{
+ sharable::Node * pNode = _aNodeAddress;
+
+ sal_uInt8 aTypeTag = pNode->info.type;
+ switch ( aTypeTag & Type::mask_nodetype )
+ {
+ case Type::nodetype_group:
+ destroyData( &pNode->group );
+ break;
+ case Type::nodetype_value:
+ destroyData( &pNode->value );
+ break;
+ case Type::nodetype_set:
+ destroyData( &pNode->set );
+ break;
+ default:
+ OSL_ENSURE(false, "Cannot destroy node: Invalid type tag in node");
+ break;
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DataTreeCleanup::destroyData(sharable::TreeFragmentHeader * _pHeader)
+{
+ // 'component' is owned elsewhere -> leave alone
+
+ rtl_uString * aName = _pHeader->name;
+
+ rtl_uString_release( aName );
+}
+//-----------------------------------------------------------------------------
+
+void DataTreeCleanup::destroyData(sharable::NodeInfo * _pNodeInfo)
+{
+ rtl_uString * aName = _pNodeInfo->name;
+
+ if (aName) rtl_uString_release( aName );
+}
+//-----------------------------------------------------------------------------
+
+void DataTreeCleanup::destroyData(sharable::SetNode * _pNode)
+{
+ sharable::TreeFragment * aElement( _pNode->elements );
+
+ sal_uInt8 * aTemplate = _pNode->elementType;;
+
+ destroyData(&_pNode->info);
+
+ while (aElement != NULL)
+ aElement = destroyTree(aElement);
+
+ sharable::SetNode::releaseTemplateData( aTemplate );
+}
+//-----------------------------------------------------------------------------
+
+void DataTreeCleanup::destroyData(sharable::GroupNode * _pNode)
+{
+ destroyData(&_pNode->info);
+ // nothing more to do
+}
+//-----------------------------------------------------------------------------
+
+void DataTreeCleanup::destroyData(sharable::ValueNode * _pNode)
+{
+ sal_uInt8 aValueType = sal_uInt8( _pNode->info.type & Type::mask_valuetype );
+ sal_uInt8 aFlags = _pNode->info.flags;
+
+ destroyData(&_pNode->info);
+
+ if (aFlags & Flags::valueAvailable)
+ freeData( aValueType, _pNode->value );
+
+ if (aFlags & Flags::defaultAvailable)
+ freeData( aValueType, _pNode->defaultValue );
+
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+ //-------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/tree/changes.cxx b/configmgr/source/tree/changes.cxx
new file mode 100644
index 000000000000..5fc98fd863c4
--- /dev/null
+++ b/configmgr/source/tree/changes.cxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: changes.cxx,v $
+ * $Revision: 1.22 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+
+#include <stdio.h>
+
+#include "change.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+
+//==========================================================================
+//= ValueChange
+//==========================================================================
+
+// works reliably only if old value is set and the value really changes
+uno::Type implGetValueType(uno::Any const & _aValue, uno::Any const & _aOldValue)
+{
+ if (_aValue.hasValue())
+ {
+ OSL_ENSURE(!_aOldValue.hasValue() || _aOldValue.getValueType() == _aValue.getValueType(),
+ "ERROR: Type mismatch in value change");
+
+ return _aValue.getValueType();
+ }
+ else
+ {
+ OSL_ENSURE(_aOldValue.hasValue(),"WARNING: Cannot determine value type of change");
+ return _aOldValue.getValueType();
+ }
+}
+// -------------------------------------------------------------------------
+static inline bool isDefaultMode(ValueChange::Mode _eMode)
+{ return (_eMode == ValueChange::setToDefault) || (_eMode == ValueChange::changeDefault); }
+// -------------------------------------------------------------------------
+static inline bool isLayerChangeMode(ValueChange::Mode _eMode)
+{ return (_eMode == ValueChange::setToDefault) || (_eMode == ValueChange::wasDefault); }
+// -----------------------------------------------------------------------------
+ValueChange::ValueChange(rtl::OUString const& _rName,
+ const node::Attributes& _rAttributes,
+ Mode _eMode,
+ uno::Any const & aNewValue, uno::Any const & aOldValue)
+ : Change(_rName, isDefaultMode(_eMode))
+ ,m_aValueType( implGetValueType(aNewValue,aOldValue) )
+ ,m_aValue(aNewValue)
+ ,m_aOldValue(aOldValue)
+ ,m_aAttributes(_rAttributes)
+ ,m_eMode(_eMode)
+{
+ m_aAttributes.markAsDefault(Change::isToDefault());
+}
+
+// -----------------------------------------------------------------------------
+void ValueChange::setNewValue(const uno::Any& _rNewVal)
+{
+ OSL_ENSURE(_rNewVal.getValueType() == m_aValueType || !_rNewVal.hasValue(),
+ "ValueChange: Type mismatch in setNewValue" );
+
+ m_aValue = _rNewVal;
+}
+
+// -----------------------------------------------------------------------------
+std::auto_ptr<Change> ValueChange::clone() const
+{
+ return std::auto_ptr<Change>(new ValueChange(*this));
+}
+
+// -----------------------------------------------------------------------------
+bool ValueChange::isChange() const // makes sense only if old value is set
+{
+ return isLayerChangeMode(m_eMode) || (m_aOldValue != m_aValue);
+}
+// -------------------------------------------------------------------------
+namespace tree_changes_internal {
+ inline void doAdjust(uno::Any& aActual, uno::Any const& aTarget)
+ {
+ // If set - it should already match
+ OSL_ASSERT(!aActual.hasValue() || aTarget == aActual);
+ aActual = aTarget;
+ }
+}
+
+// -------------------------------------------------------------------------
+void ValueChange::applyChangeNoRecover(ValueNode& aValue) const
+{
+ switch (getMode())
+ {
+ case wasDefault:
+ OSL_ASSERT(aValue.isDefault());
+ case changeValue:
+ aValue.setValue(getNewValue());
+ break;
+
+ case setToDefault:
+ aValue.setDefault();
+ break;
+
+ case changeDefault:
+ aValue.changeDefault(getNewValue());
+ break;
+
+ default:
+ OSL_ENSURE(0, "Unknown mode found for ValueChange");
+ break;
+ }
+}
+
+//==========================================================================
+//= AddNode
+//==========================================================================
+AddNode::AddNode(rtl::Reference< data::TreeSegment > const & _aAddedTree, rtl::OUString const& _rName, bool _bToDefault)
+ :Change(_rName,_bToDefault)
+ ,m_aOwnNewNode(_aAddedTree)
+ ,m_aOwnOldNode()
+ ,m_aInsertedTree(NULL)
+ ,m_bReplacing(false)
+{
+}
+
+//--------------------------------------------------------------------------
+AddNode::~AddNode()
+{
+}
+
+// -----------------------------------------------------------------------------
+AddNode::AddNode(const AddNode& _aObj)
+: Change(_aObj)
+, m_aOwnNewNode(data::TreeSegment::create(_aObj.m_aOwnNewNode))
+, m_aOwnOldNode(data::TreeSegment::create(_aObj.m_aOwnOldNode))
+, m_aInsertedTree(_aObj.m_aInsertedTree)
+, m_bReplacing(_aObj.m_bReplacing)
+{
+}
+
+// -----------------------------------------------------------------------------
+std::auto_ptr<Change> AddNode::clone() const
+{
+ return std::auto_ptr<Change>(new AddNode(*this));
+}
+
+//--------------------------------------------------------------------------
+void AddNode::setInsertedAddress(sharable::TreeFragment * const & _aInsertedTree)
+{
+ OSL_ENSURE( m_aInsertedTree == NULL, "AddNode already was applied - inserted a second time ?");
+ m_aInsertedTree = _aInsertedTree;
+}
+//--------------------------------------------------------------------------
+
+#if 0
+void AddNode::expectReplacedNode(INode const* pOldNode)
+{
+ if (pOldNode != m_aOwnOldNode.getRoot())
+ {
+ OSL_ENSURE(!m_aOwnOldNode.is(), "This AddNode already owns a replaced Node - throwing that away");
+ m_aOwnOldNode.clear();
+ }
+ m_pOldNode = pOldNode;
+}
+#endif
+//--------------------------------------------------------------------------
+
+void AddNode::takeReplacedTree(rtl::Reference< data::TreeSegment > const & _aReplacedTree)
+{
+ m_aOwnOldNode = _aReplacedTree;
+
+ if (m_aOwnOldNode.is()) m_bReplacing = true;
+}
+
+
+//==========================================================================
+//= RemoveNode
+//==========================================================================
+RemoveNode::RemoveNode(rtl::OUString const& _rName, bool _bToDefault)
+ :Change(_rName,_bToDefault)
+ ,m_aOwnOldNode()
+{
+}
+
+//--------------------------------------------------------------------------
+RemoveNode::~RemoveNode()
+{
+}
+// -----------------------------------------------------------------------------
+RemoveNode::RemoveNode(const RemoveNode& _aObj)
+: Change(_aObj)
+, m_aOwnOldNode(data::TreeSegment::create(_aObj.m_aOwnOldNode))
+{
+}
+
+// -----------------------------------------------------------------------------
+std::auto_ptr<Change> RemoveNode::clone() const
+{
+ return std::auto_ptr<Change>(new RemoveNode(*this));
+}
+//--------------------------------------------------------------------------
+#if 0
+void RemoveNode::expectRemovedNode(INode const* pOldNode)
+{
+ if (pOldNode != m_aOwnOldNode.getRoot())
+ {
+ OSL_ENSURE(!m_aOwnOldNode.is(), "This RemoveNode already owns a Node - throwing that away");
+ m_aOwnOldNode.clear();
+ }
+ m_pOldNode = pOldNode;
+}
+#endif
+//--------------------------------------------------------------------------
+
+void RemoveNode::takeRemovedTree(rtl::Reference< data::TreeSegment > const & _aRemovedTree)
+{
+ m_aOwnOldNode = _aRemovedTree;
+}
+
+//--------------------------------------------------------------------------
+} // namespace configmgr
+
diff --git a/configmgr/source/tree/cmtree.cxx b/configmgr/source/tree/cmtree.cxx
new file mode 100644
index 000000000000..674ddd4e4460
--- /dev/null
+++ b/configmgr/source/tree/cmtree.cxx
@@ -0,0 +1,381 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cmtree.cxx,v $
+ * $Revision: 1.41 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "subtree.hxx"
+#include "change.hxx"
+#include "treechangelist.hxx"
+
+//#include "treeactions.hxx"
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+
+#ifndef INCLUDED_DEQUE
+#include <deque>
+#define INCLUDED_DEQUE
+#endif
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+#ifndef INCLUDED_EXCEPTION
+#include <exception>
+#define INCLUDED_EXCEPTION
+#endif
+#ifndef INCLUDED_SET
+#include <set>
+#define INCLUDED_SET
+#endif
+#include <algorithm>
+
+namespace configmgr
+{
+
+// ------------------------ ChildListSet implementations ------------------------
+ ChildListSet::ChildListSet(ChildListSet const& aSet, treeop::DeepChildCopy)
+ : m_aChildList(aSet.m_aChildList.size())
+ {
+ for (size_t i = 0; i < aSet.m_aChildList.size(); i++)
+ {
+ m_aChildList[i] = aSet.m_aChildList[i]->clone().release();
+ }
+ }
+ ChildListSet::~ChildListSet()
+ {
+ for (size_t i = 0; i < m_aChildList.size(); i++)
+ delete m_aChildList[i];
+ }
+
+ struct ltNode
+ {
+ ltNode() {}
+
+ bool operator()(const configmgr::INode* n1, const configmgr::INode* n2) const
+ {
+ return n1->getName().compareTo(n2->getName()) < 0;
+ }
+ };
+
+ std::vector< INode* >::iterator ChildListSet::find(INode *pNode) const
+ {
+ std::vector< INode* > &rList = const_cast<std::vector< INode* > &>(m_aChildList);
+ std::pair<std::vector< INode* >::iterator, std::vector< INode* >::iterator> aRange;
+ ltNode aCompare;
+ aRange = std::equal_range(rList.begin(), rList.end(), pNode, aCompare);
+ if (aRange.second - aRange.first == 0)
+ return rList.end();
+ else
+ return aRange.first;
+ }
+
+ // Keep the list sorted ...
+ std::pair<std::vector< INode* >::iterator, bool> ChildListSet::insert(INode *pNode)
+ {
+ // Inserted records are (mostly) already in order
+ if (m_aChildList.size() > 0)
+ {
+ sal_Int32 nCmp = pNode->getName().compareTo(
+ m_aChildList.back()->getName());
+ if (nCmp == 0)
+ {
+ return std::pair<std::vector< INode* >::iterator, bool>(m_aChildList.end(), false);
+ }
+ else if (nCmp < 0)
+ {
+ std::vector< INode* >::iterator aIns;
+ ltNode aCompare;
+ aIns = std::lower_bound(m_aChildList.begin(), m_aChildList.end(), pNode, aCompare);
+ if (aIns != m_aChildList.end() && pNode->getName().compareTo((*aIns)->getName()) == 0)
+ return std::pair<std::vector< INode* >::iterator, bool>(m_aChildList.end(), false);
+ return std::pair<std::vector< INode* >::iterator, bool>(m_aChildList.insert(aIns, pNode), true);
+ }
+ }
+ // simple append - the common case.
+ return std::pair<std::vector< INode* >::iterator, bool>(m_aChildList.insert(m_aChildList.end(), pNode), true);
+ }
+
+ INode *ChildListSet::erase(INode *pNode)
+ {
+ std::vector< INode* >::iterator aIter = find(pNode);
+
+ if (aIter != m_aChildList.end())
+ {
+ INode *pCopy = *aIter;
+ m_aChildList.erase(aIter);
+ return pCopy;
+ }
+ else
+ return NULL;
+ }
+
+// ---------------------------- Node implementation ----------------------------
+
+ INode::INode(rtl::OUString const& aName, node::Attributes _aAttr)
+ :m_aName(aName)
+ ,m_aAttributes(_aAttr){}
+ // CopyCTor will be create automatically
+
+ INode::~INode() {}
+
+ ISubtree* INode::asISubtree(){return NULL;}
+ ISubtree const* INode::asISubtree() const {return NULL;}
+ ValueNode* INode::asValueNode() {return NULL;}
+ ValueNode const* INode::asValueNode() const {return NULL;}
+
+ void INode::modifyState(node::State _eNewState)
+ {
+ m_aAttributes.setState(_eNewState);
+ }
+
+ void INode::modifyAccess(node::Access _aAccessLevel)
+ {
+ OSL_ENSURE( node::accessWritable <= _aAccessLevel && _aAccessLevel <= node::accessReadonly,"Invalid access level for Node");
+
+ m_aAttributes.setAccess(_aAccessLevel);
+ }
+
+ void INode::markMandatory()
+ {
+ m_aAttributes.markMandatory();
+ }
+
+ void INode::markRemovable()
+ {
+ m_aAttributes.markRemovable();
+ }
+
+ void INode::promoteAccessToDefault()
+ {
+ if (m_aAttributes.isFinalized())
+ m_aAttributes.setAccess(node::accessReadonly);
+
+ if ( m_aAttributes.isMandatory())
+ m_aAttributes.setRemovability(false,false);
+ }
+
+// ------------------------- SearchNode implementation -------------------------
+ SearchNode::SearchNode(rtl::OUString const& aName)
+ :INode(aName, node::Attributes()){}
+
+ std::auto_ptr<INode> SearchNode::clone() const {return std::auto_ptr<INode>(new SearchNode(*this));}
+
+ SearchNode::~SearchNode(){}
+
+ //==========================================================================
+ //= OPropagateLevels
+ //==========================================================================
+ /** fills a subtree with the correct level informations
+ */
+ struct OPropagateLevels : public NodeModification
+ {
+ public:
+ OPropagateLevels(sal_Int16 _nParentLevel, sal_Int16 _nParentDefaultLevel)
+ : m_nLevel ( childLevel(_nParentLevel) )
+ , m_nDefaultLevel ( childLevel(_nParentDefaultLevel) )
+ {
+ }
+ virtual void handle(ValueNode&) { /* not interested in value nodes */ }
+ virtual void handle(ISubtree& _rSubtree)
+ {
+ _rSubtree.setLevels(m_nLevel, m_nDefaultLevel);
+ }
+
+ static sal_Int16 childLevel(sal_Int16 _nLevel)
+ {
+ OSL_ASSERT(0 > treeop::ALL_LEVELS);
+ return (_nLevel > 0) ? _nLevel-1 : _nLevel;
+ }
+ protected:
+ sal_Int16 m_nLevel;
+ sal_Int16 m_nDefaultLevel;
+ };
+
+
+// -------------------------- ISubtree implementation --------------------------
+ ISubtree* ISubtree::asISubtree() {return this;}
+ ISubtree const* ISubtree::asISubtree() const {return this;}
+
+ //--------------------------------------------------------------------------
+ static inline bool adjustLevel(sal_Int16& _rLevel, sal_Int16 _nNewLevel)
+ {
+ if (_rLevel == treeop::ALL_LEVELS) return false;
+ if (_nNewLevel <= _rLevel &&
+ _nNewLevel != treeop::ALL_LEVELS) return false;
+
+ _rLevel = _nNewLevel;
+ return true;
+ }
+
+ //--------------------------------------------------------------------------
+ void ISubtree::setLevels(sal_Int16 _nLevel, sal_Int16 _nDefaultLevels)
+ {
+ bool bActive = false;
+
+ if (_nLevel && adjustLevel(m_nLevel, _nLevel))
+ bActive = true;
+
+ if (_nDefaultLevels && adjustLevel(m_nDefaultLevels, _nDefaultLevels))
+ bActive = true;
+
+ // forward the level numbers to any child subtrees we have
+ if (bActive)
+ {
+ OPropagateLevels aPropagate(_nLevel,_nDefaultLevels);
+ aPropagate.applyToChildren(*this);
+ }
+ }
+
+// --------------------------- Subtree implementation ---------------------------
+ std::auto_ptr<INode> Subtree::clone() const
+ {
+ return std::auto_ptr<INode>(new Subtree(*this, treeop::DeepChildCopy()));
+ }
+
+ INode* Subtree::doGetChild(rtl::OUString const& aName) const
+ {
+ SearchNode searchObj(aName);
+
+ std::vector< INode* >::iterator aIter = m_aChildren.find(&searchObj);
+ return aIter != m_aChildren.end() ? *aIter : NULL;
+ }
+
+ INode* Subtree::addChild(std::auto_ptr<INode> aNode) // takes ownership
+ {
+ rtl::OUString aName = aNode->getName();
+ std::pair<std::vector< INode* >::iterator, bool> aInserted =
+ m_aChildren.insert(aNode.get());
+ if (aInserted.second)
+ aNode.release();
+ return *aInserted.first;
+ }
+
+ ::std::auto_ptr<INode> Subtree::removeChild(rtl::OUString const& aName)
+ {
+ SearchNode searchObj(aName);
+ return ::std::auto_ptr<INode>(m_aChildren.erase(&searchObj));
+ }
+// // -------------------------- ValueNode implementation --------------------------
+
+ void Subtree::forEachChild(NodeAction& anAction) const
+ {
+ for(std::vector< INode* >::const_iterator it = m_aChildren.begin();
+ it != m_aChildren.end();
+ ++it)
+ (**it).dispatch(anAction);
+ }
+
+ void Subtree::forEachChild(NodeModification& anAction)
+ {
+ std::vector< INode* >::iterator it = m_aChildren.begin();
+ while( it != m_aChildren.end() )
+ {
+ // modification-safe iteration
+ (**it++).dispatch(anAction);
+ }
+ }
+
+// // -------------------------- ValueNode implementation --------------------------
+ bool ValueNode::setValueType(uno::Type const& _aType)
+ {
+ if (_aType == this->getValueType()) return true;
+
+ if (!this->isNull()) return false;
+
+ uno::TypeClass eTC = this->getValueType().getTypeClass();
+ if (eTC != uno::TypeClass_VOID && eTC != uno::TypeClass_ANY)
+ return false;
+
+ m_aValuePair = AnyPair(_aType);
+
+ OSL_ASSERT(_aType == this->getValueType());
+
+ return true;
+ }
+ bool ValueNode::setValue(com::sun::star::uno::Any const& _aValue)
+ {
+ sal_Bool bRet = m_aValuePair.setFirst(_aValue);
+ if (bRet) this->markAsDefault(false);
+ return !! bRet;
+ }
+
+ bool ValueNode::changeDefault(com::sun::star::uno::Any const& _aValue)
+ {
+ return !! m_aValuePair.setSecond(_aValue);
+ }
+
+ void ValueNode::setDefault()
+ {
+ OSL_PRECOND( hasUsableDefault(), "No default value to set for value node");
+ m_aValuePair.clear( selectValue() );
+ this->markAsDefault();
+ OSL_POSTCOND( isDefault(), "Could not set value node to default");
+ }
+
+ void ValueNode::promoteToDefault()
+ {
+ if (!isDefault())
+ {
+ if (m_aValuePair.hasFirst())
+ {
+ OSL_VERIFY( m_aValuePair.setSecond(m_aValuePair.getFirst()) );
+ m_aValuePair.clear( selectValue() );
+ }
+ else
+ {
+ m_aValuePair.clear( selectDeflt() );
+ OSL_ASSERT( m_aValuePair.isNull() );
+ }
+
+ this->markAsDefault();
+
+ OSL_ENSURE( !m_aValuePair.hasFirst(), "Leaving orphaned value in after promoting to default");
+ }
+ else
+ OSL_ENSURE( !m_aValuePair.hasFirst(), "Orphaned value in default node won't be promoted");
+
+ OSL_POSTCOND( isDefault(), "Could not promote value node to default");
+ }
+
+ std::auto_ptr<INode> ValueNode::clone() const
+ {
+ return std::auto_ptr<INode>(new ValueNode(*this));
+ }
+
+ ValueNode* ValueNode::asValueNode() {return this;}
+ ValueNode const* ValueNode::asValueNode() const {return this;}
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/tree/cmtreemodel.cxx b/configmgr/source/tree/cmtreemodel.cxx
new file mode 100644
index 000000000000..24033440f065
--- /dev/null
+++ b/configmgr/source/tree/cmtreemodel.cxx
@@ -0,0 +1,374 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cmtreemodel.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "valuenode.hxx"
+#include "change.hxx"
+#include "configexcept.hxx"
+#include "strdecl.hxx"
+#include <osl/diagnose.h>
+
+#ifndef INCLUDED_ALGORITHM
+#define INCLUDED_ALGORITHM
+#include <algorithm>
+#endif
+
+//..........................................................................
+namespace configmgr
+{
+//==========================================================================
+
+bool isLocalizedValueSet(ISubtree const& _aSubtree)
+{
+ if ( !_aSubtree.isSetNode()) return false;
+ if ( !_aSubtree.isLocalized()) return false;
+ if ( !_aSubtree.getElementTemplateModule().equals(TEMPLATE_MODULE_LOCALIZED_VALUE) ) return false;
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool isLocalizedValueSet(SubtreeChange const& _aSubtree)
+{
+ if ( !_aSubtree.isSetNodeChange()) return false;
+ if ( !_aSubtree.isLocalizedContainer()) return false;
+ if ( !_aSubtree.getElementTemplateModule().equals(TEMPLATE_MODULE_LOCALIZED_VALUE) ) return false;
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+bool isValueSet(SubtreeChange const& _aSubtree)
+{
+ if ( !_aSubtree.isSetNodeChange()) return false;
+ if ( !_aSubtree.getElementTemplateModule().equals(TEMPLATE_MODULE_NATIVE_VALUE) ) return false;
+ return true;
+}
+//==========================================================================
+
+//==========================================================================
+//= Change
+//==========================================================================
+void Change::swap(Change& aOther)
+{
+ std::swap(m_aName, aOther.m_aName);
+ std::swap(m_bIsToDefault, aOther.m_bIsToDefault);
+}
+
+//==========================================================================
+//= SubtreeChange
+//==========================================================================
+//--------------------------------------------------------------------------
+void SubtreeChange::swap(SubtreeChange& aOther)
+{
+ Change::swap(aOther);
+ m_aChanges.swap(aOther.m_aChanges);
+ std::swap(m_sTemplateName, aOther.m_sTemplateName);
+ std::swap(m_sTemplateModule, aOther.m_sTemplateModule);
+ std::swap(m_aAttributes, aOther.m_aAttributes);
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::~SubtreeChange()
+{
+ for(Children::iterator aIter = m_aChanges.begin();
+ aIter != m_aChanges.end();
+ ++aIter)
+ {
+ // Change* pChange = aIter->second;
+ delete aIter->second;
+ }
+}
+
+// -----------------------------------------------------------------------------
+SubtreeChange::SubtreeChange(const SubtreeChange& _aObj, treeop::DeepChildCopy)
+ :Change(_aObj),
+ m_sTemplateName(_aObj.m_sTemplateName),
+ m_sTemplateModule(_aObj.m_sTemplateModule),
+ m_aAttributes(_aObj.m_aAttributes)
+{
+ for(Children::const_iterator aIter = _aObj.m_aChanges.begin();
+ aIter != _aObj.m_aChanges.end();
+ ++aIter)
+ {
+ OSL_ASSERT(aIter->second);
+ Children::value_type aCopy(aIter->first, aIter->second->clone().release());
+ m_aChanges.insert(m_aChanges.end(), aCopy);
+ }
+}
+
+// -----------------------------------------------------------------------------
+std::auto_ptr<Change> SubtreeChange::clone() const
+{
+ return std::auto_ptr<Change>(new SubtreeChange(*this, treeop::DeepChildCopy()));
+}
+//--------------------------------------------------------------------------
+void SubtreeChange::addChange(std::auto_ptr<Change> aChange)
+{
+ rtl::OUString aNodeName(aChange->getNodeName());
+ m_aChanges.find(aNodeName);
+ OSL_ENSURE(m_aChanges.end() == m_aChanges.find(aNodeName),
+ "SubtreeChange::addChange : overwriting an existent change !");
+ delete m_aChanges[aNodeName];
+ m_aChanges[aNodeName] = aChange.release();
+}
+
+//--------------------------------------------------------------------------
+::std::auto_ptr<Change> SubtreeChange::removeChange(rtl::OUString const& _rName)
+{
+ Children::iterator aIter = m_aChanges.find(_rName);
+
+ ::std::auto_ptr<Change> aReturn;
+ if (m_aChanges.end() != aIter)
+ {
+ aReturn = ::std::auto_ptr<Change>(aIter->second);
+ m_aChanges.erase(aIter);
+ }
+ return aReturn;
+}
+
+//--------------------------------------------------------------------------
+Change* SubtreeChange::getChange(rtl::OUString const& _rName)
+{
+ return doGetChild(_rName);
+}
+
+//--------------------------------------------------------------------------
+Change const* SubtreeChange::getChange(rtl::OUString const& _rName) const
+{
+ return doGetChild(_rName);
+}
+
+//--------------------------------------------------------------------------
+void SubtreeChange::dispatch(ChangeTreeAction& _anAction) const
+{
+ _anAction.handle(*this);
+}
+
+//--------------------------------------------------------------------------
+void SubtreeChange::dispatch(ChangeTreeModification& _anAction)
+{
+ _anAction.handle(*this);
+}
+
+//--------------------------------------------------------------------------
+void SubtreeChange::forEachChange(ChangeTreeAction& _anAction) const
+{
+ ::std::map< ::rtl::OUString,Change* >::const_iterator aIter = m_aChanges.begin();
+ while (aIter != m_aChanges.end())
+ {
+ (aIter++)->second->dispatch(_anAction);
+ }
+}
+
+//--------------------------------------------------------------------------
+void SubtreeChange::forEachChange(ChangeTreeModification& _anAction)
+{
+ ::std::map< ::rtl::OUString,Change* >::const_iterator aIter = m_aChanges.begin();
+ while (aIter != m_aChanges.end())
+ {
+ (aIter++)->second->dispatch(_anAction);
+ }
+}
+
+//--------------------------------------------------------------------------
+Change* SubtreeChange::doGetChild(rtl::OUString const& _rName) const
+{
+ Children::const_iterator aIter = m_aChanges.find(_rName);
+ return (aIter != m_aChanges.end()) ? aIter->second : NULL;
+}
+
+//--------------------------------------------------------------------------
+uno::Sequence< rtl::OUString > SubtreeChange::elementNames() const
+{
+ uno::Sequence< rtl::OUString > aReturn(size());
+ rtl::OUString* pReturn = aReturn.getArray();
+
+ for ( Children::const_iterator aCollector = m_aChanges.begin();
+ aCollector != m_aChanges.end();
+ ++aCollector, ++pReturn
+ )
+ {
+ *pReturn = aCollector->first;
+ }
+
+ return aReturn;
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::MutatingChildIterator SubtreeChange::begin_changes() throw()
+{
+ return MutatingChildIterator(m_aChanges.begin());
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::MutatingChildIterator SubtreeChange::end_changes() throw()
+{
+ return MutatingChildIterator(m_aChanges.end());
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::ChildIterator SubtreeChange::begin() const throw()
+{
+ return ChildIterator(this);
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::ChildIterator SubtreeChange::end() const throw()
+{
+ return ChildIterator(this, ChildIterator::EndPos());
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::ChildIterator::ChildIterator(const SubtreeChange* _pTree)
+ :m_aNames(_pTree->elementNames())
+ ,m_pTree(_pTree)
+ ,m_nPos(0)
+{
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::ChildIterator::ChildIterator(const SubtreeChange* _pTree, struct EndPos)
+ :m_aNames(_pTree->elementNames())
+ ,m_pTree(_pTree)
+ ,m_nPos(_pTree->size())
+{
+}
+
+//--------------------------------------------------------------------------
+Change const & SubtreeChange::ChildIterator::operator*() const
+{
+ OSL_ENSURE(isValid(), "SubtreeChange::ChildIterator::operator* : invalid iterator !");
+
+ if (!isValid())
+ throw configuration::Exception("INTERNAL ERROR: Invalid SubtreeChange::ChildIterator dereferenced");
+
+ return *m_pTree->getChange(m_aNames[m_nPos]);
+}
+
+//--------------------------------------------------------------------------
+Change const * SubtreeChange::ChildIterator::operator->() const
+{
+ if (isValid())
+ return m_pTree->getChange(m_aNames[m_nPos]);
+ OSL_ENSURE(sal_False, "SubtreeChange::ChildIterator::operator-> : invalid iterator !");
+ return NULL;
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::ChildIterator& SubtreeChange::ChildIterator::operator++()
+{
+ OSL_ENSURE(m_nPos < m_aNames.getLength(), "SubtreeChange::ChildIterator : can't increment the end iterator !");
+ if (m_nPos < m_aNames.getLength())
+ ++m_nPos;
+ return *this;
+}
+
+//--------------------------------------------------------------------------
+SubtreeChange::ChildIterator& SubtreeChange::ChildIterator::operator--()
+{
+ OSL_ENSURE(m_nPos > 0, "SubtreeChange::ChildIterator : can't decrement the begin iterator !");
+ if (m_nPos > 0)
+ --m_nPos;
+ return *this;
+}
+
+//--------------------------------------------------------------------------
+bool operator==(SubtreeChange::ChildIterator const& lhs, SubtreeChange::ChildIterator const& rhs)
+{
+ return (lhs.m_pTree == rhs.m_pTree) && (lhs.m_nPos == rhs.m_nPos);
+}
+
+//==========================================================================
+//= SubtreeChangeReferrer
+//==========================================================================
+//--------------------------------------------------------------------------
+SubtreeChangeReferrer::SubtreeChangeReferrer(const SubtreeChange& _rSource)
+ :SubtreeChange(_rSource, treeop::NoChildCopy())
+{
+ ChildIterator aSourceChildren = _rSource.begin();
+ while (aSourceChildren != _rSource.end())
+ {
+ const Change* pChange = &*aSourceChildren;
+ OSL_ENSURE(pChange, "SubtreeChangeReferrer::SubtreeChangeReferrer : invalid change !");
+ if (dynamic_cast< ValueChange const * >(pChange) != 0 ||
+ dynamic_cast< RemoveNode const * >(pChange) != 0 ||
+ dynamic_cast< AddNode const * >(pChange) != 0)
+ SubtreeChange::addChange(::std::auto_ptr<Change>(const_cast<Change*>(pChange)));
+ else if (dynamic_cast< SubtreeChange const * >(pChange) != 0 ||
+ dynamic_cast< SubtreeChangeReferrer const * >(pChange) != 0)
+ {
+ SubtreeChange::addChange(::std::auto_ptr<Change>(new SubtreeChangeReferrer(*static_cast<const SubtreeChange*>(pChange))));
+ }
+ else
+ OSL_ENSURE(sal_False, "SubtreeChangeReferrer::SubtreeChangeReferrer : unknown changes type !");
+
+ ++aSourceChildren;
+ }
+}
+
+//--------------------------------------------------------------------------
+SubtreeChangeReferrer::~SubtreeChangeReferrer()
+{
+ for ( Children::iterator aChildren = m_aChanges.begin();
+ aChildren != m_aChanges.end();
+
+ )
+ {
+ const Change* pChange = aChildren->second;
+ Children::iterator aCurrent = aChildren++;
+
+ if (dynamic_cast< ValueChange const * >(pChange) != 0 ||
+ dynamic_cast< RemoveNode const * >(pChange) != 0 ||
+ dynamic_cast< AddNode const * >(pChange) != 0)
+ {
+ // we just hold references to the non-SubtreeChange-objects, so don't delete them
+ m_aChanges.erase(aCurrent);
+ }
+ else if (dynamic_cast< SubtreeChange const * >(pChange) != 0 ||
+ dynamic_cast< SubtreeChangeReferrer const * >(pChange) != 0)
+ {
+ // nothing to do
+ }
+ else
+ OSL_ENSURE(sal_False, "SubtreeChangeReferrer::~SubtreeChangeReferrer : unknown changes type !");
+ }
+
+ // the base class will remove the remaining SubtreeChanges, which are SubtreeChangeReferrer's in real
+}
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+
diff --git a/configmgr/source/tree/localizedtreeactions.cxx b/configmgr/source/tree/localizedtreeactions.cxx
new file mode 100644
index 000000000000..8cd40c4da79f
--- /dev/null
+++ b/configmgr/source/tree/localizedtreeactions.cxx
@@ -0,0 +1,543 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: localizedtreeactions.cxx,v $
+ * $Revision: 1.19 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "localizedtreeactions.hxx"
+#include "treeactions.hxx"
+#include "builddata.hxx"
+#include "subtree.hxx"
+#include "matchlocale.hxx"
+#include "typeconverter.hxx"
+#include "change.hxx"
+#include "treechangefactory.hxx"
+#include "treenodefactory.hxx"
+#include "strdecl.hxx"
+#include <osl/diagnose.h>
+
+
+//..........................................................................
+namespace configmgr
+{
+
+//--------------------------------------------------------------------------
+namespace
+{
+//--------------------------------------------------------------------------
+ //==========================================================================
+ //= OCloneForLocale
+ //==========================================================================
+ //= clones a subtree , in the process selecting only the best match locale
+ //= from the set representation of localized values
+ //==========================================================================
+ class OCloneForLocale : public NodeAction
+ {
+ rtl::OUString m_sTargetLocale;
+ std::auto_ptr<INode> m_pClone;
+ public:
+ OCloneForLocale(rtl::OUString const& aLocale) : m_sTargetLocale(aLocale) {}
+ std::auto_ptr<INode> getResult() { return m_pClone; }
+
+ private:
+ void handle(ValueNode const& _aValue);
+ void handle(ISubtree const& _aSubtree);
+ };
+//--------------------------------------------------------------------------
+ struct OCloneChildrenForLocale : NodeAction
+ {
+ ISubtree& m_rParent;
+ localehelper::FindBestLocale& m_rLocaleMatcher;
+ public:
+ OCloneChildrenForLocale(ISubtree& _rParent, localehelper::FindBestLocale& _rLocaleMatcher)
+ : m_rParent(_rParent)
+ , m_rLocaleMatcher(_rLocaleMatcher)
+ {}
+
+ virtual void handle(ValueNode const& _aValue);
+ virtual void handle(ISubtree const& _aSubtree);
+ };
+
+//--------------------------------------------------------------------------
+ struct OSelectForLocale : NodeAction
+ {
+ ValueNode const* m_pFound;
+ localehelper::FindBestLocale& m_rLocaleMatcher;
+ public:
+ OSelectForLocale(localehelper::FindBestLocale& _rLocaleMatcher)
+ : m_pFound(NULL)
+ , m_rLocaleMatcher(_rLocaleMatcher)
+ {}
+
+
+ bool hasResult() const
+ { return m_pFound != NULL; }
+
+ ValueNode const* getResult() const
+ { return m_pFound; }
+
+ private:
+ virtual void handle(ValueNode const& _aValue);
+ virtual void handle(ISubtree const& _aSubtree);
+
+ void maybeSelect(ValueNode const& _aNode);
+ };
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+ void OSelectForLocale::handle(ValueNode const& _aValue)
+ {
+ maybeSelect(_aValue);
+ }
+//--------------------------------------------------------------------------
+ void OSelectForLocale::handle(ISubtree const& /*_aSubtree*/)
+ {
+ OSL_ENSURE(false, "INTERNAL ERROR: Inconsistent data: Found a Subtree in a set of localized values");
+ }
+//--------------------------------------------------------------------------
+ void OSelectForLocale::maybeSelect(ValueNode const& _aNode)
+ {
+ if (m_rLocaleMatcher.accept( localehelper::makeLocale(_aNode.getName()) ) )
+ m_pFound = &_aNode;
+
+ else
+ OSL_ENSURE(m_pFound, "WARNING: Node Locale wasn't accepted, but no node had been found before");
+ }
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+ std::auto_ptr< INode > implReduceLocalizedSet(ISubtree const& _aSubtree, localehelper::FindBestLocale& _rLocaleMatcher)
+ {
+ // -- find the best-match locale -----------------------------
+ _rLocaleMatcher.reset();
+
+ OSelectForLocale aSelector(_rLocaleMatcher);
+
+ aSelector.applyToChildren(_aSubtree);
+
+ std::auto_ptr< INode > pResult;
+
+ // -- look for a non-NULL value -----------------------------
+ uno::Type aValueType;
+ if (aSelector.hasResult())
+ {
+ ValueNode const& rSelected = *aSelector.getResult();
+
+ aValueType = rSelected.getValueType();
+
+ if (!rSelected.isNull()) // values are present - clone it from the values
+ {
+ pResult.reset ( new ValueNode( _aSubtree.getName(),
+ rSelected.getValue(), rSelected.getDefault(),
+ _aSubtree.getAttributes()
+ ) );
+
+ }
+ }
+ else // no entry - exract the type to be used from the template name
+ aValueType = parseTemplateName(_aSubtree.getElementTemplateName());
+
+ // -- create NULL value, if none was found -----------------------------
+ // create a NULL of the found type
+ if (pResult.get() == NULL)
+ {
+ pResult.reset( new ValueNode( _aSubtree.getName(),
+ aValueType,
+ _aSubtree.getAttributes()
+ ) );
+ }
+
+ // -- -----------------------------
+ OSL_ENSURE( aValueType != uno::Type(), "VOID result type found");
+ OSL_ENSURE( aValueType == parseTemplateName(_aSubtree.getElementTemplateName()),
+ "ERROR: Found Value Type doesn't match encoded value type in pseudo template name");
+ OSL_POSTCOND( static_cast<ValueNode&>(*pResult).getValueType() == aValueType,
+ "ERROR: Resulting Value Type doesn't match original value type" );
+
+ return pResult;
+ }
+//--------------------------------------------------------------------------
+ std::auto_ptr< INode > implCloneForLocale(ISubtree const& _aSubtree, localehelper::FindBestLocale& _rLocaleMatcher)
+ {
+ std::auto_ptr< INode > pClone;
+
+ if (isLocalizedValueSet(_aSubtree))
+ {
+ pClone = implReduceLocalizedSet(_aSubtree, _rLocaleMatcher);
+ }
+ else
+ {
+ // ISubtree should get a clone(NoChildCopy) member ...
+ std::auto_ptr< Subtree > pCloneTree( new Subtree(_aSubtree, treeop::NoChildCopy()) );
+
+ OCloneChildrenForLocale aSubCloner(*pCloneTree,_rLocaleMatcher);
+
+ aSubCloner.applyToChildren(_aSubtree);
+
+ pClone.reset( pCloneTree.release() );
+ }
+
+ return pClone;
+ }
+//--------------------------------------------------------------------------
+//--- OCloneChildrenForLocale:-----------------------------------------------------------------------
+
+ void OCloneChildrenForLocale::handle(ValueNode const& _aValue)
+ {
+ // just a single value - nothing to do
+ std::auto_ptr< INode > pClone( _aValue.clone() );
+
+ m_rParent.addChild(pClone);
+
+ }
+//--------------------------------------------------------------------------
+ void OCloneChildrenForLocale::handle(ISubtree const& _aSubtree)
+ {
+ std::auto_ptr< INode > pClone = implCloneForLocale(_aSubtree,m_rLocaleMatcher);
+
+ m_rParent.addChild(pClone);
+ }
+
+ //--------------------------------------------------------------------------
+ //= OCloneForLocale
+
+ // rtl::OUString m_sTargetLocale;
+ // std::auto_ptr<INode> m_pClone;
+
+ void OCloneForLocale::handle(ValueNode const& _aValue)
+ {
+ // just a single value - nothing to do
+ std::auto_ptr< INode > pClone( _aValue.clone() );
+
+ m_pClone = pClone;
+ }
+ //--------------------------------------------------------------------------
+ void OCloneForLocale::handle(ISubtree const& _aSubtree)
+ {
+ localehelper::FindBestLocale aLocaleMatcher( localehelper::makeLocale(m_sTargetLocale) );
+
+ m_pClone = implCloneForLocale(_aSubtree,aLocaleMatcher);
+ }
+ //--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+} // anonymous namespace
+
+//==========================================================================
+// Helper function to invoke the previous ones properly
+
+// convert to the given locale format, assuming the original representation was expanded
+static std::auto_ptr<INode> impl_cloneExpandedForLocale(INode const* _pNode, rtl::OUString const& _sLocale)
+{
+ OSL_ASSERT(_pNode != NULL);
+
+ if ( localehelper::designatesAllLocales(localehelper::makeLocale(_sLocale)) ) // from expanded to expanded
+ {
+ return _pNode->clone();
+ }
+
+ else // needs reduction
+ {
+ OCloneForLocale aCloner(_sLocale);
+ aCloner.applyToNode(*_pNode);
+ return aCloner.getResult();
+ }
+}
+//--------------------------------------------------------------------------
+
+// convert to the given locale format, assuming the original representation was expanded
+static rtl::Reference< data::TreeSegment > old_cloneExpandedForLocale(rtl::OUString const& _sName, INode const* _pNode, rtl::OUString const& _sLocale)
+{
+ if (_pNode == NULL)
+ return rtl::Reference< data::TreeSegment >();
+
+ std::auto_ptr<INode> aResult;
+ if (dynamic_cast< ISubtree const * >(_pNode) == 0) // simple value - nothing to reduce
+ aResult = _pNode->clone();
+
+ else
+ aResult = impl_cloneExpandedForLocale(_pNode,_sLocale);
+
+ return data::TreeSegment::create(_sName,aResult);
+}
+//--------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+rtl::Reference< data::TreeSegment > cloneExpandedForLocale(sharable::TreeFragment * tree, rtl::OUString const& _sLocale)
+{
+ std::auto_ptr<INode> aOldTree = data::convertTree(tree, true);
+
+ return old_cloneExpandedForLocale(tree->getName(), aOldTree.get(), _sLocale);
+}
+//--------------------------------------------------------------------------
+// convert to the given locale format, assuming the original representation was expanded
+std::auto_ptr<INode> reduceExpandedForLocale(std::auto_ptr<ISubtree> _pNode, rtl::OUString const& _sLocale)
+{
+ std::auto_ptr<INode> aResult;
+
+ if ( _pNode.get() == NULL || // nothing to reduce
+ localehelper::designatesAllLocales(localehelper::makeLocale(_sLocale)) ) // from expanded to expanded
+ {
+ aResult.reset( _pNode.release() );
+ }
+
+ else // needs reduction
+ {
+ OCloneForLocale aCloner(_sLocale);
+ aCloner.applyToNode(*_pNode);
+ aResult = aCloner.getResult();
+
+ OSL_ENSURE(aResult.get(),"Cloning a tree for a locale unexpectedly produced NOTHING");
+ }
+ return aResult;
+}
+//--------------------------------------------------------------------------
+namespace
+{
+//--------------------------------------------------------------------------
+ class ExpandTreeForLocale : NodeModification
+ {
+ ISubtree & m_rParent;
+ rtl::OUString const & m_aSourceLocale;
+
+ ExpandTreeForLocale(ISubtree & _rParent,rtl::OUString const & _aSourceLocale)
+ : m_rParent(_rParent)
+ , m_aSourceLocale(_aSourceLocale)
+ {}
+
+ void handle(ISubtree& _rNode);
+ void handle(ValueNode& _rNode);
+
+ void substitute(std::auto_ptr<INode> _aExpanded);
+ public:
+ static void expand(ISubtree& _rTree, rtl::OUString const & _aSourceLocale)
+ {
+ ExpandTreeForLocale(_rTree,_aSourceLocale).applyToChildren(_rTree);
+ }
+
+ // returns NULL, if not a localized value
+ static std::auto_ptr<ISubtree> expanded(ValueNode const& _aNode, rtl::OUString const & _aSourceLocale);
+ };
+
+//--------------------------------------------------------------------------
+ class ExpandChangesForLocale : ChangeTreeModification
+ {
+ SubtreeChange & m_rParent;
+ rtl::OUString const & m_aSourceLocale;
+
+ ExpandChangesForLocale(SubtreeChange & _rParent,rtl::OUString const & _aSourceLocale)
+ : m_rParent(_rParent)
+ , m_aSourceLocale(_aSourceLocale)
+ {}
+
+ void handle(SubtreeChange& _rNode);
+ void handle(ValueChange& _rNode);
+
+ void handle(AddNode& _rNode);
+ void handle(RemoveNode& _rNode);
+
+ void substitute(std::auto_ptr<Change> _aExpanded);
+ public:
+ static void expand(SubtreeChange& _rTree, rtl::OUString const & _aSourceLocale)
+ {
+ ExpandChangesForLocale(_rTree,_aSourceLocale).applyToChildren(_rTree);
+ }
+
+ // returns NULL, if not a localized value
+ static std::auto_ptr<SubtreeChange> expanded(ValueChange const& _aNode, rtl::OUString const & _aSourceLocale);
+ };
+//--------------------------------------------------------------------------
+inline
+void ExpandTreeForLocale::substitute(std::auto_ptr<INode> _aExpanded)
+{
+ m_rParent.removeChild(_aExpanded->getName());
+ m_rParent.addChild(_aExpanded);
+}
+
+//--------------------------------------------------------------------------
+void ExpandTreeForLocale::handle(ISubtree& _rNode)
+{
+ expand(_rNode,m_aSourceLocale);
+}
+
+//--------------------------------------------------------------------------
+void ExpandTreeForLocale::handle(ValueNode& _rNode)
+{
+ std::auto_ptr<ISubtree> aExpanded = expanded(_rNode,m_aSourceLocale);
+
+ if (aExpanded.get())
+ substitute( base_ptr(aExpanded) );
+}
+
+//--------------------------------------------------------------------------
+
+std::auto_ptr<ISubtree> ExpandTreeForLocale::expanded(ValueNode const& _aNode, rtl::OUString const & _aSourceLocale)
+{
+ if (!_aNode.isLocalized()) return std::auto_ptr<ISubtree>();
+
+ OTreeNodeFactory & rFactory = getDefaultTreeNodeFactory();
+
+ node::Attributes aValueAttributes = _aNode.getAttributes();
+
+ aValueAttributes.setLocalized(false);
+ if (aValueAttributes.state() == node::isMerged)
+ aValueAttributes.setState( node::isReplaced );
+
+
+ std::auto_ptr<ValueNode> aValue = _aNode.isNull()
+ ? rFactory.createNullValueNode(_aSourceLocale,_aNode.getValueType(),aValueAttributes)
+ : rFactory.createValueNode(_aSourceLocale,_aNode.getValue(),aValueAttributes);
+
+ std::auto_ptr<ISubtree> aRet = rFactory.createSetNode( _aNode.getName(),
+ toTemplateName(_aNode.getValueType()),
+ TEMPLATE_MODULE_LOCALIZED_VALUE,
+ _aNode.getAttributes() );
+
+ aRet->addChild(base_ptr(aValue));
+
+ return aRet;
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+inline
+void ExpandChangesForLocale::substitute(std::auto_ptr<Change> _aExpanded)
+{
+ m_rParent.removeChange(_aExpanded->getNodeName());
+ m_rParent.addChange(_aExpanded);
+}
+
+//--------------------------------------------------------------------------
+
+void ExpandChangesForLocale::handle(SubtreeChange& _rNode)
+{
+ expand(_rNode,m_aSourceLocale);
+}
+
+//--------------------------------------------------------------------------
+void ExpandChangesForLocale::handle(ValueChange& _rNode)
+{
+ std::auto_ptr<SubtreeChange> aExpanded = expanded(_rNode,m_aSourceLocale);
+
+ if (aExpanded.get())
+ substitute( base_ptr( aExpanded ) );
+}
+
+//--------------------------------------------------------------------------
+void ExpandChangesForLocale::handle(AddNode& _rNode)
+{
+ rtl::Reference< data::TreeSegment > seg(_rNode.getNewTree());
+ std::auto_ptr<INode> pAdded(data::convertTree(seg.is() ? seg->fragment : 0, false));
+ if (pAdded.get() != NULL)
+ {
+ std::auto_ptr<INode> pExpanded;
+ if (ISubtree * pAddedTree = pAdded->asISubtree())
+ {
+ ExpandTreeForLocale::expand(*pAddedTree,m_aSourceLocale);
+ pExpanded = pAdded;
+ }
+ else if(ValueNode * pAddedValue = pAdded->asValueNode())
+ {
+ pExpanded = base_ptr(ExpandTreeForLocale::expanded(*pAddedValue,m_aSourceLocale));
+ }
+ else
+ OSL_ENSURE(false, "Cannot expand unknown Node type (found in AddNode)");
+
+
+ if (pExpanded.get())
+ {
+ rtl::Reference< data::TreeSegment > aExpanded = data::TreeSegment::create( _rNode.getNodeName(),pExpanded);
+ std::auto_ptr<AddNode> aExpandedAdd( new AddNode( aExpanded, _rNode.getNodeName(), _rNode.isToDefault() ) );
+
+ if (_rNode.isReplacing()) aExpandedAdd->setReplacing();
+
+ substitute( base_ptr( aExpandedAdd ) );
+ }
+ }
+ else
+ OSL_ENSURE(false, "Cannot expand AddNode without content");
+}
+
+//--------------------------------------------------------------------------
+void ExpandChangesForLocale::handle(RemoveNode& )
+{
+ // nothing to do
+}
+
+//--------------------------------------------------------------------------
+std::auto_ptr<SubtreeChange> ExpandChangesForLocale::expanded(ValueChange const& _aNode, rtl::OUString const & _aSourceLocale)
+{
+ std::auto_ptr<SubtreeChange> aRet;
+ if (_aNode.isLocalizedValue())
+ {
+ OTreeNodeFactory & rNodeFactory = getDefaultTreeNodeFactory();
+ OTreeChangeFactory & rFactory = getDefaultTreeChangeFactory();
+
+ node::Attributes aValueAttributes = _aNode.getAttributes();
+
+ aValueAttributes.setLocalized(false);
+ if (aValueAttributes.state() == node::isMerged)
+ aValueAttributes.setState( node::isReplaced );
+
+
+ rtl::OUString const sTemplateName = toTemplateName(_aNode.getValueType());
+
+ std::auto_ptr<ValueNode> aValue = _aNode.getNewValue().hasValue()
+ ? rNodeFactory.createValueNode(sTemplateName,_aNode.getNewValue(),aValueAttributes)
+ : rNodeFactory.createNullValueNode(sTemplateName,_aNode.getValueType(),aValueAttributes);
+
+ rtl::Reference< data::TreeSegment > aValueSegment = data::TreeSegment::create(_aSourceLocale, base_ptr(aValue));
+
+ std::auto_ptr<AddNode> aAddValue = rFactory.createAddNodeChange(aValueSegment,_aSourceLocale,_aNode.isToDefault());
+ aAddValue->setReplacing();
+
+ aRet = rFactory.createSetNodeChange( _aNode.getNodeName(),
+ sTemplateName,
+ TEMPLATE_MODULE_LOCALIZED_VALUE,
+ _aNode.getAttributes() );
+
+ aRet->addChange(base_ptr(aAddValue));
+ }
+ return aRet;
+}
+
+//--------------------------------------------------------------------------
+} // anonymous namespace
+//--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+
diff --git a/configmgr/source/tree/makefile.mk b/configmgr/source/tree/makefile.mk
new file mode 100644
index 000000000000..41cf2e0c5f8f
--- /dev/null
+++ b/configmgr/source/tree/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.13 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source
+
+PRJNAME=configmgr
+TARGET=cm
+ENABLE_EXCEPTIONS=TRUE
+
+
+# --- Settings ---
+.IF "$(DBGUTIL_OJ)"!=""
+ENVCFLAGS+=/FR$(SLO)$/
+.ENDIF
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+# --- Files ---
+
+SLOFILES=\
+ $(SLO)$/builddata.obj \
+ $(SLO)$/node.obj \
+ $(SLO)$/treefragment.obj \
+ $(SLO)$/treesegment.obj \
+ $(SLO)$/nodevisitor.obj \
+ $(SLO)$/changes.obj \
+ $(SLO)$/treenodefactory.obj \
+ $(SLO)$/treechangefactory.obj \
+ $(SLO)$/localizedtreeactions.obj \
+ $(SLO)$/treeactions.obj \
+ $(SLO)$/cmtreemodel.obj \
+ $(SLO)$/cmtree.obj \
+ $(SLO)$/nodeconverter.obj \
+ $(SLO)$/updatehelper.obj \
+ $(SLO)$/mergehelper.obj \
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/tree/mergehelper.cxx b/configmgr/source/tree/mergehelper.cxx
new file mode 100644
index 000000000000..61747aa68b85
--- /dev/null
+++ b/configmgr/source/tree/mergehelper.cxx
@@ -0,0 +1,459 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mergehelper.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "builddata.hxx"
+#include "nodeconverter.hxx"
+#include "treefragment.hxx"
+#include "treenodefactory.hxx"
+#include "treechangefactory.hxx"
+#include "configpath.hxx"
+#include "tracer.hxx"
+#include <osl/diagnose.h>
+
+
+//..........................................................................
+namespace configmgr
+{
+
+namespace
+{
+//==========================================================================
+//= OCleanupLayerAction
+//==========================================================================
+//= This class cleans up a layer to be merged into an existing tree
+//==========================================================================
+class OCleanupLayerAction : ChangeTreeModification
+{
+ SubtreeChange& m_rResultTree; // list which containes changes merged with the existing nodes
+ ISubtree const & m_rTargetTree; // reference node needed for merging
+ OTreeNodeConverter m_aNodeConverter;
+public:
+ static bool adjust(SubtreeChange& _rResultTree, SubtreeChange& _aLayerTree, ISubtree const& _aTargetTree)
+ {
+ return OCleanupLayerAction(_rResultTree,_aTargetTree).impl_cleanup(_aLayerTree);
+ }
+ static bool adjust(SubtreeChange& _rResultTree, SubtreeChange& _aLayerTree, ISubtree const& _aTargetTree, OTreeNodeFactory& _rNodeFactory)
+ {
+ return OCleanupLayerAction(_rResultTree,_aTargetTree,_rNodeFactory).impl_cleanup(_aLayerTree);
+ }
+
+private:
+ OCleanupLayerAction(SubtreeChange& _rResult, ISubtree const& _rTree)
+ :m_rResultTree(_rResult)
+ ,m_rTargetTree(_rTree)
+ ,m_aNodeConverter()
+ {}
+
+ OCleanupLayerAction(SubtreeChange& _rResult, ISubtree const& _rTree, OTreeNodeFactory& _rNodeFactory)
+ :m_rResultTree(_rResult)
+ ,m_rTargetTree(_rTree)
+ ,m_aNodeConverter(_rNodeFactory)
+ {}
+
+ void handle(ValueChange& aValueNode);
+ void handle(AddNode& aAddNode);
+ void handle(RemoveNode& aRemoveNode);
+ void handle(SubtreeChange& aSubtree);
+
+ bool impl_cleanup(SubtreeChange& _aUpdateTree);
+
+ void add(std::auto_ptr<Change> _pChange);
+ void addReplacedNode(rtl::Reference< data::TreeSegment > const & _aReplacedTree);
+ void addReplacedNode(std::auto_ptr<INode> _aReplacedNode);
+};
+
+// --------------------------------- MergeLayerToTree ---------------------------------
+
+class MergeLayerToTree : ChangeTreeModification
+{
+ ISubtree& m_rTree;
+
+public:
+ explicit
+ MergeLayerToTree(ISubtree& _rTree):m_rTree(_rTree) {}
+
+ MergeLayerToTree& merge(SubtreeChange & _rLayerTree);
+private:
+ void handle(ValueChange& aValueNode);
+ void handle(AddNode& aAddNode);
+ void handle(RemoveNode& aRemoveNode);
+ void handle(SubtreeChange& aSubtree);
+
+ static void mergeAttributes(INode& _rNode, node::Attributes const& _aChangeAttributes);
+};
+// --------------------------------- AttributeSetter ---------------------------------
+
+class AttributeSetter : NodeModification
+{
+ node::State m_state;
+ bool m_bPromoteFinalized;
+public:
+ explicit
+ AttributeSetter(node::State _state, bool _bPromoteFinalized)
+ : m_state(_state)
+ , m_bPromoteFinalized(_bPromoteFinalized)
+ {}
+
+ void setNodeAttributes(INode& _rNode);
+
+ using NodeModification::applyToNode;
+private:
+ void handle(ValueNode& _rValueNode);
+ void handle(ISubtree& _rSubtree);
+};
+// -----------------------------------------------------------------------------
+
+} // anon namepsace
+// -----------------------------------------------------------------------------
+// this is our 'exported' function
+
+// -----------------------------------------------------------------------------
+namespace
+{
+//==========================================================================
+//= OCleanupLayerAction
+//==========================================================================
+static inline bool isFinal(node::Attributes const& _aAttributes)
+{
+ return _aAttributes.isFinalized() || _aAttributes.isReadonly();
+}
+//==========================================================================
+bool OCleanupLayerAction::impl_cleanup(SubtreeChange& _aUpdateTree)
+{
+ OSL_ENSURE(!_aUpdateTree.isReplacedNode(), "Layer cleanup: A replaced tree should not be merged");
+
+ if (isFinal(m_rTargetTree.getAttributes()))
+ {
+ CFG_TRACE_WARNING("Layer cleanup : Ignoring change to write-protected tree '%s'",OUSTRING2ASCII(m_rTargetTree.getName()));
+ return false;
+ }
+
+ // first check the changes
+ this->applyToChildren(_aUpdateTree);
+
+ return m_rResultTree.size() != 0;
+}
+//--------------------------------------------------------------------------
+inline void OCleanupLayerAction::add(std::auto_ptr<Change> _aChange)
+{
+ m_rResultTree.addChange(_aChange);
+}
+//--------------------------------------------------------------------------
+void OCleanupLayerAction::handle(ValueChange& _rChange)
+{
+ rtl::OUString const sNodeName = _rChange.getNodeName();
+
+ OSL_ENSURE(!_rChange.isToDefault(),"Found change to default in layer being merged");
+
+ // replaced state -> should be a full (added/replaced) node
+ //if (_rChange.isReplacedNode() && m_rTargetTree.isSetNodeChange())
+ if ( _rChange.isReplacedValue() )
+ {
+ std::auto_ptr<ValueNode> pNode( m_aNodeConverter.createCorrespondingNode(_rChange) );
+
+ this->addReplacedNode( base_ptr(pNode) );
+
+ }
+ else if (INode const * const pTargetNode = m_rTargetTree.getChild(sNodeName))
+ {
+ // this mismatch is not discarded here (should be ignored while merging though)
+ OSL_ENSURE(pTargetNode->asValueNode(), "Layer cleanup : Node type mismatch: Value change applied to non-value node !");
+
+ if (!isFinal(pTargetNode->getAttributes()))
+ {
+ std::auto_ptr<Change> pResult( new ValueChange(_rChange) );
+ this->add(pResult);
+ }
+ else
+ {
+ CFG_TRACE_WARNING("Layer cleanup : Ignoring change to write-protected value '%s'",OUSTRING2ASCII(sNodeName));
+ }
+ }
+ else
+ {
+ OSL_TRACE("Layer cleanup : Found orphaned node (value) '%s'",OUSTRING2ASCII(sNodeName));
+ CFG_TRACE_INFO("Layer cleanup : Found orphaned node (value) '%s'",OUSTRING2ASCII(sNodeName));
+ OSL_ENSURE(false, "Layer cleanup : Found orphaned Value");
+ }
+}
+
+//--------------------------------------------------------------------------
+void OCleanupLayerAction::handle(SubtreeChange& _rChange)
+{
+ rtl::OUString const sNodeName = _rChange.getNodeName();
+
+ OSL_ENSURE(!_rChange.isToDefault(),"Found change to default in layer being merged");
+
+ // replaced state -> should be a full (added/replaced) node
+ if (_rChange.isReplacedNode())
+ {
+ std::auto_ptr<ISubtree> pNode = m_aNodeConverter.createCorrespondingTree(_rChange);
+
+ // mark as complete with defaults)
+ pNode->setLevels(treeop::ALL_LEVELS,treeop::ALL_LEVELS);
+
+ this->addReplacedNode( base_ptr(pNode) );
+ }
+ else if ( INode const * const pTargetNode = m_rTargetTree.getChild(sNodeName) )
+ {
+ ISubtree const * pTargetTree = pTargetNode->asISubtree();
+
+ if (pTargetTree)
+ {
+ // generate a new change
+ std::auto_ptr<SubtreeChange> pResult( new SubtreeChange(_rChange, treeop::NoChildCopy()) );
+
+ // recurse
+ if ( adjust(*pResult,_rChange,*pTargetTree,m_aNodeConverter.nodeFactory()) )
+ this->add(base_ptr(pResult));
+
+ else
+ CFG_TRACE_INFO("Layer cleanup : Found void modification tree '%s'",OUSTRING2ASCII(sNodeName));
+ }
+ else
+ {
+ OSL_ENSURE(false, "Layer cleanup : Node type mismatch: Tree change applied to non-tree node !");
+ CFG_TRACE_ERROR("Layer cleanup : Discarding schema violation for node '%s'",OUSTRING2ASCII(sNodeName));
+ //throw Whatever();
+ }
+ }
+ else
+ {
+ OSL_TRACE("Layer cleanup : Found orphaned node (subtree) '%s'",OUSTRING2ASCII(sNodeName));
+ CFG_TRACE_INFO("Layer cleanup : Found orphaned node (subtree) '%s'",OUSTRING2ASCII(sNodeName));
+ }
+}
+
+//--------------------------------------------------------------------------
+void OCleanupLayerAction::handle(RemoveNode& _rChange)
+{
+ rtl::OUString const sNodeName = _rChange.getNodeName();
+
+ OSL_ENSURE(!_rChange.isToDefault(),"Found change to default in layer being merged");
+
+ OSL_ENSURE(m_rTargetTree.isSetNode(),"Found RemoveNode for non-set-element in layer being merged");
+
+ // look up the corresponding node
+ INode const * const pTargetNode = m_rTargetTree.getChild(sNodeName);
+
+ if (pTargetNode)
+ {
+ // generate the same change
+ std::auto_ptr<Change> pResult( new RemoveNode(sNodeName,false) );
+ this->add(pResult);
+ }
+ else
+ {
+ OSL_TRACE("Layer cleanup : Found orphaned node (removal) '%s'",OUSTRING2ASCII(sNodeName));
+ CFG_TRACE_INFO("Layer cleanup : Found orphaned node (removal) '%s'",OUSTRING2ASCII(sNodeName));
+ }
+}
+
+//--------------------------------------------------------------------------
+void OCleanupLayerAction::handle(AddNode& _rChange)
+{
+ OSL_ENSURE(!_rChange.isToDefault(),"Found change to default in layer being merged");
+
+// generate the same change
+ this->addReplacedNode( _rChange.getNewTree() );
+}
+
+//--------------------------------------------------------------------------
+void OCleanupLayerAction::addReplacedNode(std::auto_ptr<INode> _aReplacedNode)
+{
+ OSL_ENSURE(m_rTargetTree.isSetNode(),"Found replaced node for non-set-element in layer being merged");
+
+ OSL_ASSERT(_aReplacedNode.get());
+
+ rtl::OUString sTypeName = m_rTargetTree.getElementTemplateName();
+
+ this->addReplacedNode( data::TreeSegment::create(_aReplacedNode,sTypeName) );
+}
+
+//--------------------------------------------------------------------------
+void OCleanupLayerAction::addReplacedNode(rtl::Reference< data::TreeSegment > const & _aReplacedTree)
+{
+ OSL_ENSURE(m_rTargetTree.isSetNode(),"Found replaced node for non-set-element in layer being merged");
+
+ OSL_ASSERT(_aReplacedTree.is());
+
+ rtl::OUString sNodeName = _aReplacedTree->fragment->getName();
+
+ // add the tree to the change list
+ std::auto_ptr<AddNode> pResult( new AddNode(_aReplacedTree,sNodeName, false) );
+
+ // look up the corresponding existing node
+ INode const * const pTargetNode = m_rTargetTree.getChild(sNodeName);
+
+ if (pTargetNode) pResult->setReplacing();
+
+ this->add( base_ptr(pResult) );
+}
+
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+void MergeLayerToTree::mergeAttributes(INode& _rNode, node::Attributes const& _aChangeAttributes)
+{
+ OSL_ENSURE(!isFinal(_rNode.getAttributes()),"Layer merge: Node being merged is READONLY - cleanup broken");
+ OSL_ENSURE(_aChangeAttributes.state() == node::isMerged,"Layer merge: Found unexpected state for change being merged");
+
+ _rNode.modifyState(node::isMerged);
+ _rNode.modifyAccess(_aChangeAttributes.getAccess());
+}
+//--------------------------------------------------------------------------
+
+MergeLayerToTree& MergeLayerToTree::merge(SubtreeChange & _rLayerTree)
+{
+ OSL_ENSURE(_rLayerTree.getNodeName() == m_rTree.getName(),"Layer merge: change does not match tree");
+
+ this->applyToChildren(_rLayerTree);
+ mergeAttributes(m_rTree,_rLayerTree.getAttributes());
+
+ return *this;
+}
+//--------------------------------------------------------------------------
+
+void MergeLayerToTree::handle(ValueChange& _rChange)
+{
+ OSL_ENSURE(!_rChange.isToDefault(),"Layer merge: Found change to default - cleanup broken");
+
+ rtl::OUString const sNodeName = _rChange.getNodeName();
+
+ INode * const pTargetNode = m_rTree.getChild(sNodeName);
+
+ OSL_ENSURE(pTargetNode,"Layer merge: Found NULL value - cleanup broken");
+ OSL_ENSURE(!isFinal(pTargetNode->getAttributes()),"Layer merge: Found READONLY value - cleanup broken");
+
+ if (ValueNode* pTargetValue = pTargetNode->asValueNode() )
+ {
+ _rChange.applyChangeNoRecover(*pTargetValue);
+ mergeAttributes(*pTargetValue,_rChange.getAttributes());
+ }
+ else
+ {
+ OSL_ENSURE(false, "Layer merge : Node type mismatch: Value change applied to non-value node !");
+ CFG_TRACE_ERROR("Layer merge : Discarding schema violation for value '%s'",OUSTRING2ASCII(sNodeName));
+ //throw Whatever();
+ }
+}
+//--------------------------------------------------------------------------
+
+void MergeLayerToTree::handle(AddNode& _rChange)
+{
+ rtl::OUString const sNodeName = _rChange.getNodeName();
+
+ node::State eNodeState = node::isAdded;
+
+ if (_rChange.isReplacing())
+ {
+ OSL_VERIFY( m_rTree.removeChild(sNodeName).get() );
+ eNodeState = node::isReplaced;
+ }
+
+ OSL_ENSURE( !m_rTree.getChild(sNodeName),"Layer merge: Found conflicting data on insert - cleanup broken");
+
+ rtl::Reference< data::TreeSegment > aAddedTree = _rChange.getNewTree();
+
+ OSL_ENSURE(aAddedTree.is(), "Layer merge: Found empty data on insert - cleanup broken");
+
+ // clean up the attributes of the added node
+ std::auto_ptr<INode> aAddedData(data::convertTree(aAddedTree->fragment, true));
+
+ AttributeSetter(eNodeState,false).applyToNode(*aAddedData);
+
+ m_rTree.addChild(aAddedData);
+}
+//--------------------------------------------------------------------------
+
+void MergeLayerToTree::handle(RemoveNode& _rChange)
+{
+ rtl::OUString const sNodeName = _rChange.getNodeName();
+
+ // should have such a node when removing
+ OSL_VERIFY( m_rTree.removeChild(sNodeName).get() );
+}
+//--------------------------------------------------------------------------
+
+
+void MergeLayerToTree::handle(SubtreeChange& _rChange)
+{
+ OSL_ENSURE(!_rChange.isToDefault(),"Layer merge: Found change to default - cleanup broken");
+
+ rtl::OUString const sNodeName = _rChange.getNodeName();
+
+ INode * const pTargetNode = m_rTree.getChild(sNodeName);
+
+ OSL_ENSURE(pTargetNode,"Layer merge: Found NULL subtree - cleanup broken");
+ OSL_ENSURE(!isFinal(pTargetNode->getAttributes()),"Layer merge: Found READONLY subtree - cleanup broken");
+
+ ISubtree * const pTargetTree = pTargetNode->asISubtree();
+ OSL_ENSURE(pTargetTree,"Layer merge: Found non-tree for SubtreeChange - cleanup broken");
+
+ // recurse
+ MergeLayerToTree(*pTargetTree).merge(_rChange);
+}
+//--------------------------------------------------------------------------
+
+void AttributeSetter::setNodeAttributes(INode& _rNode)
+{
+ node::Attributes const aOldAttributes = _rNode.getAttributes();
+
+ _rNode.modifyState(m_state);
+ if (m_bPromoteFinalized && isFinal(aOldAttributes))
+ _rNode.modifyAccess(node::accessReadonly);
+}
+// -----------------------------------------------------------------------------
+
+void AttributeSetter::handle(ValueNode& _rValueNode)
+{
+ setNodeAttributes(_rValueNode);
+}
+// -----------------------------------------------------------------------------
+
+void AttributeSetter::handle(ISubtree& _rSubtree)
+{
+ setNodeAttributes(_rSubtree);
+
+ this->applyToChildren(_rSubtree);
+}
+//--------------------------------------------------------------------------
+
+} // anonymous namespace
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+
diff --git a/configmgr/source/tree/node.cxx b/configmgr/source/tree/node.cxx
new file mode 100644
index 000000000000..43dc4de3ddd7
--- /dev/null
+++ b/configmgr/source/tree/node.cxx
@@ -0,0 +1,538 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: node.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "node.hxx"
+#include "anydata.hxx"
+#include "treefragment.hxx"
+#include "attributes.hxx"
+#include "utility.hxx"
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+#ifndef INCLUDED_CSTDDEF
+#include <cstddef>
+#define INCLUDED_CSTDDEF
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace sharable
+ {
+//-----------------------------------------------------------------------------
+
+rtl::OUString NodeInfo::getName() const
+{
+ return rtl::OUString(this->name);
+}
+//-----------------------------------------------------------------------------
+
+configmgr::node::Attributes NodeInfo::getNodeInfoAttributes() const
+{
+ configmgr::node::Attributes aResult;
+
+ bool help = !!(flags & data::Flags::readonly);
+ aResult.setAccess( help,!!(flags & data::Flags::finalized) );
+// aResult.setAccess( !!(flags & data::Flags::readonly),!!(flags & data::Flags::finalized) );
+
+ aResult.setNullable(!!(flags & data::Flags::nullable));
+ aResult.setLocalized(!!(flags & data::Flags::localized));
+
+ configmgr::node::State state = (flags & data::Flags::defaulted) ? configmgr::node::isDefault :
+ (flags & data::Flags::defaultable) ? configmgr::node::isMerged :
+ configmgr::node::isReplaced;
+ aResult.setState(state);
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+bool NodeInfo::isDefault() const
+{
+ return !!(this->flags & data::Flags::defaulted);
+}
+//-----------------------------------------------------------------------------
+
+bool NodeInfo::isLocalized() const
+{
+ return !!(this->flags & data::Flags::localized);
+}
+//-----------------------------------------------------------------------------
+
+void NodeInfo::markAsDefault(bool bDefault)
+{
+ if (bDefault)
+ {
+ OSL_ENSURE(flags & data::Flags::defaultable,"Marking a non-defaultable node as default");
+ this->flags |= data::Flags::defaulted;
+ }
+ else
+ this->flags &= ~data::Flags::defaulted;
+}
+//-----------------------------------------------------------------------------
+
+bool GroupNode::hasDefaultsAvailable() const
+{
+ if (this->info.isDefault())
+ return true;
+
+ if (node(this)->getTreeFragment()->hasDefaultsAvailable())
+ return true;
+
+#if 0 // extended check for default state
+ for (Node const * pChild = getFirstChild(); pChild != NULL; pChild = getNextChild(pChild))
+ if (! pChild->isDefault() )
+ return false;
+
+ return true;
+#endif
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+Node * GroupNode::getFirstChild() const
+{
+ OSL_ENSURE(numDescendants, "Groups MUST have at least one child");
+ return const_cast< Node * >(node(this) + 1);
+}
+//-----------------------------------------------------------------------------
+
+static
+sal_uInt16 implGetNextChildOffset(GroupNode const * _pParent, Node const * _pChild)
+{
+ OSL_PRECOND(_pChild, "getNextChild: previous child must not be NULL");
+ OSL_PRECOND(_pChild->getParentNode() == node(_pParent), "getNextChild: not a child of this node");
+
+
+ OSL_ENSURE( node(_pParent) < _pChild && _pChild <= node(_pParent) + _pParent->numDescendants,
+ "getNextChild: child out of descendants range");
+
+ // offset to child's next sibling
+ sal_uInt16 next = 1;
+ if ( _pChild->isGroup())
+ {
+ next = next + _pChild->group.numDescendants;
+ }
+
+ if (_pChild->info.parent + next > _pParent->numDescendants)
+ {
+ OSL_ENSURE(_pChild->info.parent + next == _pParent->numDescendants+1, "Next child candidate should match next sibling here");
+ return 0;
+ }
+
+ OSL_POSTCOND( (_pChild+next)->getParentNode() == node(_pParent), "getNextChild: not a child of this node");
+ return next;
+}
+//-----------------------------------------------------------------------------
+
+Node * GroupNode::getNextChild(Node * _pChild) const
+{
+ if (sal_uInt16 next = implGetNextChildOffset(this, _pChild))
+ return _pChild + next;
+
+ else
+ return NULL;
+}
+
+Node * GroupNode::getChild(rtl::OUString const & name) const {
+ for (Node * child = getFirstChild(); child != 0;
+ child = getNextChild(child))
+ {
+ if (child->isNamed(name)) {
+ return child;
+ }
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+// TODO: optimize this - keep a list of such structs ....
+struct SetNodeTemplateData
+{
+ rtl_uString * name;
+ rtl_uString * module;
+};
+//-----------------------------------------------------------------------------
+static inline
+SetNodeTemplateData * readTemplateData(sal_uInt8 * _aTemplateData)
+{
+ return reinterpret_cast<SetNodeTemplateData *>( _aTemplateData );
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt8 * SetNode::allocTemplateData(const rtl::OUString &rName,
+ const rtl::OUString &rModule)
+{
+ SetNodeTemplateData * pData = new SetNodeTemplateData();
+
+ OSL_ENSURE(pData, "Creating template data: unexpected NULL data");
+
+ pData->name = acquireString(rName);
+ pData->module = acquireString(rModule);
+
+ return reinterpret_cast<sal_uInt8 *>( pData );
+}
+
+sal_uInt8 * SetNode::copyTemplateData(sal_uInt8 * _aTemplateData)
+{
+ SetNodeTemplateData const * pData = readTemplateData(_aTemplateData);
+
+ OSL_ENSURE(pData, "Copying template data: unexpected NULL data");
+
+ return allocTemplateData(rtl::OUString(pData->name), rtl::OUString(pData->module));
+}
+
+//-----------------------------------------------------------------------------
+
+void SetNode::releaseTemplateData(sal_uInt8 * _aTemplateData)
+{
+ if (!_aTemplateData) return;
+
+ SetNodeTemplateData const * pData = readTemplateData(_aTemplateData);
+
+ OSL_ENSURE(pData, "Freeing template data: unexpected NULL data");
+
+ rtl_uString_release(pData->name);
+ rtl_uString_release(pData->module);
+
+ delete pData;
+}
+
+//-----------------------------------------------------------------------------
+
+rtl::OUString SetNode::getElementTemplateName() const
+{
+ SetNodeTemplateData const * pData = readTemplateData(this->elementType);
+
+ OSL_ENSURE(pData, "ERROR: No template data found for set");
+
+ return rtl::OUString(pData->name);
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString SetNode::getElementTemplateModule() const
+{
+ SetNodeTemplateData const * pData = readTemplateData(this->elementType);
+
+ OSL_ENSURE(pData, "ERROR: No template data found for set");
+
+ return rtl::OUString(pData->module);
+}
+//-----------------------------------------------------------------------------
+
+static inline
+TreeFragment * implGetFragmentFromList(TreeFragment * _aListEntry)
+{
+ return reinterpret_cast<TreeFragment *>(_aListEntry);
+}
+//-----------------------------------------------------------------------------
+
+TreeFragment * SetNode::getFirstElement() const
+{
+ return implGetFragmentFromList(this->elements);
+}
+//-----------------------------------------------------------------------------
+
+TreeFragment * SetNode::getNextElement(TreeFragment * _pElement) const
+{
+ OSL_PRECOND(_pElement, "getNextElement: previous element must not be NULL");
+ OSL_PRECOND(_pElement->header.parent == (Node *)this,
+ "getNextElement: not an element of this node");
+
+ return implGetFragmentFromList(_pElement->header.next);
+}
+
+TreeFragment * SetNode::getElement(rtl::OUString const & name) const {
+ for (TreeFragment * element = getFirstElement(); element != 0;
+ element = getNextElement(element))
+ {
+ if (element->isNamed(name)) {
+ return element;
+ }
+ }
+ return 0;
+}
+
+void SetNode::addElement(TreeFragment * newElement) {
+ OSL_ASSERT(newElement != 0);
+ newElement->header.next = elements;
+ newElement->header.parent = node(this);
+ elements = newElement;
+}
+
+TreeFragment * SetNode::removeElement(rtl::OUString const & name) {
+ for (TreeFragment ** link = &elements; *link != 0;
+ link = &(*link)->header.next)
+ {
+ if ((*link)->isNamed(name)) {
+ TreeFragment * removed = *link;
+ *link = removed->header.next;
+ removed->header.next = 0;
+ removed->header.parent = 0;
+ return removed;
+ }
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+
+bool ValueNode::isNull() const
+{
+ data::Flags::Type availmask = (info.flags & data::Flags::defaulted) ?
+ data::Flags::defaultAvailable :
+ data::Flags::valueAvailable;
+
+ return !(info.flags & availmask);
+}
+//-----------------------------------------------------------------------------
+
+bool ValueNode::hasUsableDefault() const
+{
+ return (info.flags & data::Flags::defaultable) &&
+ (info.flags & (data::Flags::defaultAvailable| data::Flags::nullable));
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Type ValueNode::getValueType() const
+{
+ sal_uInt8 aType = sal_uInt8( info.type & data::Type::mask_valuetype );
+
+ return getUnoType(aType);
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any ValueNode::getValue() const
+{
+ if (info.flags & data::Flags::defaulted)
+ return getDefaultValue();
+
+ else
+ return getUserValue();
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any ValueNode::getUserValue() const
+{
+ if (info.flags & data::Flags::valueAvailable)
+ {
+ sal_uInt8 aType = sal_uInt8( info.type & data::Type::mask_valuetype );
+
+ return readData(aType,this->value);
+ }
+ else
+ return com::sun::star::uno::Any();
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any ValueNode::getDefaultValue() const
+{
+ if (info.flags & data::Flags::defaultAvailable)
+ {
+ sal_uInt8 aType = sal_uInt8( info.type & data::Type::mask_valuetype );
+
+ return readData(aType,this->defaultValue);
+ }
+ else
+ return com::sun::star::uno::Any();
+}
+
+void ValueNode::setValue(com::sun::star::uno::Any const & newValue) {
+ releaseValue();
+ if (newValue.hasValue()) {
+ sal_uInt8 type = adaptType(newValue);
+ value = allocData(type, newValue);
+ info.flags |= data::Flags::valueAvailable;
+ }
+ info.flags &= ~data::Flags::defaulted;
+}
+
+void ValueNode::setToDefault() {
+ OSL_ASSERT(hasUsableDefault());
+ releaseValue();
+ info.flags |= data::Flags::defaulted;
+}
+
+void ValueNode::changeDefault(com::sun::star::uno::Any const & newDefault) {
+ sal_uInt8 type = static_cast< sal_uInt8 >(
+ info.type & data::Type::mask_valuetype);
+ if (info.flags & data::Flags::defaultAvailable) {
+ OSL_ASSERT(type != data::Type::value_any);
+ freeData(type, defaultValue);
+ defaultValue.data = 0;
+ info.flags &= ~data::Flags::defaultAvailable;
+ }
+ if (newDefault.hasValue()) {
+ type = adaptType(newDefault);
+ defaultValue = allocData(type, newDefault);
+ info.flags |= data::Flags::defaultAvailable;
+ }
+}
+
+void ValueNode::releaseValue() {
+ if ((info.flags & data::Flags::valueAvailable) != 0) {
+ sal_uInt8 type = static_cast< sal_uInt8 >(
+ info.type & data::Type::mask_valuetype);
+ OSL_ASSERT(type != data::Type::value_any);
+ freeData(type, value);
+ value.data = 0;
+ info.flags &= ~data::Flags::valueAvailable;
+ }
+}
+
+sal_uInt8 ValueNode::adaptType(com::sun::star::uno::Any const & newValue) {
+ sal_uInt8 newType = getTypeCode(newValue.getValueType());
+ OSL_ASSERT(newType != data::Type::value_any);
+ sal_uInt8 type = static_cast< sal_uInt8 >(
+ info.type & data::Type::mask_valuetype);
+ if (type == data::Type::value_any) {
+ type = static_cast< sal_uInt8 >(newType & data::Type::mask_valuetype);
+ info.type = (info.type & ~data::Type::mask_valuetype) | type;
+ }
+ OSL_ASSERT(newType == type);
+ return type;
+}
+
+//-----------------------------------------------------------------------------
+
+bool Node::isNamed(rtl::OUString const & _aName) const
+{
+ rtl_uString *pCmpData = _aName.pData;
+ rtl_uString *pNodeData = info.name;
+
+ // Creating an OUString does rather expensive interlocking here.
+ if (pCmpData == pNodeData)
+ return true;
+ if (pCmpData->length != pNodeData->length)
+ return false;
+ return !rtl_ustr_compare_WithLength( pCmpData->buffer,
+ pCmpData->length,
+ pNodeData->buffer,
+ pNodeData->length);
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString Node::getName() const
+{
+ return info.getName();
+}
+//-----------------------------------------------------------------------------
+
+configmgr::node::Attributes Node::getAttributes() const
+{
+ if(this->isFragmentRoot())
+ {
+ return this->getTreeFragment()->getAttributes();
+ }
+ else
+ {
+ return info.getNodeInfoAttributes();
+ }
+}
+//-----------------------------------------------------------------------------
+
+bool Node::isDefault() const
+{
+ return info.isDefault();
+}
+//-----------------------------------------------------------------------------
+
+bool Node::isFragmentRoot() const
+{
+ return !info.parent;
+}
+#if OSL_DEBUG_LEVEL > 0
+//-----------------------------------------------------------------------------
+Node * Node::getParentNode()
+{
+ return info.parent ? this - info.parent : NULL;
+}
+//-----------------------------------------------------------------------------
+
+Node const * Node::getParentNode() const
+{
+ return info.parent ? this - info.parent : NULL;
+}
+#endif
+//-----------------------------------------------------------------------------
+static sal_uInt16 getFragmentIndex(Node const * pNode)
+{
+ sal_uInt16 result = 0;
+ while (sal_uInt16 step = pNode->info.parent)
+ {
+ result = result + step;
+ pNode -= step;
+ }
+ return result;
+}
+//-----------------------------------------------------------------------------
+
+TreeFragment * Node::getTreeFragment()
+{
+ void * pRoot = this - getFragmentIndex(this);
+
+ void * pFrag = static_cast<char*>(pRoot) - offsetof(TreeFragment,nodes);
+
+ return static_cast<TreeFragment *>(pFrag);
+}
+//-----------------------------------------------------------------------------
+
+TreeFragment const * Node::getTreeFragment() const
+{
+ void const * pRoot = this - getFragmentIndex(this);
+
+ void const * pFrag = static_cast<char const*>(pRoot) - offsetof(TreeFragment,nodes);
+
+ return static_cast<TreeFragment const *>(pFrag);
+}
+
+Node * Node::getSubnode(rtl::OUString const & name) {
+ if (isGroup()) {
+ return group.getChild(name);
+ } else if (isSet()) {
+ TreeFragment * element = set.getElement(name);
+ return element == 0 ? 0 : element->getRootNode();
+ } else {
+ OSL_ASSERT(false);
+ return 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+ } // namespace sharable
+//-----------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/tree/nodeconverter.cxx b/configmgr/source/tree/nodeconverter.cxx
new file mode 100644
index 000000000000..0bf9950acb3e
--- /dev/null
+++ b/configmgr/source/tree/nodeconverter.cxx
@@ -0,0 +1,213 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodeconverter.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "builddata.hxx"
+#include "nodeconverter.hxx"
+#include "treenodefactory.hxx"
+#include <osl/diagnose.h>
+
+
+//..........................................................................
+namespace configmgr
+{
+
+//==========================================================================
+//= OTreeNodeConverter
+//==========================================================================
+OTreeNodeConverter::OTreeNodeConverter()
+: m_rFactory( getDefaultTreeNodeFactory() )
+{
+}
+
+std::auto_ptr<ISubtree> OTreeNodeConverter::createCorrespondingNode(SubtreeChange const& _rChange)
+{
+ std::auto_ptr<ISubtree> aRet;
+
+ //if ( isLocalizedValueSet(aSubtree) ) { ... } else - no special case yet
+ if (_rChange.isSetNodeChange())
+ {
+ aRet = nodeFactory().createSetNode(_rChange.getNodeName(),
+ _rChange.getElementTemplateName(),
+ _rChange.getElementTemplateModule(),
+ _rChange.getAttributes());
+ }
+ else
+ {
+ aRet = nodeFactory().createGroupNode(_rChange.getNodeName(),
+ _rChange.getAttributes());
+ }
+ return aRet;
+}
+
+//--------------------------------------------------------------------------
+std::auto_ptr<ValueNode> OTreeNodeConverter::createCorrespondingNode(ValueChange const& _rChange)
+{
+ // DEFAULT-TODO
+ OSL_ENSURE(_rChange.getValueType().getTypeClass() != uno::TypeClass_VOID, "Losing type information converting change to value");
+
+ std::auto_ptr<ValueNode> aRet;
+ if (_rChange.getNewValue().hasValue())
+ aRet = nodeFactory().createValueNode(_rChange.getNodeName(), _rChange.getNewValue(), _rChange.getAttributes());
+
+ else
+ aRet = nodeFactory().createNullValueNode(_rChange.getNodeName(), _rChange.getValueType(), _rChange.getAttributes());
+
+ OSL_ENSURE(aRet.get() && aRet->isValid(), "Could not create corresponding value node");
+
+ return aRet;
+}
+
+//==========================================================================
+//= ONodeConverter
+//==========================================================================
+class ONodeConverter : public ChangeTreeModification
+{
+ OTreeNodeConverter& m_rFactory;
+ std::auto_ptr<INode> m_pNode;
+
+public:
+ explicit
+ ONodeConverter(OTreeNodeConverter& rFactory)
+ : m_rFactory(rFactory)
+ {
+ }
+
+ virtual void handle(ValueChange& aValueNode);
+ virtual void handle(AddNode& aAddNode);
+ virtual void handle(RemoveNode& aRemoveNode);
+ virtual void handle(SubtreeChange& aSubtree);
+
+ std::auto_ptr<INode> result() { return m_pNode; }
+
+};
+//==========================================================================
+//= OCreateSubtreeAction
+//==========================================================================
+//= creates a subtree out of a changes list
+//==========================================================================
+struct OCreateSubtreeAction : public ChangeTreeModification
+{
+ ISubtree& m_rTree;
+ OTreeNodeConverter& m_rNodeFactory;
+
+public:
+ OCreateSubtreeAction(ISubtree& _rTree, OTreeNodeConverter& rFactory)
+ :m_rTree(_rTree)
+ ,m_rNodeFactory(rFactory) {}
+
+ void handle(ValueChange& aValueNode);
+ void handle(AddNode& aAddNode);
+ void handle(RemoveNode& aRemoveNode);
+ void handle(SubtreeChange& aSubtree);
+};
+
+
+//--------------------------------------------------------------------------
+std::auto_ptr<ISubtree> OTreeNodeConverter::createCorrespondingTree(SubtreeChange& _rChange)
+{
+ std::auto_ptr<ISubtree> pBaseTree = this->createCorrespondingNode(_rChange);
+
+ OCreateSubtreeAction aNextLevel(*pBaseTree,*this);
+ _rChange.forEachChange(aNextLevel);
+
+ return pBaseTree;
+}
+
+//--------------------------------------------------------------------------
+void ONodeConverter::handle(ValueChange& aValueNode)
+{
+ m_pNode = base_ptr(m_rFactory.createCorrespondingNode(aValueNode));
+}
+
+//--------------------------------------------------------------------------
+void ONodeConverter::handle(AddNode& aAddNode)
+{
+ rtl::Reference< data::TreeSegment > seg(aAddNode.getNewTree());
+ m_pNode = data::convertTree(seg.is() ? seg->fragment : 0, true);
+}
+
+//--------------------------------------------------------------------------
+void ONodeConverter::handle(RemoveNode& /*aRemoveNode*/)
+{
+ m_pNode.reset();
+}
+
+//--------------------------------------------------------------------------
+void ONodeConverter::handle(SubtreeChange& aSubtree)
+{
+ m_pNode = base_ptr(m_rFactory.createCorrespondingNode(aSubtree));
+}
+
+//--------------------------------------------------------------------------
+void OCreateSubtreeAction::handle(ValueChange& _rChange)
+{
+ // create a node by a ValueChange
+ std::auto_ptr<ValueNode> pNode = m_rNodeFactory.createCorrespondingNode(_rChange);
+
+ m_rTree.addChild(base_ptr(pNode));
+}
+
+//--------------------------------------------------------------------------
+void OCreateSubtreeAction::handle(SubtreeChange& _rChange)
+{
+ // create a node from a SubtreeChange (recursively)
+ std::auto_ptr<ISubtree> pNode = m_rNodeFactory.createCorrespondingTree(_rChange);
+
+ // add it to the tree
+ m_rTree.addChild(base_ptr(pNode));
+}
+
+//--------------------------------------------------------------------------
+void OCreateSubtreeAction::handle(RemoveNode& _rChange)
+{
+ { (void)_rChange; }
+ // we have nothing to do
+ OSL_ENSURE(!m_rTree.getChild(_rChange.getNodeName()), "Removed node found in tree being built");
+}
+
+//--------------------------------------------------------------------------
+void OCreateSubtreeAction::handle(AddNode& _rChange)
+{
+ // free the node and add it to the subtree
+ rtl::Reference< data::TreeSegment > aNewNode = _rChange.getNewTree();
+ m_rTree.addChild(data::convertTree(aNewNode.is() ? aNewNode->fragment : 0, true));
+}
+
+
+//--------------------------------------------------------------------------
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+
diff --git a/configmgr/source/tree/nodevisitor.cxx b/configmgr/source/tree/nodevisitor.cxx
new file mode 100644
index 000000000000..1cda7071252d
--- /dev/null
+++ b/configmgr/source/tree/nodevisitor.cxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodevisitor.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_configmgr.hxx"
+#include "sal/config.h"
+
+#include "osl/diagnose.h"
+
+#include "flags.hxx"
+#include "nodevisitor.hxx"
+#include "node.hxx"
+#include "treefragment.hxx"
+
+namespace configmgr { namespace data {
+
+NodeVisitor::~NodeVisitor() {}
+
+bool NodeVisitor::visitNode(sharable::Node * node) {
+ switch (node->info.type & data::Type::mask_nodetype) {
+ case data::Type::nodetype_value:
+ return handle(&node->value);
+ case data::Type::nodetype_group:
+ return handle(&node->group);
+ case data::Type::nodetype_set:
+ return handle(&node->set);
+ default:
+ OSL_ASSERT(false);
+ return false;
+ }
+}
+
+bool NodeVisitor::visitChildren(sharable::GroupNode * node) {
+ for (sharable::Node * child = node->getFirstChild(); child != 0;
+ child = node->getNextChild(child))
+ {
+ if (visitNode(child)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool NodeVisitor::handle(sharable::Node *) {
+ return false;
+}
+
+bool NodeVisitor::handle(sharable::ValueNode * node) {
+ return handle(sharable::node(node));
+}
+
+bool NodeVisitor::handle(sharable::GroupNode * node) {
+ return handle(sharable::node(node));
+}
+
+bool NodeVisitor::handle(sharable::SetNode * node) {
+ return handle(sharable::node(node));
+}
+
+SetVisitor::~SetVisitor() {}
+
+bool SetVisitor::visitTree(sharable::TreeFragment * tree) {
+ return handle(tree);
+}
+
+bool SetVisitor::visitElements(sharable::SetNode * node) {
+ for (sharable::TreeFragment * element = node->getFirstElement();
+ element != 0; element = node->getNextElement(element))
+ {
+ if (handle(element)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SetVisitor::handle(sharable::TreeFragment * tree) {
+ return visitNode(tree->getRootNode());
+}
+
+} }
diff --git a/configmgr/source/tree/subtree.hxx b/configmgr/source/tree/subtree.hxx
new file mode 100644
index 000000000000..4189ecc967cd
--- /dev/null
+++ b/configmgr/source/tree/subtree.hxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: subtree.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_SUBTREE_HXX
+#define CONFIGMGR_SUBTREE_HXX
+
+#include "valuenode.hxx"
+#include <rtl/ustring.hxx>
+
+#include <memory>
+#include <set>
+#include <vector>
+
+namespace configmgr
+{
+ // List sorted by name for binary search
+ class ChildListSet {
+ std::vector< INode* > m_aChildList;
+
+ ChildListSet(ChildListSet const&);
+ ChildListSet& operator=(ChildListSet const& aSet);
+ public:
+ std::vector< INode* >::iterator begin() const { return const_cast<std::vector< INode* >*>(&m_aChildList)->begin(); }
+ std::vector< INode* >::iterator end() const { return const_cast<std::vector< INode* >*>(&m_aChildList)->end(); }
+ INode *erase(INode *pNode);
+ std::vector< INode* >::iterator find(INode *pNode) const;
+ std::pair<std::vector< INode* >::iterator, bool> insert(INode *aInsert);
+
+ ChildListSet() : m_aChildList(0) {}
+ ChildListSet(ChildListSet const&, treeop::DeepChildCopy);
+ ~ChildListSet();
+ };
+
+// Inner Node
+ class Subtree : public ISubtree
+ {
+ ChildListSet m_aChildren;
+ virtual INode* doGetChild(rtl::OUString const& name) const;
+
+ public:
+ Subtree(){}
+ Subtree(const rtl::OUString& _rName,
+ const node::Attributes& _rAttrs)
+ :ISubtree(_rName, _rAttrs){};
+
+ Subtree(const ISubtree& _rOther, treeop::NoChildCopy)
+ : ISubtree(_rOther), m_aChildren(){};
+
+ Subtree(const rtl::OUString& _rName,
+ const rtl::OUString& _rTemplateName, const rtl::OUString& _rTemplateModule,
+ const node::Attributes& _rAttrs)
+ :ISubtree(_rName, _rTemplateName, _rTemplateModule, _rAttrs){};
+
+ Subtree(const Subtree& _rOther, treeop::DeepChildCopy _dc)
+ : ISubtree(_rOther), m_aChildren(_rOther.m_aChildren,_dc){}
+
+ virtual INode* addChild(std::auto_ptr<INode> node); // takes ownership
+ virtual ::std::auto_ptr<INode> removeChild(rtl::OUString const& name);
+
+ virtual std::auto_ptr<INode> clone() const;
+
+// Iteration support
+ virtual void forEachChild(NodeAction& anAction) const;
+ virtual void forEachChild(NodeModification& anAction);
+ };
+
+
+
+ // to search in ChildListSet a value
+ class SearchNode : public INode
+ {
+ public:
+ SearchNode(rtl::OUString const& aName);
+ virtual ~SearchNode();
+ virtual std::auto_ptr<INode> clone() const;
+
+// double dispatch support
+ virtual void dispatch(NodeAction& /*anAction*/) const { }
+ virtual void dispatch(NodeModification& /*anAction*/) { }
+ };
+
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/tree/treeactions.cxx b/configmgr/source/tree/treeactions.cxx
new file mode 100644
index 000000000000..08cf8e3cabf5
--- /dev/null
+++ b/configmgr/source/tree/treeactions.cxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treeactions.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "treeactions.hxx"
+#include <osl/diagnose.h>
+
+
+//..........................................................................
+namespace configmgr
+{
+
+//==========================================================================
+//= OChangeActionCounter
+//==========================================================================
+
+//--------------------------------------------------------------------------
+void OChangeActionCounter::handle(ValueChange const& /*aValueNode*/){ ++nValues; }
+
+//--------------------------------------------------------------------------
+void OChangeActionCounter::handle(AddNode const& /*aAddNode*/){ ++nAdds; }
+
+//--------------------------------------------------------------------------
+void OChangeActionCounter::handle(RemoveNode const& /*aRemoveNode*/){ ++nRemoves; }
+
+//--------------------------------------------------------------------------
+void OChangeActionCounter::handle(SubtreeChange const& aSubtree)
+{
+ applyToChildren(aSubtree);
+}
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+
diff --git a/configmgr/source/tree/treechangefactory.cxx b/configmgr/source/tree/treechangefactory.cxx
new file mode 100644
index 000000000000..aa7a23e6108b
--- /dev/null
+++ b/configmgr/source/tree/treechangefactory.cxx
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treechangefactory.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "treechangefactory.hxx"
+#include "change.hxx"
+#include "configpath.hxx"
+
+namespace configmgr
+{
+//= dummy helpe ============================================================
+bool isGenericSetElementType(rtl::OUString const& _aElementType)
+{
+ return !! _aElementType.equals( getGenericSetElementType() );
+}
+
+bool isDummySetElementModule(rtl::OUString const& _aElementModule)
+{
+ return !! _aElementModule.equals( getDummySetElementModule() );
+}
+
+rtl::OUString getGenericSetElementType()
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*"));
+}
+
+rtl::OUString getDummySetElementModule()
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cfg:dummy-change"));
+}
+
+//= static default ============================================================
+OTreeChangeFactory& getDefaultTreeChangeFactory()
+{
+ static OTreeChangeFactory aDefaultFactory;
+ return aDefaultFactory;
+}
+
+//= SubtreeChanges ============================================================
+std::auto_ptr<SubtreeChange> OTreeChangeFactory::createDummyChange(
+ rtl::OUString const& _aName, rtl::OUString const& _aElementTypeName)
+{
+ std::auto_ptr<SubtreeChange> pResult;
+
+ if (_aElementTypeName.getLength() == 0)
+ {
+ pResult.reset( new SubtreeChange(_aName, node::Attributes()) );
+ }
+ else
+ {
+ pResult.reset( new SubtreeChange(_aName,
+ _aElementTypeName,
+ getDummySetElementModule(),
+ node::Attributes()) );
+ }
+ return pResult;
+}
+
+//-----------------------------------------------
+std::auto_ptr<SubtreeChange> OTreeChangeFactory::createSetNodeChange(
+ rtl::OUString const& _aName,
+ rtl::OUString const& _aTemplateName,
+ rtl::OUString const& _aTemplateModule,
+ node::Attributes _aAttrs,
+ bool _bToDefault)
+{
+ return std::auto_ptr<SubtreeChange>(new SubtreeChange(_aName,
+ _aTemplateName,
+ _aTemplateModule,
+ _aAttrs,_bToDefault));
+}
+//-----------------------------------------------
+
+//= Set Changes ============================================================
+std::auto_ptr<AddNode> OTreeChangeFactory::createAddNodeChange(
+ rtl::Reference< data::TreeSegment > const & _aNewTree,
+ rtl::OUString const& _aName,
+ bool _bToDefault)
+{
+ return std::auto_ptr<AddNode>(new AddNode(_aNewTree,_aName,_bToDefault));
+}
+
+//-----------------------------------------------
+std::auto_ptr<RemoveNode> OTreeChangeFactory::createRemoveNodeChange(
+ rtl::OUString const& _aName,
+ bool _bToDefault)
+{
+ return std::auto_ptr<RemoveNode>(new RemoveNode(_aName,_bToDefault));
+}
+
+//-----------------------------------------------
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/tree/treefragment.cxx b/configmgr/source/tree/treefragment.cxx
new file mode 100644
index 000000000000..9a8dc46fbd7b
--- /dev/null
+++ b/configmgr/source/tree/treefragment.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treefragment.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "treefragment.hxx"
+#include "utility.hxx"
+#include "attributes.hxx"
+#include <rtl/ustring.hxx>
+
+// memset
+#include <string.h>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace sharable
+ {
+//-----------------------------------------------------------------------------
+rtl::OUString TreeFragment::getName() const
+{
+ return rtl::OUString(this->header.name);
+}
+
+void TreeFragment::setName(rtl::OUString const & name) {
+ rtl_uString * old = header.name;
+ header.name = acquireString(name);
+ rtl_uString_release(old);
+}
+
+//-----------------------------------------------------------------------------
+
+bool TreeFragment::isNamed(rtl::OUString const & _aName) const
+{
+ // TODO: optimize comparison
+ return !!(this->getName() == _aName);
+}
+//-----------------------------------------------------------------------------
+
+bool TreeFragment::hasDefaultsAvailable() const
+{
+ return (this->header.state & data::State::flag_default_avail) || isDefault();
+}
+//-----------------------------------------------------------------------------
+
+
+bool TreeFragment::isDefault() const
+{
+ return (this->header.state & data::State::mask_state) == data::State::defaulted;
+}
+//-----------------------------------------------------------------------------
+
+bool TreeFragment::isNew() const
+{
+ return (this->header.state & data::State::mask_state) == data::State::added;
+}
+//-----------------------------------------------------------------------------
+
+configmgr::node::Attributes TreeFragment::getAttributes() const
+{
+ configmgr::node::Attributes aResult;
+
+ switch (this->header.state & data::State::mask_state)
+ {
+ case data::State::merged: aResult.setState(configmgr::node::isMerged); break;
+ case data::State::defaulted: aResult.setState(configmgr::node::isDefault); break;
+ case data::State::replaced: aResult.setState(configmgr::node::isReplaced); break;
+ case data::State::added: aResult.setState(configmgr::node::isAdded); break;
+ default: OSL_ASSERT(false); break; // not reachable
+ }
+
+ aResult.setRemovability(!!(this->header.state & data::State::flag_removable),
+ !!(this->header.state & data::State::flag_mandatory));
+
+
+ OSL_ASSERT( header.count != 0 );
+ NodeInfo const & aRootNodeInfo = this->nodes[0].info;
+
+ aResult.setAccess( !!(this->header.state & data::State::flag_readonly),
+ !!(aRootNodeInfo.flags & data::Flags::finalized) );
+
+ aResult.setLocalized ( !!(aRootNodeInfo.flags & data::Flags::localized));
+
+ return aResult;
+}
+
+TreeFragment *TreeFragment::allocate(sal_uInt32 nFragments)
+{
+ sal_uInt32 nSize = sizeof(TreeFragment) + sizeof(Node) * (nFragments-1);
+ sal_uInt8 *pMem = new sal_uInt8 [nSize];
+ memset (pMem, 0, nSize);
+ return reinterpret_cast<TreeFragment *>(pMem);
+}
+
+void TreeFragment::free_shallow(TreeFragment *pFragment )
+{
+ delete[] (sal_uInt8 *) pFragment;
+}
+
+//-----------------------------------------------------------------------------
+ } // namespace sharable
+//-----------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/tree/treenodefactory.cxx b/configmgr/source/tree/treenodefactory.cxx
new file mode 100644
index 000000000000..169edd26cb8f
--- /dev/null
+++ b/configmgr/source/tree/treenodefactory.cxx
@@ -0,0 +1,113 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treenodefactory.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "treenodefactory.hxx"
+#include "valuenode.hxx"
+#include "subtree.hxx"
+#include "treechangefactory.hxx"
+#include "configpath.hxx"
+
+namespace configmgr
+{
+
+//= static default ============================================================
+OTreeNodeFactory& getDefaultTreeNodeFactory()
+{
+ static OTreeNodeFactory aDefaultFactory;
+ return aDefaultFactory;
+}
+
+//= ValueNodes ============================================================
+
+std::auto_ptr<ValueNode> OTreeNodeFactory::createValueNode(
+ rtl::OUString const& aName,
+ uno::Any const& aValue,
+ node::Attributes _aAttrs)
+{
+ OSL_ENSURE(aValue.hasValue(), "OTreeNodeFactory: Creating a value node having no type");
+ return std::auto_ptr<ValueNode>( new ValueNode(aName, aValue, _aAttrs) );
+}
+
+//-----------------------------------------------
+
+std::auto_ptr<ValueNode> OTreeNodeFactory::createValueNode(
+ rtl::OUString const& aName,
+ uno::Any const& aValue,
+ uno::Any const& aDefault,
+ node::Attributes _aAttrs)
+{
+ OSL_ENSURE(aValue.hasValue() || aDefault.hasValue(), "OTreeNodeFactory: Creating a value node having no type");
+ return std::auto_ptr<ValueNode>( new ValueNode(aName, aValue, aDefault, _aAttrs) );
+}
+
+
+//-----------------------------------------------
+
+std::auto_ptr<ValueNode> OTreeNodeFactory::createNullValueNode(
+ rtl::OUString const& aName,
+ uno::Type const& aType,
+ node::Attributes _aAttrs)
+{
+ OSL_ENSURE(aType.getTypeClass() != uno::TypeClass_VOID, "OTreeNodeFactory: Creating a value node having VOID type");
+ return std::auto_ptr<ValueNode>( new ValueNode(aName, aType, _aAttrs) );
+}
+
+
+//-----------------------------------------------
+
+std::auto_ptr<ISubtree> OTreeNodeFactory::createGroupNode(
+ rtl::OUString const& aName,
+ node::Attributes _aAttrs)
+{
+ return std::auto_ptr<ISubtree>( new Subtree(aName, _aAttrs) );
+}
+
+
+//-----------------------------------------------
+
+std::auto_ptr<ISubtree> OTreeNodeFactory::createSetNode(
+ rtl::OUString const& aName,
+ rtl::OUString const& _rTemplateName,
+ rtl::OUString const& _rTemplateModule,
+ node::Attributes _aAttrs)
+{
+ return std::auto_ptr<ISubtree>( new Subtree(aName, _rTemplateName, _rTemplateModule, _aAttrs) );
+}
+
+//-----------------------------------------------
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/tree/treesegment.cxx b/configmgr/source/tree/treesegment.cxx
new file mode 100644
index 000000000000..5abbc20dc796
--- /dev/null
+++ b/configmgr/source/tree/treesegment.cxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treesegment.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_configmgr.hxx"
+#include "sal/config.h"
+
+#include <memory>
+
+#include "osl/diagnose.h"
+#include "rtl/ref.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "builddata.hxx"
+#include "treesegment.hxx"
+
+namespace configmgr { namespace data {
+
+rtl::Reference< TreeSegment > TreeSegment::create(
+ std::auto_ptr< INode > tree, rtl::OUString const & type)
+{
+ rtl::Reference< TreeSegment > r;
+ if (tree.get() != 0) {
+ std::auto_ptr< sharable::TreeFragment > p(
+ buildElementTree(*tree, type, false));
+ r = new TreeSegment(p.get());
+ p.release();
+ }
+ return r;
+}
+
+rtl::Reference< TreeSegment > TreeSegment::create(
+ rtl::OUString const & name, std::auto_ptr< INode > tree)
+{
+ rtl::Reference< TreeSegment > r;
+ if (tree.get() != 0) {
+ std::auto_ptr< sharable::TreeFragment > p(
+ buildTree(name, *tree, false));
+ r = new TreeSegment(p.get());
+ p.release();
+ }
+ return r;
+}
+
+rtl::Reference< TreeSegment > TreeSegment::create(
+ sharable::TreeFragment * tree)
+{
+ rtl::Reference< TreeSegment > r;
+ if (tree != 0) {
+ std::auto_ptr< sharable::TreeFragment > p(data::buildTree(tree));
+ r = new TreeSegment(p.get());
+ p.release();
+ }
+ return r;
+}
+
+TreeSegment::TreeSegment(sharable::TreeFragment * tree): fragment(tree) {
+ OSL_ASSERT(tree != 0);
+}
+
+TreeSegment::~TreeSegment() {
+ destroyTree(fragment);
+}
+
+} }
diff --git a/configmgr/source/tree/updatehelper.cxx b/configmgr/source/tree/updatehelper.cxx
new file mode 100644
index 000000000000..5d07d3289e3d
--- /dev/null
+++ b/configmgr/source/tree/updatehelper.cxx
@@ -0,0 +1,625 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: updatehelper.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "updatehelper.hxx"
+#include "change.hxx"
+#include "nodeconverter.hxx"
+#include "treeactions.hxx"
+#include "treechangefactory.hxx"
+#include "treenodefactory.hxx"
+
+// -----------------------------------------------------------------------------
+#include "node.hxx"
+#include "treefragment.hxx"
+#include "builddata.hxx"
+#include "nodevisitor.hxx"
+// -----------------------------------------------------------------------------
+#include "tracer.hxx"
+#include <osl/diagnose.h>
+
+
+//..........................................................................
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+//==========================================================================
+//= AdjustUpdate
+//==========================================================================
+//= This class tests changes on an existing tree and drops them if they
+//= are not need anymore or alters add nodes in node changes and vice versa
+//==========================================================================
+class AdjustUpdate : ChangeTreeModification
+{
+ SubtreeChange& m_rChangeList; // list which containes changes merged with the existing nodes
+ sharable::Node * m_refNode; // reference node needed for merging
+ OTreeNodeConverter m_aNodeConverter;
+public:
+ static bool adjust(SubtreeChange& _rResultTree, SubtreeChange& _aUpdateTree,
+ sharable::Node * targetNode)
+ {
+ return AdjustUpdate(_rResultTree, targetNode).impl_adjust(_aUpdateTree);
+ }
+ static bool adjust(SubtreeChange& _rResultTree, SubtreeChange& _aUpdateTree,
+ sharable::Node * targetNode,
+ OTreeNodeFactory& _rNodeFactory)
+ {
+ return AdjustUpdate(_rResultTree, targetNode, _rNodeFactory).impl_adjust(_aUpdateTree);
+ }
+private:
+ AdjustUpdate(SubtreeChange& rList, sharable::Node * node)
+ :m_rChangeList(rList)
+ ,m_refNode(node)
+ ,m_aNodeConverter()
+ {}
+
+ AdjustUpdate(SubtreeChange& rList, sharable::Node * node, OTreeNodeFactory& _rNodeFactory)
+ :m_rChangeList(rList)
+ ,m_refNode(node)
+ ,m_aNodeConverter(_rNodeFactory)
+ {}
+
+ void handle(ValueChange& aValueNode);
+ void handle(AddNode& aAddNode);
+ void handle(RemoveNode& aRemoveNode);
+ void handle(SubtreeChange& aSubtree);
+
+ bool impl_adjust(SubtreeChange& _aUpdateTree);
+private:
+ // ensuring the correct state
+ bool checkNode() const;
+};
+
+// --------------------------------- ApplyUpdate ---------------------------------
+
+class ApplyUpdate : public ChangeTreeModification
+{
+ sharable::Node * m_aCurrentNode;
+public:
+ ApplyUpdate(sharable::Node * _aNode)
+ : m_aCurrentNode(_aNode)
+ {}
+
+ void handle(ValueChange& aValueNode);
+ void handle(AddNode& aAddNode);
+ void handle(RemoveNode& aRemoveNode);
+ void handle(SubtreeChange& aSubtree);
+};
+//--------------------------------------------------------------------------
+class ApplyValueChange
+{
+ static
+ void adjust(uno::Any& aActual, uno::Any const& aTarget);
+
+public:
+ static
+ void apply(ValueChange& _rValueChange, sharable::ValueNode * valueNode);
+};
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+// apply a already matching set of changes to the target tree
+ void applyUpdateToTree(SubtreeChange& _anUpdateTree, sharable::Node * _aRootNode)
+ {
+ ApplyUpdate aUpdater(_aRootNode);
+ _anUpdateTree.forEachChange(aUpdater);
+ }
+//--------------------------------------------------------------------------
+// apply a set of changes to the target tree
+ void applyUpdateWithAdjustmentToTree(SubtreeChange& _anUpdateTree, sharable::Node * _aRootNode)
+ {
+ // POST: pSubtree = pSubtree + aChangeList
+ SubtreeChange aActualChanges(_anUpdateTree, treeop::NoChildCopy());
+
+ if ( AdjustUpdate::adjust(aActualChanges,_anUpdateTree, _aRootNode) )
+ {
+ applyUpdateToTree(aActualChanges, _aRootNode);
+ }
+ _anUpdateTree.swap(aActualChanges);
+
+ }
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+static inline
+rtl::OUString getNodeName(INode const & _aNode)
+{
+ return _aNode.getName();
+}
+//--------------------------------------------------------------------------
+
+static inline
+rtl::OUString getChangeNodeName(Change const & _aChange)
+{
+ return _aChange.getNodeName();
+}
+//--------------------------------------------------------------------------
+
+bool AdjustUpdate::impl_adjust(SubtreeChange& _aUpdateTree)
+{
+ // first check the changes
+ this->applyToChildren(_aUpdateTree);
+
+ // now check whether there are real modifications
+ OChangeActionCounter aChangeCounter;
+ aChangeCounter.handle(m_rChangeList);
+ CFG_TRACE_INFO_NI("cache manager: counted changes : additions: %i , removes: %i, value changes: %i", aChangeCounter.nAdds, aChangeCounter.nRemoves, aChangeCounter.nValues);
+
+ return !! aChangeCounter.hasChanges();
+}
+// -----------------------------------------------------------------------------
+
+inline bool AdjustUpdate::checkNode() const
+{
+ // Change a Value
+ OSL_ENSURE(m_refNode != 0, "AdjustUpdate: no data");
+
+ return m_refNode != 0;
+}
+//--------------------------------------------------------------------------
+
+void AdjustUpdate::handle(ValueChange& _rChange)
+{
+ if (checkNode())
+ {
+ // We need to find the element in the tree
+ sharable::Node * childNode = m_refNode->getSubnode(getChangeNodeName(_rChange));
+
+ // We have a node so we can keep the Change and the values do not differ
+ if (childNode != 0)
+ {
+ bool bIsValue = childNode->isValue();
+ OSL_ENSURE(bIsValue, "AdjustUpdate : node must be a value node!");
+
+ if (bIsValue && _rChange.isChange())
+ {
+ std::auto_ptr<Change> pChange( new ValueChange(_rChange) );
+ m_rChangeList.addChange(pChange);
+ }
+ }
+ else
+ {
+ std::auto_ptr<ValueNode> pNode = m_aNodeConverter.createCorrespondingNode(_rChange);
+
+ OSL_ENSURE(m_rChangeList.isSetNodeChange(), "Adding a new value to a non-set node");
+ rtl::OUString sTypeName = m_rChangeList.getElementTemplateName();
+
+ rtl::Reference< data::TreeSegment > aNewTree = data::TreeSegment::create(base_ptr(pNode),sTypeName);
+ // add the tree to the change list
+ std::auto_ptr<Change> pChange( new AddNode( aNewTree,_rChange.getNodeName(), _rChange.isToDefault()) );
+ m_rChangeList.addChange(pChange);
+ }
+ }
+}
+//--------------------------------------------------------------------------
+
+void AdjustUpdate::handle(SubtreeChange& _rChange)
+{
+ if (checkNode())
+ {
+ // We need to find the element in the tree
+ sharable::Node * childNode = m_refNode->getSubnode(getChangeNodeName(_rChange));
+
+ // if there is a node we continue
+ if (childNode != 0)
+ {
+ bool bIsSubtree = childNode->isGroup() || childNode->isSet();
+ OSL_ENSURE(bIsSubtree, "AdjustUpdate : node must be a inner node!");
+
+ if (bIsSubtree)
+ {
+ // generate a new change
+ std::auto_ptr<SubtreeChange> pChange( new SubtreeChange(_rChange, treeop::NoChildCopy()) );
+
+ // recurse
+ if ( adjust(*pChange,_rChange,childNode,m_aNodeConverter.nodeFactory()) )
+ m_rChangeList.addChange(base_ptr(pChange));
+ }
+ else
+ OSL_ENSURE(false, "Inconsistent data: Subtree Change is merged into non-subtree node.");
+ }
+ // otherwise we have to create the node
+ else
+ {
+ std::auto_ptr<ISubtree> pNode = m_aNodeConverter.createCorrespondingTree(_rChange);
+ OSL_ASSERT(pNode.get() != NULL);
+
+ // set the level
+ pNode->setLevels(treeop::ALL_LEVELS,treeop::ALL_LEVELS);
+
+ OSL_ENSURE(m_rChangeList.isSetNodeChange(), "Adding a new value to a non-set node");
+ rtl::OUString sTypeName = m_rChangeList.getElementTemplateName();
+
+ rtl::Reference< data::TreeSegment > aNewTree = data::TreeSegment::create(base_ptr(pNode), sTypeName);
+
+ // add the tree to the change list
+ std::auto_ptr<Change> pChange( new AddNode(aNewTree,_rChange.getNodeName(), _rChange.isToDefault()) );
+ m_rChangeList.addChange( pChange );
+ }
+ }
+}
+//--------------------------------------------------------------------------
+
+void AdjustUpdate::handle(RemoveNode& _rChange)
+{
+ if (checkNode())
+ {
+ // We need to find the element in the tree
+ sharable::Node * childNode = m_refNode->getSubnode(getChangeNodeName(_rChange));
+
+ // only if there is a node, we will keep the change
+ if (childNode != 0)
+ {
+ // generate a new change
+ std::auto_ptr<Change> pChange( new RemoveNode(_rChange.getNodeName(),_rChange.isToDefault()) );
+ m_rChangeList.addChange(pChange);
+ }
+ }
+}
+//--------------------------------------------------------------------------
+
+void AdjustUpdate::handle(AddNode& _rChange)
+{
+ if (checkNode())
+ {
+ // We need to find the element in the tree
+ sharable::Node * childNode = m_refNode->getSubnode(getChangeNodeName(_rChange));
+
+ rtl::Reference< data::TreeSegment > aNewNode = _rChange.getNewTree();
+ std::auto_ptr<AddNode> pChange( new AddNode(aNewNode,_rChange.getNodeName(),_rChange.isToDefault()) );
+ if (childNode != 0)
+ {
+ pChange->setReplacing();
+ }
+ m_rChangeList.addChange(base_ptr(pChange));
+ }
+}
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+inline
+void ApplyValueChange::adjust(uno::Any& aActual, uno::Any const& aTarget)
+{
+ // If set - it should already match
+ OSL_ASSERT(!aActual.hasValue() || aTarget == aActual);
+ aActual = aTarget;
+}
+
+//--------------------------------------------------------------------------
+// _rValueChange.applyTo(_aValueNode)
+void ApplyValueChange::apply(ValueChange& _rValueChange, sharable::ValueNode * valueNode)
+{
+ switch (_rValueChange.getMode())
+ {
+ case ValueChange::wasDefault:
+ OSL_ASSERT(valueNode->info.isDefault());
+
+ case ValueChange::changeValue:
+ adjust( _rValueChange.m_aOldValue, valueNode->getValue());
+ valueNode->setValue(_rValueChange.getNewValue());
+ break;
+
+ case ValueChange::setToDefault:
+ adjust(_rValueChange.m_aOldValue, valueNode->getValue());
+ adjust(_rValueChange.m_aValue, valueNode->getDefaultValue());
+ valueNode->setToDefault();
+ break;
+
+ case ValueChange::changeDefault:
+ adjust(_rValueChange.m_aOldValue, valueNode->getDefaultValue());
+ valueNode->changeDefault(_rValueChange.getNewValue());
+ break;
+
+ default:
+ OSL_ENSURE(0, "Unknown mode found for ValueChange");
+ break;
+ }
+}
+//--------------------------------------------------------------------------
+
+void ApplyUpdate::handle(ValueChange& _rChange)
+{
+ // Change a Value
+ OSL_ENSURE(m_aCurrentNode != NULL,"Cannot apply ValueChange without node");
+
+ sharable::Node * childNode = m_aCurrentNode->getSubnode(getChangeNodeName(_rChange));
+ OSL_ENSURE(childNode != 0, "Cannot apply Change: No node to change");
+
+ sharable::ValueNode * aValueAddr = childNode->valueData();
+ OSL_ENSURE(aValueAddr != NULL,"Cannot apply ValueChange: Node is not a value");
+
+ if (aValueAddr != NULL)
+ ApplyValueChange::apply(_rChange,aValueAddr);
+}
+//--------------------------------------------------------------------------
+
+void ApplyUpdate::handle(SubtreeChange& _rChange)
+{
+ // handle traversion
+ OSL_ENSURE(m_aCurrentNode != NULL,"Cannot apply SubtreeChange without node");
+
+ sharable::Node * childNode = m_aCurrentNode->getSubnode(getChangeNodeName(_rChange));
+ OSL_ENSURE(childNode != 0, "Cannot apply Change: No node to change");
+
+ OSL_ENSURE( childNode->isGroup() || childNode->isSet(),
+ "Cannot Apply SubtreeChange: Node is not an inner node");
+
+ if (childNode != 0)
+ {
+ childNode->info.markAsDefault( _rChange.isToDefault() );
+
+ sharable::Node * aOldNode = m_aCurrentNode;
+ m_aCurrentNode = childNode;
+
+ _rChange.forEachChange(*this);
+
+ m_aCurrentNode = aOldNode;
+ }
+}
+//--------------------------------------------------------------------------
+
+void ApplyUpdate::handle(AddNode& _rChange)
+{
+ OSL_ENSURE(m_aCurrentNode != NULL,"Cannot apply AddNode without node");
+
+ sharable::SetNode * aSetNodeAddr = sharable::SetNode::from(m_aCurrentNode);
+ OSL_ENSURE(aSetNodeAddr != NULL,"Cannot apply AddNode: Node is not a set node");
+
+ // Add a new element
+ if (aSetNodeAddr != NULL)
+ {
+ if (_rChange.isReplacing())
+ {
+ sharable::TreeFragment * old = aSetNodeAddr->removeElement(getChangeNodeName(_rChange));
+ OSL_ASSERT(old != 0);
+ _rChange.takeReplacedTree(data::TreeSegment::create(old));
+ }
+
+ sharable::TreeFragment * aNewAddress = data::buildTree(_rChange.getNewTree()->fragment);
+ OSL_ENSURE(aNewAddress != NULL, "ApplyUpdate: AddNode: could not create new element");
+
+ aSetNodeAddr->addElement(aNewAddress);
+
+ _rChange.setInsertedAddress( aNewAddress );
+ }
+}
+//--------------------------------------------------------------------------
+
+void ApplyUpdate::handle(RemoveNode& _rChange)
+{
+ OSL_ENSURE(m_aCurrentNode != NULL,"Cannot apply RemoveNode without node");
+
+ sharable::SetNode * aSetNodeAddr = sharable::SetNode::from(m_aCurrentNode);
+ OSL_ENSURE(aSetNodeAddr != NULL,"Cannot apply RemoveNode: Node is not a set node");
+
+ // Remove an element
+ if (aSetNodeAddr != NULL)
+ {
+ sharable::TreeFragment * old = aSetNodeAddr->removeElement(getChangeNodeName(_rChange));
+ OSL_ASSERT(old != 0);
+ _rChange.takeRemovedTree(data::TreeSegment::create(old));
+ }
+}
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ struct ForwardTreeDifferenceBuilder : NodeAction
+ {
+ protected:
+ SubtreeChange& m_rChangeList;
+ sharable::Node * m_cacheNode;
+
+ public:
+ ForwardTreeDifferenceBuilder(SubtreeChange& rList, sharable::Node * cacheNode)
+ : m_rChangeList(rList)
+ , m_cacheNode(cacheNode)
+ {
+ }
+
+ virtual void handle(ValueNode const& _aNewNode)
+ {
+ sharable::Node * childNode = m_cacheNode->getSubnode(getNodeName(_aNewNode));
+ if (childNode != 0)
+ {
+ sharable::ValueNode * valueNode = childNode->valueData();
+
+ OSL_ENSURE(valueNode != 0, "TreeDifferenceBuilder: node must be a value node!");
+
+ // if the values differ add a new change
+ if (_aNewNode.getValue() != valueNode->getValue())
+ {
+ bool bNewDefault = _aNewNode.isDefault();
+ bool bOldDefault = valueNode->info.isDefault();
+
+ ValueChange::Mode eMode;
+ if (bNewDefault)
+ if (bOldDefault)
+ eMode = ValueChange::changeDefault;
+ else
+ eMode = ValueChange::setToDefault;
+ else
+ if (bOldDefault)
+ eMode = ValueChange::wasDefault;
+ else
+ eMode = ValueChange::changeValue;
+
+ std::auto_ptr<Change> pChange(
+ new ValueChange(_aNewNode.getName(), _aNewNode.getAttributes(), eMode,
+ _aNewNode.getValue(), valueNode->getValue()) );
+
+ m_rChangeList.addChange(pChange);
+ }
+ }
+ }
+ virtual void handle(ISubtree const& _aNewNode)
+ {
+ sharable::Node * childNode = m_cacheNode->getSubnode(getNodeName(_aNewNode));
+
+ if (childNode != 0)
+ {
+ OSL_ENSURE( childNode->isGroup() || childNode->isSet(),
+ "ForwardTreeDifferenceBuilder: Node must be an inner node");
+
+ // generate a new change
+ std::auto_ptr<SubtreeChange> pNewChange( new SubtreeChange(_aNewNode) );
+
+ // .. and recurse
+ ForwardTreeDifferenceBuilder aNextLevel(*pNewChange, childNode);
+ aNextLevel.applyToChildren(_aNewNode);
+
+ // now count if there are any changes
+ OChangeActionCounter aCounter;
+ aCounter.applyToChange(*pNewChange);
+
+ if (aCounter.hasChanges())
+ m_rChangeList.addChange(base_ptr(pNewChange));
+ }
+ else if (m_cacheNode != 0 && m_cacheNode->isSet())
+ {
+ // Subtree not in Cache, add in TreeChangeList
+ // SubtreeChange* pChange = new SubtreeChange(_rSubtree);
+ OSL_ENSURE(m_rChangeList.isSetNodeChange(), "Found newly added node in non-set node");
+ rtl::OUString sTypeName = m_rChangeList.getElementTemplateName();
+
+ std::auto_ptr<INode> pSubtree( _aNewNode.clone() );
+ rtl::Reference< data::TreeSegment > aNewTree = data::TreeSegment::create(pSubtree,sTypeName);
+
+ std::auto_ptr<Change> pAdd(new AddNode(aNewTree, _aNewNode.getName(), _aNewNode.isDefault()));
+
+ m_rChangeList.addChange(pAdd);
+ }
+ else
+ OSL_ENSURE(false, "Found newly added node in group");
+
+ }
+ };
+// -----------------------------------------------------------------------------
+
+class BackwardTreeDifferenceBuilder: public data::SetVisitor {
+public:
+ BackwardTreeDifferenceBuilder(SubtreeChange & list, ISubtree const * node):
+ m_changeList(list), m_newNode(node) {}
+
+ void applyToChildren(sharable::Node * cacheNode) {
+ OSL_ASSERT(cacheNode != 0);
+ if (cacheNode->isGroup()) {
+ OSL_ASSERT(!m_changeList.isSetNodeChange());
+ visitChildren(&cacheNode->group);
+ } else if (cacheNode->isSet()) {
+ OSL_ASSERT(m_changeList.isSetNodeChange());
+ visitElements(&cacheNode->set);
+ } else {
+ OSL_ASSERT(false);
+ }
+ }
+
+private:
+ using NodeVisitor::handle;
+
+ virtual bool handle(sharable::Node * node) {
+ OSL_ASSERT(!node->isValue());
+ INode const * newChild = m_newNode->getChild(node->getName());
+ ISubtree const * newTree = newChild == 0 ? 0 : newChild->asISubtree();
+ if (newTree != 0) {
+ // Traverse down to next change:
+ Change * change = m_changeList.getChange(node->getName());
+ std::auto_ptr< Change > newChange;
+ SubtreeChange * groupChange = 0;
+ if (change == 0) {
+ groupChange = new SubtreeChange(*newTree);
+ newChange.reset(groupChange);
+ } else {
+ groupChange = dynamic_cast< SubtreeChange * >(change);
+ OSL_ASSERT(groupChange != 0);
+ }
+ if (groupChange != 0) {
+ BackwardTreeDifferenceBuilder(*groupChange, newTree).
+ applyToChildren(node);
+ if (newChange.get() != 0) {
+ // Now count if there are any real changes:
+ OChangeActionCounter counter;
+ counter.applyToChange(*newChange);
+ if (counter.hasChanges()) {
+ m_changeList.addChange(newChange);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ virtual bool handle(sharable::ValueNode *) {
+ return false;
+ }
+
+ virtual bool handle(sharable::TreeFragment * tree) {
+ INode const * newElement = m_newNode->getChild(tree->getName());
+ if (newElement == 0) {
+ // Remove node:
+ std::auto_ptr< Change > remove(
+ new RemoveNode(tree->getName(), tree->isNew()));
+ m_changeList.addChange(remove);
+ return false;
+ } else {
+ // Handle the root node:
+ return SetVisitor::handle(tree);
+ }
+ }
+
+ SubtreeChange & m_changeList;
+ ISubtree const * m_newNode;
+};
+
+//--------------------------------------------------------------------------
+
+// apply a set of changes to the target tree, return true, if there are changes found
+ bool createUpdateFromDifference(SubtreeChange& _rResultingUpdateTree, sharable::Node * existingData, ISubtree const & _aNewData)
+ {
+ OSL_ENSURE(existingData != 0, "Trying to create diffrence for empty data");
+ // create the differences
+ ForwardTreeDifferenceBuilder aForwardTreeDifference(_rResultingUpdateTree, existingData);
+ aForwardTreeDifference.applyToChildren(_aNewData);
+
+ BackwardTreeDifferenceBuilder aBackwardTreeDifference(_rResultingUpdateTree, & _aNewData);
+ aBackwardTreeDifference.applyToChildren(existingData);
+
+ return true;
+ }
+//--------------------------------------------------------------------------
+
+//..........................................................................
+} // namespace configmgr
+//..........................................................................
+
+
diff --git a/configmgr/source/treecache/cacheaccess.cxx b/configmgr/source/treecache/cacheaccess.cxx
new file mode 100644
index 000000000000..ba59185d8213
--- /dev/null
+++ b/configmgr/source/treecache/cacheaccess.cxx
@@ -0,0 +1,355 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cacheaccess.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "cacheaccess.hxx"
+#include "tracer.hxx"
+#include "configpath.hxx"
+
+namespace configmgr
+{
+// -------------------------------------------------------------------------
+
+CacheClientAccess::CacheClientAccess(ConfigChangeBroadcastHelper * _pBroadcastHelper)
+: m_pBroadcastHelper( _pBroadcastHelper )
+{
+}
+// -------------------------------------------------------------------------
+
+CacheClientAccess::~CacheClientAccess()
+{
+ OSL_ENSURE(!m_pBroadcastHelper, "Forgot to dispose broadcast helper");
+}
+// -------------------------------------------------------------------------
+
+ConfigChangeBroadcastHelper * CacheClientAccess::releaseBroadcaster()
+{
+ ConfigChangeBroadcastHelper * pRet = m_pBroadcastHelper;
+ m_pBroadcastHelper = NULL;
+ return pRet;
+}
+
+// -------------------------------------------------------------------------
+
+bool CacheClientAccess::hasModule(const configuration::AbsolutePath& _aLocation)
+{
+ return this->m_aData.hasModule(_aLocation.getModuleName());
+}
+// -------------------------------------------------------------------------
+
+bool CacheClientAccess::hasModuleDefaults(configuration::AbsolutePath const& _aLocation)
+{
+ return this->m_aData.hasModuleDefaults(_aLocation.getModuleName());
+}
+// -------------------------------------------------------------------------
+void CacheClientAccess::attachModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aModule)
+{
+ this->m_aData.attachModule(_aLocation, _aModule);
+}
+// -------------------------------------------------------------------------
+
+sharable::Node * CacheClientAccess::acquireNode(configuration::AbsolutePath const& rLocation )
+{
+ CFG_TRACE_INFO("CacheClientAccess: Requesting data for path '%s'", OUSTRING2ASCII(rLocation.toString()) );
+
+ sharable::Node * aResult = this->m_aData.acquireNode(rLocation);
+
+ if (aResult != NULL)
+ {
+ CFG_TRACE_INFO_NI("- Data is available - returning Subtree");
+ }
+ else
+ CFG_TRACE_INFO_NI("- Data is not available - returning NULL");
+
+ return aResult;
+}
+// -------------------------------------------------------------------------
+
+oslInterlockedCount CacheClientAccess::releaseNode( configuration::AbsolutePath const& rLocation )
+{
+ CFG_TRACE_INFO("Tree Info: Releasing subtree data for path '%s'", OUSTRING2ASCII(rLocation.toString()) );
+
+ oslInterlockedCount nRet = this->m_aData.releaseModule(rLocation.getModuleName(),false);
+
+ return nRet;
+}
+// -----------------------------------------------------------------------------
+
+void CacheClientAccess::applyUpdate(backend::UpdateInstance & _aUpdate) SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ CFG_TRACE_INFO("CacheClientAccess: Merging changes into subtree '%s'", OUSTRING2ASCII(_aUpdate.root().toString()) );
+
+ this->m_aData.applyUpdate(_aUpdate );
+}
+
+// -----------------------------------------------------------------------------
+sharable::Node * CacheClientAccess::findInnerNode( configuration::AbsolutePath const& aComponentName )
+{
+ sharable::Node * node = m_aData.getNode(aComponentName);
+ return node == 0 || node->isValue() ? 0 : node;
+}
+
+// -------------------------------------------------------------------------
+
+bool CacheClientAccess::insertDefaults( backend::NodeInstance const & _aDefaultData ) SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ CFG_TRACE_INFO("Tree Info: Adding default data for path '%s'", OUSTRING2ASCII(_aDefaultData.root().toString()) );
+
+ return this->m_aData.insertDefaults(_aDefaultData);
+}
+// -------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+
+CacheLoadingAccess::CacheLoadingAccess()
+: m_aDeadModules()
+{
+}
+// -------------------------------------------------------------------------
+
+CacheLoadingAccess::~CacheLoadingAccess()
+{
+}
+
+// -------------------------------------------------------------------------
+
+/// gets a tree reference for the given path if exists
+sharable::TreeFragment * CacheLoadingAccess::getTreeAddress(rtl::OUString const & _aModule)
+{
+ return this->m_aData.getTreeAddress(_aModule);
+}
+// -------------------------------------------------------------------------
+void CacheLoadingAccess::createModule(rtl::OUString const & _aModule)
+{
+ this->m_aData.createModule(_aModule);
+}
+// -------------------------------------------------------------------------
+bool CacheLoadingAccess::hasModule(rtl::OUString const & _aModule)
+{
+ return this->m_aData.hasModule(_aModule);
+}
+// -------------------------------------------------------------------------
+
+bool CacheLoadingAccess::acquireModule(rtl::OUString const & _aModule)
+{
+ CFG_TRACE_INFO("Tree Info: Requesting data for module '%s'", OUSTRING2ASCII(_aModule));
+
+ if (this->m_aData.acquireModule(_aModule))
+ {
+ m_aDeadModules.erase( _aModule );
+ CFG_TRACE_INFO_NI("- Data is available - returning Subtree");
+ return true;
+ }
+ else
+ {
+ CFG_TRACE_INFO_NI("- Data is not available - returning NULL");
+ return false;
+ }
+}
+// -------------------------------------------------------------------------
+
+oslInterlockedCount CacheLoadingAccess::releaseModule( rtl::OUString const & _aModule )
+{
+ CFG_TRACE_INFO("Tree Info: Releasing data for module '%s'", OUSTRING2ASCII(_aModule) );
+
+ oslInterlockedCount nRet = this->m_aData.releaseModule(_aModule,true); // keep
+ if (nRet == 0)
+ {
+ m_aDeadModules[ _aModule ] = TimeStamp::getCurrentTime();
+ CFG_TRACE_INFO_NI("- Last reference released - marking data for cleanup");
+ }
+
+ return nRet;
+}
+// -----------------------------------------------------------------------------
+
+bool CacheLoadingAccess::isEmpty()
+{
+ ExtendedCacheData::ModuleList& rModules = this->m_aData.accessModuleList();
+
+ bool bRet = rModules.empty();
+
+ if (bRet) // while we are at it - clean up
+ m_aDeadModules.clear();
+
+ return bRet;
+}
+// -------------------------------------------------------------------------
+
+sharable::TreeFragment * CacheLoadingAccess::addComponentData( backend::ComponentInstance const & _aComponentInstance,
+ bool _bIncludesDefaults
+ ) SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ CFG_TRACE_INFO("CacheLoadingAccess: Adding component data for module '%s' : %s",
+ OUSTRING2ASCII(_aComponentInstance.component()),
+ _bIncludesDefaults ? "Data includes defaults." : "Data does not include defaults." );
+
+ sharable::TreeFragment * aResult = this->m_aData.addComponentData(_aComponentInstance, _bIncludesDefaults);
+ if (aResult != NULL)
+ {
+ m_aDeadModules.erase( _aComponentInstance.component() );
+ CFG_TRACE_INFO_NI("- Data added successfully - returning Subtree");
+ }
+ else
+ CFG_TRACE_INFO_NI("- Data not added - returning NULL");
+
+ return aResult;
+}
+// -------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+void CacheLoadingAccess::addChangesToPending( backend::ConstUpdateInstance const& _anUpdate ) SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ // NICE: m_pPending[_rLocation] += pSubtreeChange;
+ CFG_TRACE_INFO("CacheLoadingAccess: Adding pending changes for subtree '%s'", OUSTRING2ASCII(_anUpdate.root().toString()) );
+
+ this->m_aData.addPending(_anUpdate);
+}
+
+// -----------------------------------------------------------------------------
+std::auto_ptr<SubtreeChange> CacheLoadingAccess::releasePendingChanges(rtl::OUString const& _aComponentName)
+{
+ CFG_TRACE_INFO("Tree Info: extract pending changes from subtree '%s'", OUSTRING2ASCII(_aComponentName) );
+ return this->m_aData.releasePending(_aComponentName);
+}
+
+// -----------------------------------------------------------------------------
+bool CacheLoadingAccess::findPendingChangedModules( std::vector< rtl::OUString > & _rPendingList )
+{
+ this->m_aData.findPendingModules(_rPendingList);
+ return !_rPendingList.empty();
+}
+
+// -------------------------------------------------------------------------
+
+TimeStamp CacheLoadingAccess::collectDisposeList(std::vector< rtl::Reference<CacheLine> > & _rList, TimeStamp const & _aLimitTime, TimeInterval const & _aDelay)
+{
+ TimeStamp aRetTime = TimeStamp::never();
+
+ CFG_TRACE_INFO("Tree Info: Collecting disposable module trees for cleanup" );
+
+ ExtendedCacheData::ModuleList& rActiveModules = this->m_aData.accessModuleList();
+
+ std::map< rtl::OUString, TimeStamp >::iterator it = m_aDeadModules.begin();
+
+ while (it != m_aDeadModules.end())
+ {
+ std::map< rtl::OUString, TimeStamp >::iterator current = it;
+ // increment here, as we may later erase(current)
+ ++it;
+
+#if (OSL_DEBUG_LEVEL > 0) || defined _DBG_UTIL || defined CFG_TRACE_ENABLE
+ rtl::OUString sCurrentName( current->first );
+#endif
+ TimeStamp aExpireTime = current->second + _aDelay;
+ if (aExpireTime <= _aLimitTime)
+ {
+ ExtendedCacheData::ModuleList::iterator itModule = rActiveModules.find( current->first );
+
+ if (itModule != rActiveModules.end())
+ {
+ rtl::Reference<CacheLine> xModule = itModule->second;
+
+ bool bHandled = false;
+
+ if (!xModule.is())
+ {
+ CFG_TRACE_ERROR_NI("- Unexpected: Module '%s' is NULL in active module list", OUSTRING2ASCII(sCurrentName) );
+ bHandled = true;
+ }
+ else if (xModule->clientReferences() != 0)// at least in temporary use
+ {
+ OSL_ENSURE( false, "Referenced entry in dead module list");
+
+ CFG_TRACE_WARNING_NI("- Module '%s' in (temporary ?) use - rescheduling", OUSTRING2ASCII(sCurrentName) );
+ bHandled = false; // still remove from the lists
+ }
+ else if (m_aData.hasPending(current->first))
+ {
+ CFG_TRACE_WARNING_NI("- Module '%s' has pending changes - rescheduling disposal", OUSTRING2ASCII(sCurrentName) );
+ bHandled = false;
+ }
+ else // now this really can be disposed
+ {
+ CFG_TRACE_INFO_NI("- Removing module '%s' for disposal", OUSTRING2ASCII(sCurrentName) );
+
+ // It really is ok to dispose this entry
+ _rList.push_back(xModule);
+
+ bHandled = true;
+ }
+
+
+ if (bHandled)
+ {
+ // really remove
+ rActiveModules.erase(itModule);
+ m_aDeadModules.erase(current);
+ }
+ else
+ {
+ // reschedule
+ TimeStamp aRetryTime = _aLimitTime + _aDelay;
+ OSL_ASSERT(aRetryTime > _aLimitTime);
+
+ current->second = _aLimitTime; // ?
+ if (aRetryTime < aRetTime)
+ aRetTime = aRetryTime;
+ }
+ }
+ else
+ {
+ // obsolete dispose list entry - discard
+ OSL_ENSURE( false, "Obsolete entry in dead module list");
+
+ CFG_TRACE_WARNING_NI("- Module '%s' not found any more - obsolete entry in dead module list", OUSTRING2ASCII(sCurrentName) );
+
+ m_aDeadModules.erase(current);
+ }
+ }
+ else // consider for restart time
+ {
+ CFG_TRACE_INFO_NI("- Module '%s' has not expired yet - rescheduling", OUSTRING2ASCII(sCurrentName) );
+
+ if (aExpireTime < aRetTime)
+ aRetTime = aExpireTime;
+ }
+ }
+
+ OSL_ASSERT(aRetTime > _aLimitTime);
+ return aRetTime;
+}
+// -------------------------------------------------------------------------
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/treecache/cacheaccess.hxx b/configmgr/source/treecache/cacheaccess.hxx
new file mode 100644
index 000000000000..25c8ffff8e06
--- /dev/null
+++ b/configmgr/source/treecache/cacheaccess.hxx
@@ -0,0 +1,160 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cacheaccess.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CACHEACCESS_HXX
+#define CONFIGMGR_CACHEACCESS_HXX
+
+#include "cachedata.hxx"
+#include "timestamp.hxx"
+#include "utility.hxx"
+#include <boost/utility.hpp>
+#include <osl/mutex.hxx>
+#ifndef _CONFIGMGR_UTILITY_HXX_
+#include <utility.hxx>
+#endif
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+
+namespace configmgr
+{
+////////////////////////////////////////////////////////////////////////////////
+ class ConfigChangeBroadcastHelper;
+ namespace backend
+ {
+ class CacheController;
+ }
+//-----------------------------------------------------------------------------
+
+ class CacheClientAccess: private boost::noncopyable, public salhelper::SimpleReferenceObject
+ {
+ private:
+ CacheData m_aData;
+
+ ConfigChangeBroadcastHelper* m_pBroadcastHelper;
+ public:
+ explicit
+ CacheClientAccess(ConfigChangeBroadcastHelper* _pBroadcastHelper);
+
+ ~CacheClientAccess();
+
+ /// gets a helper to broadcast changes for
+ ConfigChangeBroadcastHelper * getBroadcaster() const
+ { return m_pBroadcastHelper; }
+
+ /// removes an existing broadcast helper
+ ConfigChangeBroadcastHelper * releaseBroadcaster();
+
+ // attach a module with a given name
+ void attachModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aModule);
+ /// check if the given module exists already (and is not empty)
+ bool hasModule(const configuration::AbsolutePath& _aLocation);
+ /// checks if the given module exists and has defaults available
+ bool hasModuleDefaults(configuration::AbsolutePath const & _aLocation);
+
+ /// retrieve the subtree at _aPath (maybe if it has the requested defaults) and clientAcquire() it
+ sharable::Node * acquireNode(configuration::AbsolutePath const& _aPath);
+
+ /** add or merge the given subtree at the given location,
+ return <TRUE/> if the tree has defaults then
+ */
+ bool insertDefaults( backend::NodeInstance const & _aDefaultData ) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ /// clientRelease() the tree at aComponentName, and return the resulting reference count
+ oslInterlockedCount releaseNode( configuration::AbsolutePath const& _aPath );
+
+ /// retrieve the given subtree without changing its ref count
+ sharable::Node * findInnerNode(configuration::AbsolutePath const& _aPath );
+
+ /// merge the given change list into this tree - reflects old data to _aUpdate
+ void applyUpdate(backend::UpdateInstance & _aUpdate) SAL_THROW((com::sun::star::uno::RuntimeException));
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+ class CacheLoadingAccess: private boost::noncopyable, public salhelper::SimpleReferenceObject
+ {
+ public:
+ friend class backend::CacheController;
+ private:
+ friend class CacheDisposeScheduler;
+
+ ExtendedCacheData m_aData;
+ std::map< rtl::OUString, TimeStamp > m_aDeadModules; /// list of nodes which are registered for throwing away
+ public:
+ explicit
+ CacheLoadingAccess();
+ ~CacheLoadingAccess();
+
+ /// gets a tree address for the given module if it exists
+ sharable::TreeFragment * getTreeAddress(rtl::OUString const & _aModule);
+
+ /// return TRUE if there is no data (left) in this object's cache data
+ bool isEmpty();
+
+ // create a module with a given name
+ void createModule(rtl::OUString const & _aModule);
+ /// check if the given module exists already (and is not empty)
+ bool hasModule(rtl::OUString const & _aLocation);
+ /// retrieve the subtree at aComponentName and clientAcquire() it, true if succeeded
+ bool acquireModule(rtl::OUString const & _aModule);
+
+ /// clientRelease() the tree at aComponentName, and return the resulting reference count
+ oslInterlockedCount releaseModule( rtl::OUString const & _aModule );
+
+ /// collect the modules that can be disposed now (i.e. released after _rLimitReleaseTime)
+ TimeStamp collectDisposeList(std::vector< rtl::Reference<CacheLine> > & _rList,
+ TimeStamp const & _aLimitTime,
+ TimeInterval const & _aDelay);
+
+ // stuff that is particular for CacheLoadingAccess
+ /** add the given subtree at the given location,
+ return the tree that is then pertinent and clientAcquire() it once
+ */
+ sharable::TreeFragment * addComponentData( backend::ComponentInstance const & _aComponentInstance,
+ bool _bIncludesDefaults
+ ) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ /// merge the given change list into the pending change list of this tree
+ void addChangesToPending( backend::ConstUpdateInstance const& _anUpdate ) SAL_THROW((com::sun::star::uno::RuntimeException));
+ /// retrieve accumulated pending changes
+ std::auto_ptr<SubtreeChange> releasePendingChanges(rtl::OUString const& _aModule);
+
+ /// find the modules having pending changes
+ bool findPendingChangedModules( std::vector< rtl::OUString > & _rPendingList );
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/treecache/cachecontroller.cxx b/configmgr/source/treecache/cachecontroller.cxx
new file mode 100644
index 000000000000..765f7df8d2e2
--- /dev/null
+++ b/configmgr/source/treecache/cachecontroller.cxx
@@ -0,0 +1,719 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachecontroller.cxx,v $
+ * $Revision: 1.21 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "cachecontroller.hxx"
+#include "disposetimer.hxx"
+#include "cachewritescheduler.hxx"
+#include "builddata.hxx"
+#include "localizedtreeactions.hxx"
+#include "configexcept.hxx"
+#include "tracer.hxx"
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <osl/diagnose.h>
+#include <rtl/logfile.hxx>
+
+#ifndef _CONFIGMGR_BOOTSTRAP_HXX
+#include "bootstrap.hxx"
+#endif
+
+
+#define RTL_LOGFILE_OU2A(rtlOUString) (::rtl::OUStringToOString((rtlOUString), RTL_TEXTENCODING_ASCII_US).getStr())
+
+namespace configmgr
+{
+// -------------------------------------------------------------------------
+ namespace backend
+ {
+
+static const rtl::OUString kCacheDisposeDelay(
+ RTL_CONSTASCII_USTRINGPARAM( CONTEXT_ITEM_PREFIX_ "CacheDisposeDelay"));
+static const rtl::OUString kCacheDisposeInterval(
+ RTL_CONSTASCII_USTRINGPARAM( CONTEXT_ITEM_PREFIX_ "CacheDisposeInterval"));
+static const rtl::OUString kCacheWriteInterval(
+ RTL_CONSTASCII_USTRINGPARAM( CONTEXT_ITEM_PREFIX_ "CacheWriteInterval"));
+// -------------------------------------------------------------------------
+
+OTreeDisposeScheduler* CacheController::createDisposer(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _xContext)
+{
+ ContextReader aReader(_xContext);
+ sal_uInt32 c_nDefaultDelay = 0;
+ rtl::OUString sDefaultDelay;
+ aReader.getBestContext()->getValueByName(kCacheDisposeDelay) >>= sDefaultDelay;
+ c_nDefaultDelay = sDefaultDelay.toInt32()==0?900:sDefaultDelay.toInt32() ;
+
+ sal_uInt32 c_nDefaultInterval = 0;
+ rtl::OUString sDefaultInterval;
+ aReader.getBestContext()->getValueByName(kCacheDisposeInterval) >>= sDefaultInterval;
+ c_nDefaultInterval = sDefaultInterval.toInt32()==0?60:sDefaultInterval.toInt32();
+
+ TimeInterval aDelay(c_nDefaultDelay);
+ TimeInterval aInterval(c_nDefaultInterval);
+
+ return new OTreeDisposeScheduler(*this, aDelay, aInterval);
+}
+
+// -----------------------------------------------------------------------------
+
+OCacheWriteScheduler* CacheController::createCacheWriter(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _xContext)
+{
+ ContextReader aReader(_xContext);
+ sal_uInt32 c_nDefaultInterval=0;
+ rtl::OUString sDefaultInterval;
+ aReader.getBestContext()->getValueByName(kCacheWriteInterval) >>= sDefaultInterval;
+ c_nDefaultInterval = sDefaultInterval.toInt32()==0?2:sDefaultInterval.toInt32();
+
+ TimeInterval aInterval(c_nDefaultInterval);
+ return new OCacheWriteScheduler(*this, aInterval);
+}
+// ----------------------------------------------------------------------------
+
+rtl::Reference<CacheLoadingAccess> CacheController::getCacheAlways(RequestOptions const & _aOptions)
+{
+ rtl::Reference<CacheLoadingAccess> aResult = m_aCacheMap.get(_aOptions);
+ if (!aResult.is())
+ {
+ rtl::Reference<CacheLoadingAccess> aNewCache( new CacheLoadingAccess() );
+ aResult = m_aCacheMap.insert(_aOptions,aNewCache);
+ }
+ return aResult;
+}
+
+// -------------------------------------------------------------------------
+
+// disposing
+// -------------------------------------------------------------------------
+void CacheController::disposeAll(bool _bFlushRemainingUpdates)
+{
+ CFG_TRACE_INFO("CacheController: Disposing all data" );
+ CacheMap::Map aReleaseList;
+
+ if (m_pDisposer)
+ {
+ m_pDisposer->stopAndClearTasks();
+ m_aCacheMap.swap(aReleaseList); // move data out of m_aCacheMap and empty m_aCacheMap
+ }
+
+ if (_bFlushRemainingUpdates)
+ {
+ for (CacheMap::Map::iterator it = aReleaseList.begin(); it != aReleaseList.end(); ++it)
+ saveAllPendingChanges(it->second,it->first);
+ }
+ // free all the trees
+ aReleaseList.clear();
+}
+
+// -------------------------------------------------------------------------
+void CacheController::dispose() SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ UnoApiLock aLock;
+
+ CFG_TRACE_INFO("CacheController: dispose()" );
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::CacheController", "jb99855", "configmgr: CacheController::dispose(), disable lazy write cache.");
+ m_bDisposing = true; // we are in dispose, handling of errors must be something different.
+
+ // writing of pending updates
+ this->flushCacheWriter();
+
+ // cleaning the cache
+ this->disposeAll(true);
+}
+
+// -------------------------------------------------------------------------
+CacheController::CacheController(rtl::Reference< backend::IMergedDataProvider > const & _xBackend,
+ const uno::Reference<uno::XComponentContext>& xContext)
+: m_aNotifier()
+, m_xBackend(_xBackend)
+, m_aCacheMap()
+, m_aTemplates()
+, m_pDisposer()
+, m_pCacheWriter()
+, m_bDisposing(false)
+{
+ m_pDisposer = this->createDisposer(xContext);
+ m_pCacheWriter = this->createCacheWriter(xContext);
+}
+
+// -------------------------------------------------------------------------
+CacheController::~CacheController()
+{
+ OSL_ENSURE(m_bDisposing == true, "CacheController::dispose() wasn't called, something went wrong.");
+
+ delete m_pDisposer;
+ delete m_pCacheWriter;
+}
+
+// -------------------------------------------------------------------------
+void CacheController::closeModules(std::vector< rtl::Reference<CacheLine> > & _aList, RequestOptions const & _aOptions)
+{
+ //Remove listeners from Backend as module no longer in cache
+ for (sal_uInt32 i =0; i < _aList.size(); ++i)
+ {
+ rtl::OUString aModuleName = _aList[i]->getModuleName();
+ ComponentRequest aRequest(aModuleName, _aOptions);
+ m_xBackend->removeRequestListener(this, aRequest);
+ }
+}
+// -------------------------------------------------------------------------
+#if 0
+static
+std::auto_ptr<ISubtree> reduceSubtreeForLocale(std::auto_ptr<ISubtree> _pSubtree, RequestOptions const & _aOptions)
+{
+ OSL_ENSURE(!_pSubtree.get() || !isLocalizedValueSet(*_pSubtree), "Unexpected node. Expecting a subtree, Found a single localized value.");
+
+ std::auto_ptr<ISubtree> aRet;
+
+ std::auto_ptr<INode> aReduced = reduceExpandedForLocale(_pSubtree, _aOptions.getLocale());
+
+ if (aReduced.get())
+ {
+ if (ISubtree* pReduced =aReduced->asISubtree())
+ {
+ aRet.reset(pReduced);
+ aReduced.release();
+ }
+ else
+ {
+ OSL_ENSURE(false, "Tree unexpectedly reduced to non-tree");
+ }
+ }
+ else
+ OSL_ENSURE(!_pSubtree.get(), "Tree unexpectedly reduced to nothing");
+
+ return aRet;
+}
+#endif
+
+// -------------------------------------------------------------------------
+sharable::TreeFragment * CacheController::loadComponent(ComponentRequest const & _aRequest)
+{
+ CFG_TRACE_INFO("CacheController: loading component '%s'", OUSTRING2ASCII(_aRequest.getComponentName()));
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::CacheController", "jb99855", "configmgr: CacheController::loadComponent()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "component: %s", RTL_LOGFILE_OU2A(_aRequest.getComponentName().toString()) );
+
+ rtl::Reference<CacheLoadingAccess> aCache = this->getCacheAlways(_aRequest.getOptions());
+
+ OSL_ENSURE(aCache.is(), "Could not create CacheAccess");
+
+ sharable::TreeFragment * aTemplateResultAdddress;
+
+ OSL_ENSURE(!_aRequest.isForcingReload(),"CacheController: No support for forced requests");
+ if (aCache->hasModule(_aRequest.getComponentName()))
+ {
+ CFG_TRACE_INFO_NI("CacheController: found node in cache");
+ if (_aRequest.getOptions().isRefreshEnabled())
+ {
+ refreshComponent(_aRequest);
+ }
+ aCache->acquireModule(_aRequest.getComponentName());
+ }
+ else
+ {
+ ResultHolder< ComponentInstance > aData = this->loadDirectly(_aRequest,true);
+
+ CFG_TRACE_INFO_NI("CacheController: adding loaded data to the cache");
+
+ aCache->createModule(_aRequest.getComponentName());
+
+ aCache->addComponentData(aData.instance(), true);
+ if (aData.instance().templateData().get()!=NULL)
+ aTemplateResultAdddress = addTemplates(aData.mutableInstance().componentTemplateData() );
+
+ // notify the new data to all clients
+ m_aNotifier.notifyCreated(_aRequest);
+ }
+
+ return aCache->getTreeAddress(_aRequest.getComponentName());
+}
+// -------------------------------------------------------------------------
+
+ResultHolder< ComponentInstance > CacheController::getComponentData(ComponentRequest const & _aRequest,
+ bool _bAddListenter ) SAL_THROW((com::sun::star::uno::Exception))
+{
+ // TODO: Insert check here, if the data is in the cache already - and then clone
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::CacheController", "jb99855", "configmgr: CacheController::getComponentData()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "component: %s", RTL_LOGFILE_OU2A(_aRequest.getComponentName().toString()) );
+
+ ResultHolder< ComponentInstance > aRet = this->loadDirectly(_aRequest, _bAddListenter);
+
+ return aRet;
+}
+// -------------------------------------------------------------------------
+
+ResultHolder< NodeInstance > CacheController::getDefaultData(NodeRequest const & _aRequest) SAL_THROW((com::sun::star::uno::Exception))
+{
+ // TODO: Insert check here, if the data is in the cache already - and then clone
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::CacheController", "jb99855", "configmgr: CacheController::getDefaultData()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "path: %s", RTL_LOGFILE_OU2A(_aRequest.getPath().toString()) );
+
+ ResultHolder< NodeInstance > aRet = this->loadDefaultsDirectly(_aRequest);
+
+ return aRet;
+}
+// -------------------------------------------------------------------------
+
+configuration::AbsolutePath CacheController::encodeTemplateLocation(const rtl::OUString& _rName, const rtl::OUString &_rModule) const
+{
+ namespace Path = configuration::Path;
+
+// static const
+// Component aTemplateRoot = wrapSimpleName(rtl::OUString::createFromAscii("org.openoffice.Templates"));
+
+ Path::Component aTemplateModule = Path::wrapSimpleName(_rModule);
+ Path::Component aTemplateName = Path::wrapSimpleName(_rName);
+
+ Path::Rep aResult(aTemplateName);
+ aResult.prepend(aTemplateModule);
+// aResult.prepend(aTemplateRoot);
+
+ return configuration::AbsolutePath(aResult);
+}
+// -------------------------------------------------------------------------
+#if 0
+static
+configuration::AbsolutePath templateLoadLocation(const configuration::AbsolutePath &_rTemplateLocation)
+{
+ namespace Path = configuration::Path;
+
+ static const
+ Path::Component aTemplateRoot = Path::wrapSimpleName(rtl::OUString::createFromAscii("org.openoffice.Templates"));
+
+ Path::Rep aResult(_rTemplateLocation.rep());
+ aResult.prepend(aTemplateRoot);
+
+ return configuration::AbsolutePath(aResult);
+}
+#endif
+// -------------------------------------------------------------------------
+std::auto_ptr<ISubtree> CacheController::loadTemplateData(TemplateRequest const & _aTemplateRequest) SAL_THROW((com::sun::star::uno::Exception))
+{
+ std::auto_ptr<ISubtree> aMultiTemplates;
+ ResultHolder< TemplateInstance > aTemplateInstance = m_xBackend->getTemplateData(_aTemplateRequest);
+ if (aTemplateInstance.is())
+ {
+ OSL_ASSERT(aTemplateInstance->name().getLength() == 0);
+ if (ISubtree * pMulti = aTemplateInstance->data()->asISubtree())
+ {
+ aTemplateInstance.releaseAndClear();
+ aMultiTemplates.reset(pMulti);
+ }
+ else
+ OSL_ENSURE(false,"Requested multiple templates, got non-subtree node");
+ }
+ else
+ OSL_ENSURE(false,"Requested configuration template does not exist");
+
+ if (aMultiTemplates.get() == NULL)
+ {
+ CFG_TRACE_ERROR_NI("CacheController: could not load the templates");
+ throw uno::Exception(::rtl::OUString::createFromAscii("The template description could not be loaded. The template does not exist."), NULL);
+ }
+
+ return aMultiTemplates;
+}
+// -------------------------------------------------------------------------
+sharable::TreeFragment * CacheController::addTemplates ( backend::ComponentDataStruct const & _aComponentInstance )
+{
+ OSL_PRECOND(_aComponentInstance.data.get(), "addTemplates: Data must not be NULL");
+ rtl::OUString aModuleName = _aComponentInstance.name;
+ m_aTemplates.createModule(aModuleName);
+ configuration::AbsolutePath aTemplateLocation = configuration::AbsolutePath::makeModulePath(_aComponentInstance.name);
+ sharable::TreeFragment * aTemplateAddr = NULL;
+
+ if (!m_aTemplates.hasNode(aTemplateLocation ))
+ {
+ CFG_TRACE_INFO_NI("CacheController: cache miss for that template - loading from backend");
+ aTemplateAddr = m_aTemplates.addTemplates(_aComponentInstance );
+ }
+ OSL_ASSERT (aTemplateAddr != NULL);
+ return aTemplateAddr;
+ }
+// -------------------------------------------------------------------------
+
+sharable::TreeFragment * CacheController::loadTemplate(TemplateRequest const & _aRequest) SAL_THROW((com::sun::star::uno::Exception))
+{
+
+ OSL_ENSURE(_aRequest.getTemplateName().getLength() != 0, "CacheController::loadTemplate : invalid template name !");
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::CacheController", "jb99855", "configmgr: CacheController::loadTemplate()");
+ RTL_LOGFILE_CONTEXT_TRACE2(aLog, "requested template: %s/%s",
+ RTL_LOGFILE_OU2A(_aRequest.getComponentName().toString()) ,
+ _aRequest.isComponentRequest() ?
+ "*" : RTL_LOGFILE_OU2A(_aRequest.getComponentName().toString()) );
+
+
+ configuration::AbsolutePath aTemplateLocation = encodeTemplateLocation(_aRequest.getTemplateName(), _aRequest.getComponentName());
+
+ rtl::OUString aModuleName = aTemplateLocation.getModuleName();
+
+ configuration::AbsolutePath aTemplateParent (aTemplateLocation.getParentPath());
+
+ //Load-if-not-there (componentwise)
+ if (!m_aTemplates.hasNode(aTemplateParent))
+ {
+ OSL_ENSURE(aTemplateLocation.getDepth() > 1, "CacheController::ensureTemplate : invalid template location !");
+ TemplateRequest aTemplateRequest = TemplateRequest::forComponent(_aRequest.getComponentName());
+
+ std::auto_ptr<ISubtree> aMultiTemplates = loadTemplateData(aTemplateRequest);
+ //add-if-not-loaded
+ addTemplates(backend::ComponentDataStruct(aMultiTemplates, aModuleName));
+
+ }
+ sharable::TreeFragment * aTemplateAddr = m_aTemplates.getTemplateTree(aTemplateLocation);
+ if (aTemplateAddr == NULL)
+ throw uno::Exception(::rtl::OUString::createFromAscii("Unknown template. Type description could not be found in the given module."), NULL);
+
+ return m_aTemplates.getTreeAddress(aTemplateLocation.getModuleName());
+}
+// -----------------------------------------------------------------------------
+
+ResultHolder< TemplateInstance > CacheController::getTemplateData(TemplateRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::CacheController", "jb99855", "configmgr: CacheController::getTemplateData()");
+ RTL_LOGFILE_CONTEXT_TRACE2(aLog, "requested template: %s/%s",
+ RTL_LOGFILE_OU2A(_aRequest.getComponentName().toString()) ,
+ _aRequest.isComponentRequest() ?
+ "*" : RTL_LOGFILE_OU2A(_aRequest.getComponentName().toString()) );
+
+ configuration::AbsolutePath aTemplateLocation = encodeTemplateLocation(_aRequest.getTemplateName(), _aRequest.getComponentName());
+
+ loadTemplate(_aRequest);
+ //configuration::AbsolutePath aTemplateLocation = ensureTemplate(_aRequest.getTemplateName(), _aRequest.getComponentName());
+
+ sharable::TreeFragment * aTemplateAddr = m_aTemplates.getTemplateTree(aTemplateLocation);
+ if (aTemplateAddr == NULL)
+ throw uno::Exception(::rtl::OUString::createFromAscii("Unknown template. Type description could not be found in the given module."), NULL);
+
+ std::auto_ptr<INode> aResultTree = data::convertTree(aTemplateAddr, true);
+
+ TemplateInstance aResult(aResultTree,_aRequest.getTemplateName(), _aRequest.getComponentName());
+
+ return ResultHolder< TemplateInstance >(aResult);
+}
+// -----------------------------------------------------------------------------
+
+void CacheController::saveAndNotify(UpdateRequest const & _anUpdate) SAL_THROW((com::sun::star::uno::Exception))
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::backend::CacheController", "jb99855", "configmgr: CacheController::saveAndNotify()");
+ RTL_LOGFILE_CONTEXT_TRACE1(aLog, "location: %s", RTL_LOGFILE_OU2A(_anUpdate.getUpdateRoot().toString()) );
+ try
+ {
+ // ---------- preworking on the changes ----------
+ // caller must own a read lock on this cache line
+ CFG_TRACE_INFO("CacheController: saving an update for '%s'",OUSTRING2ASCII(_anUpdate.getUpdateRoot().toString()));
+
+ rtl::Reference<CacheLoadingAccess> aCache = m_aCacheMap.get(_anUpdate.getOptions());
+
+ OSL_ENSURE(aCache.is(), "No cache data to update in saveAndNotify");
+
+ if (!aCache.is()) throw lang::DisposedException(rtl::OUString::createFromAscii("Tree to be updated was already disposed"), NULL);
+
+ aCache->addChangesToPending(_anUpdate.getUpdate());
+
+ if ( _anUpdate.isSyncRequired()|| m_bDisposing ) // cannot do it asynchronously
+ {
+ CFG_TRACE_INFO_NI("Running synchronous write");
+ savePendingChanges( aCache, getComponentRequest(_anUpdate) );
+ }
+
+ else
+ {
+ CFG_TRACE_INFO_NI("Posting asynchronous write");
+ m_pCacheWriter->scheduleWrite( getComponentRequest(_anUpdate) );
+ }
+
+ CFG_TRACE_INFO_NI("Notifying the changes");
+ // notify the changes to all clients
+ m_aNotifier.notifyChanged(_anUpdate);
+ }
+ catch(configuration::Exception& ex)
+ {
+ CFG_TRACE_ERROR_NI("Got unexpected exception: %s", ex.what());
+ configapi::ExceptionMapper e(ex);
+ e.unhandled();
+ }
+
+}
+// -----------------------------------------------------------------------------
+
+void CacheController::flushPendingUpdates()SAL_THROW((com::sun::star::uno::Exception))
+{
+ CacheMap::Map aFlushList = m_aCacheMap.copy();
+
+ for (CacheMap::Map::iterator it = aFlushList.begin(); it != aFlushList.end(); ++it)
+ saveAllPendingChanges(it->second,it->first);
+}
+
+void CacheController::flushCacheWriter()SAL_THROW(())
+{
+ //OSL_ASSERT(m_bDisposing);
+
+ if (m_pCacheWriter)
+ {
+ CFG_TRACE_INFO("CacheController: flushing all pending updates");
+
+ m_pCacheWriter->stopAndWriteCache();
+ }
+}
+// -----------------------------------------------------------------------------
+
+bool CacheController::normalizeResult(std::auto_ptr<ISubtree> & _aResult, RequestOptions const & _aOptions)
+{
+
+ if (_aResult.get()==NULL) return false;
+
+ if (_aOptions.isForAllLocales()) return true;
+
+ std::auto_ptr<INode> aReduced = reduceExpandedForLocale(_aResult, _aOptions.getLocale());
+
+ std::auto_ptr<ISubtree> aReducedTree;
+ if (aReduced.get())
+ {
+ if (ISubtree* pReducedTree =aReduced->asISubtree())
+ {
+ aReduced.release();
+ aReducedTree.reset(pReducedTree);
+ }
+ else
+ {
+ OSL_ENSURE(false, "Tree unexpectedly reduced to non-tree");
+ }
+ }
+ else
+ OSL_ENSURE(false, "Tree unexpectedly reduced to nothing");
+
+
+ _aResult = aReducedTree;
+ bool retCode = _aResult.get()!=NULL ? true : false;
+ return retCode;
+}
+// -----------------------------------------------------------------------------
+
+ResultHolder< ComponentInstance > CacheController::loadDirectly(ComponentRequest const & _aRequest, bool _bAddListenter) SAL_THROW((com::sun::star::uno::Exception))
+{
+ CFG_TRACE_INFO("CacheController: loading data for component '%s' from the backend", OUSTRING2ASCII(_aRequest.getComponentName()));
+
+ configuration::AbsolutePath aRequestPath = configuration::AbsolutePath::makeModulePath(_aRequest.getComponentName());
+
+ NodeRequest aNodeRequest(aRequestPath, _aRequest.getOptions());
+
+ ResultHolder< ComponentInstance > aResult = m_xBackend->getNodeData(_aRequest, this, _bAddListenter?this:NULL);
+
+ OSL_PRECOND(aResult.mutableInstance().mutableData().get(), "loadDirectly: Data must not be NULL");
+
+ CFG_TRACE_INFO_NI("- loading data completed - normalizing result");
+
+ if (!normalizeResult( aResult.mutableInstance().mutableData(),_aRequest.getOptions()))
+ {
+ CFG_TRACE_ERROR_NI(" - cannot normalized result: failing");
+
+ rtl::OUString sMsg(RTL_CONSTASCII_USTRINGPARAM("Requested data at '"));
+ sMsg += aRequestPath.toString();
+ sMsg += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("'is not available: "));
+
+ throw com::sun::star::container::NoSuchElementException(sMsg,NULL);
+ }
+
+ CFG_TRACE_INFO_NI(" - returning normalized defaults");
+
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+
+ResultHolder< NodeInstance > CacheController::loadDefaultsDirectly(NodeRequest const & _aRequest) SAL_THROW((com::sun::star::uno::Exception))
+{
+ CFG_TRACE_INFO("CacheController: loading defaults for '%s' from the backend", OUSTRING2ASCII(_aRequest.getPath().toString()));
+
+ ResultHolder< NodeInstance > aResult = m_xBackend->getDefaultData(_aRequest);
+
+ CFG_TRACE_INFO_NI("- loading defaultscompleted - normalizing result");
+
+ normalizeResult(aResult.mutableInstance().mutableData(),_aRequest.getOptions());
+
+ CFG_TRACE_INFO_NI(" - returning normalized defaults");
+
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+
+void CacheController::saveDirectly(UpdateRequest const & _anUpdate) SAL_THROW((com::sun::star::uno::Exception))
+{
+ m_xBackend->updateNodeData(_anUpdate);
+}
+// -----------------------------------------------------------------------------
+
+void CacheController::savePendingChanges(rtl::Reference<CacheLoadingAccess> const & _aCache, ComponentRequest const & _aComponent) SAL_THROW((com::sun::star::uno::Exception))
+{
+ CFG_TRACE_INFO("CacheController: saving updates for tree: '%s'", OUSTRING2ASCII(_aComponent.getComponentName()));
+
+ try
+ {
+ CFG_TRACE_INFO2("CacheController: saving updates for tree: '%s'", OUSTRING2ASCII(_aComponent.getComponentName()));
+
+ std::auto_ptr<SubtreeChange> aChangeData = _aCache->releasePendingChanges(_aComponent.getComponentName());
+
+ if (aChangeData.get())
+ {
+ CFG_TRACE_INFO_NI("- found changes - sending to backend");
+
+ configuration::AbsolutePath aRootPath = configuration::AbsolutePath::makeModulePath(_aComponent.getComponentName());
+
+ backend::UpdateRequest anUpdateSpec(aChangeData.get(),aRootPath,_aComponent.getOptions());
+
+ // anUpdateSpec.setRequestId(pInfo->getRequestId(_aRootPath));
+
+ this->saveDirectly(anUpdateSpec);
+
+ CFG_TRACE_INFO_NI("- saving changes completed successfully");
+ }
+ else
+ CFG_TRACE_WARNING_NI("- no changes found - cannot save");
+ }
+ catch(uno::Exception& e)
+ {
+ (void)e;
+ CFG_TRACE_ERROR_NI("CacheController: saving tree '%s' failed: %s",
+ OUSTRING2ASCII(_aComponent.getComponentName()),
+ OUSTRING2ASCII(e.Message) );
+
+ refreshComponent(_aComponent);
+ CFG_TRACE_INFO_NI("- component data invalidated");
+
+ throw;
+ }
+}
+// -----------------------------------------------------------------------------
+
+bool CacheController::saveAllPendingChanges(rtl::Reference<CacheLoadingAccess> const & _aCache, RequestOptions const & _aOptions)
+ SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ CFG_TRACE_INFO("CacheController: Saving all pending changes for cache line");
+ OSL_ASSERT(_aCache.is());
+
+ std::vector< rtl::OUString > aPendingModules;
+ _aCache->findPendingChangedModules(aPendingModules);
+
+ CFG_TRACE_INFO_NI("Found %d changed modules",int(aPendingModules.size()));
+
+ bool bSuccess = true;
+ for (std::vector< rtl::OUString >::iterator it = aPendingModules.begin();
+ it != aPendingModules.end();
+ ++it )
+ {
+ try
+ {
+ this->savePendingChanges(_aCache, ComponentRequest(*it,_aOptions) );
+ }
+ catch (uno::Exception & )
+ {
+ CFG_TRACE_ERROR_NI("CacheController: Exception while saving one module - ignoring");
+ bSuccess = false;
+ }
+ }
+ CFG_TRACE_INFO_NI("Done saving pending changes for cache line");
+
+ return bSuccess;
+}
+// -----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+void CacheController::freeComponent(ComponentRequest const & _aRequest) SAL_THROW(())
+{
+ CFG_TRACE_INFO("CacheController: releasing module '%s' for user '%s' with locale '%s'",
+ OUSTRING2ASCII(_aRequest.getComponentName()),
+ OUSTRING2ASCII(_aRequest.getOptions().getEntity()),
+ OUSTRING2ASCII(_aRequest.getOptions().getLocale()) );
+
+ rtl::Reference<CacheLoadingAccess> aCache = m_aCacheMap.get(_aRequest.getOptions());
+
+ OSL_ENSURE(aCache.is(), "Releasing a nonexisting module");
+
+ if (aCache.is())
+ {
+ if (aCache->releaseModule(_aRequest.getComponentName()) == 0)
+ {
+ // start the cleanup
+ m_pDisposer->scheduleCleanup(_aRequest.getOptions());
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void CacheController::dataChanged(const ComponentRequest& _aRequest) SAL_THROW(())
+{
+ refreshComponent(_aRequest);
+}
+// -----------------------------------------------------------------------------
+void CacheController::refreshAllComponents() SAL_THROW((com::sun::star::uno::Exception))
+{
+ CacheMap::Map aRefreshList = m_aCacheMap.copy();
+
+ for (CacheMap::Map::iterator i = aRefreshList.begin();
+ i != aRefreshList.end(); ++i)
+ {
+ if (!i->second->isEmpty())
+ {
+ ExtendedCacheData aCacheData = i->second->m_aData;
+ RequestOptions aOption = i->first;
+ CacheData::ModuleList aModuleList = aCacheData.accessModuleList();
+ for (CacheData::ModuleList::iterator itr = aModuleList.begin();
+ itr != aModuleList.end(); ++itr)
+ {
+ //Check the cacheline has atleast one client reference
+
+
+ if (itr->second->clientReferences() > 0)
+ {
+ ComponentRequest aRequest(itr->first,i->first);
+ refreshComponent(aRequest);
+ } else
+ {
+ // FIXME: otherwise dispose now
+ // XXX: (lo) refresh all, preventing cache corruption.
+ // An unused component should be purged from the cache
+ // instead of being refreshed
+ ComponentRequest aRequest(itr->first,i->first);
+ refreshComponent(aRequest);
+ }
+ }
+ }
+ }
+}
+
+// -------------------------------------------------------------------------
+ } // namespace
+
+// -------------------------------------------------------------------------
+} // namespace
diff --git a/configmgr/source/treecache/cachecontroller.hxx b/configmgr/source/treecache/cachecontroller.hxx
new file mode 100644
index 000000000000..b03a4e041130
--- /dev/null
+++ b/configmgr/source/treecache/cachecontroller.hxx
@@ -0,0 +1,341 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachecontroller.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_CACHECONTROLLER_HXX
+#define CONFIGMGR_BACKEND_CACHECONTROLLER_HXX
+
+#include "sal/config.h"
+
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "utility.hxx"
+#include "mergeddataprovider.hxx"
+#include "cacheaccess.hxx"
+#include "cachemulticaster.hxx"
+#include "requestoptions.hxx"
+#include "autoreferencemap.hxx"
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+ class OTreeDisposeScheduler;
+ class OCacheWriteScheduler;
+// ---------------------------------------------------------------------------
+ namespace backend
+ {
+// ---------------------------------------------------------------------------
+
+ /** manages a shared data cache for configuration data
+ trying to ensure consistency with a backend
+ and provides access to the data for clients
+ */
+ class CacheController:
+ public salhelper::SimpleReferenceObject,
+ public ITemplateDataProvider, public INodeDataListener
+ {
+ public:
+ /** ctor
+ */
+ explicit
+ CacheController(rtl::Reference< backend::IMergedDataProvider > const & _xBackend,
+ const uno::Reference<uno::XComponentContext>& xContext);
+
+ // disposing the cache before destroying
+ void dispose() SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ /** locates data of a component in the cache.
+
+ <p> If the data isn't in the cache it is loaded from the backend. </p>
+
+ @param _aRequest
+ identifies the component to be loaded.
+
+ @returns
+ data that can be used to locate the loaded data in the cache.
+
+ @throws com::sun::star::uno::Exception
+ if loading the data fails.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ sharable::TreeFragment * loadComponent(ComponentRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ /** releases data of a component from the cache.
+
+ <p> Should be called when a client is done with a component.
+ Each calls to <method>loadComponent</method> should
+ be balanced by exactly one call to <method>freeComponent</method>.
+ </p>
+
+ @param _aRequest
+ identifies a component previously loaded via <method>loadComponent</method>.
+
+ @returns
+ data that can be used to locate the loaded data in the cache.
+ */
+ void freeComponent(ComponentRequest const & _aRequest)
+ SAL_THROW(());
+
+ /** refreshes data of an existing component from the backend
+
+ <p> If the data is in the cache already, it is refreshed from the
+ backend and the change are notified to all registered listeners.
+ </p>
+ <p> If the data isn't in the cache nothing is done and
+ a NULL location is returned.
+ </p>
+
+ <p>Note: the caller <strong>must not</strong> hold any lock on the cache line affected.</p>
+
+ @param _aRequest
+ identifies the component to be refreshed.
+
+ @returns
+ data that can be used to locate the refreshed data in the cache.
+
+ <p>If there is no data to refresh a NULL location is returned.</p>
+
+ @throws com::sun::star::uno::Exception
+ if loading the data fails.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ sharable::TreeFragment * refreshComponent(ComponentRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception));
+ /** refreshes data of all existing components from the backend
+
+ <p> If the data is in the cache already, it is refreshed from the
+ backend and the change are notified to all registered listeners.
+ </p>
+ <p> If the data isn't in the cache nothing is done and
+ a NULL location is returned.
+ </p>
+
+ <p>Note: the caller <strong>must not</strong> hold any lock on the cache line affected.</p>
+
+ @throws com::sun::star::uno::Exception
+ if loading the data fails.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ void refreshAllComponents()
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ /** flushes data of all pending updates from cache to the backend(s)
+ @throws com::sun::star::uno::Exception
+ if flushing the data fails.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ void flushPendingUpdates() SAL_THROW((com::sun::star::uno::Exception));
+
+ /** locates a template in the cache.
+
+ <p> If the data isn't in the cache it is loaded from the backend. </p>
+
+ <p>Note: the caller <strong>must not</strong> hold any lock on the cache line affected.</p>
+
+ @param _aRequest
+ identifies the template to be loaded.
+
+ @returns
+ data that can be used to locate the template data in the cache.
+
+ @throws com::sun::star::uno::Exception
+ if loading the template data fails.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ sharable::TreeFragment * loadTemplate(TemplateRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ /** saves changes to the backend and notifies them to registered listeners.
+
+ <p> Must be called after the changes have been applied to the cache
+ and before any subsequent changes to the same component.
+ </p>
+
+ <p> Notifications are guaranteed to be delivered
+ before any subsequent changes to the same component are possible.
+ </p>
+
+ <p> Note: the caller <strong>must</strong> hold a read lock (but no write lock)
+ on the cache line affected during the call.</p>
+
+ @param _anUpdate
+ identifies the node that changed and describes the changes.
+
+ @throws com::sun::star::uno::Exception
+ if saving the changes to the backend fails.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ void saveAndNotify(UpdateRequest const & _anUpdate)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ /** @returns
+ an object that can used to broadcast changes done through this object.
+ <p> The object returned is guaranteed to live as long
+ as this object lives.
+ </p>
+ */
+ CacheChangeMulticaster & getNotifier() SAL_THROW(())
+ { return m_aNotifier; }
+
+ /** loads merged data for a (complete) tree and returns it as return value.
+
+ @param _aRequest
+ identifies the component to be loaded
+
+ @param __bAddListenter
+ identifies is listener is to be registered to backend
+
+ @returns
+ A valid component instance for the given component.
+
+ @throws com::sun::star::uno::Exception
+ if the node cannot be retrieved.
+ The exact exception being thrown may depend on the underlying backend.
+
+ */
+ ResultHolder< ComponentInstance > getComponentData(ComponentRequest const & _aRequest,
+ bool _bAddListenter)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ /** loads default data for a (partial) tree and returns it as return value
+
+ @param _aRequest
+ identifies the node to be loaded
+
+ @returns
+ A valid node instance for the default state of the given node.
+
+ <p>May be NULL, if the node exists but has no default equivalent.</p>
+
+ @throws com::sun::star::uno::Exception
+ if the default cannot be retrieved.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ ResultHolder< NodeInstance > getDefaultData(NodeRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ /** loads a given template and returns it as return value
+
+ @param _aRequest
+ identifies the template to be loaded
+
+ @returns
+ A valid instance of the given template.
+
+ <p> Currently a request with empty template name
+ will retrieve a group node holding all templates
+ of a component.
+ </p>
+
+ @throws com::sun::star::uno::Exception
+ if the template cannot be retrieved.
+ The exact exception being thrown may depend on the underlying backend.
+ */
+ virtual ResultHolder< TemplateInstance > getTemplateData(TemplateRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception));
+ //INodeDataListener Implementation
+ /** Triggered when component data is changed
+
+ @param _aRequest
+ identifies the data that changed
+ */
+ virtual void dataChanged(const ComponentRequest& _aRequest) SAL_THROW(());
+ protected:
+ // ref counted, that's why no public dtor
+ ~CacheController();
+ // implementation
+ private:
+ configuration::AbsolutePath encodeTemplateLocation(rtl::OUString const & _rName, rtl::OUString const & _rModule) const;
+
+ configuration::AbsolutePath ensureTemplate(rtl::OUString const& _rName, rtl::OUString const& _rModule) SAL_THROW((com::sun::star::uno::Exception));
+
+ // adjust a node result for locale, ...
+ bool normalizeResult(std::auto_ptr<ISubtree> & _aResult, RequestOptions const & _aOptions);
+
+ // reads data from the backend directly
+ ResultHolder< ComponentInstance > loadDirectly(ComponentRequest const & _aRequest, bool _bAddListenter )
+ SAL_THROW((com::sun::star::uno::Exception));
+ // reads default data from the backend directly
+ ResultHolder< NodeInstance > loadDefaultsDirectly(NodeRequest const & _aRequest) SAL_THROW((com::sun::star::uno::Exception));
+ // writes an update to the backend directly
+ void saveDirectly(UpdateRequest const & _anUpdate) SAL_THROW((com::sun::star::uno::Exception));
+
+ // writes updates for a component to the backend directly
+ void savePendingChanges(rtl::Reference<CacheLoadingAccess> const & _aCache, ComponentRequest const & _aComponent)
+ SAL_THROW((com::sun::star::uno::Exception));
+ // saves all pending changes from a cache access to the backend
+ bool saveAllPendingChanges(rtl::Reference<CacheLoadingAccess> const & _aCache, RequestOptions const & _aOptions)
+ SAL_THROW((com::sun::star::uno::RuntimeException));
+ // load templates componentwise from backend
+ std::auto_ptr<ISubtree> loadTemplateData(TemplateRequest const & _aRequest)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+
+ void flushCacheWriter() SAL_THROW(());
+ // add templates componentwise to cache
+ sharable::TreeFragment * addTemplates ( backend::ComponentDataStruct const & _aComponentInstance );
+ rtl::Reference<CacheLoadingAccess> getCacheAlways(RequestOptions const & _aOptions);
+
+ OTreeDisposeScheduler * createDisposer(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _xContext);
+ OCacheWriteScheduler * createCacheWriter(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _xContext);
+
+
+
+ // disposing
+ void disposeAll(bool _bFlushRemainingUpdates);
+
+ void closeModules(std::vector< rtl::Reference<CacheLine> > & _aList, RequestOptions const & _aOptions);
+ private:
+ typedef AutoReferenceMap<RequestOptions,CacheLoadingAccess,lessRequestOptions> CacheMap;
+
+ CacheChangeMulticaster m_aNotifier;
+ rtl::Reference< backend::IMergedDataProvider > m_xBackend;
+ CacheMap m_aCacheMap;
+ TemplateCacheData m_aTemplates;
+
+ OTreeDisposeScheduler* m_pDisposer;
+ OCacheWriteScheduler * m_pCacheWriter;
+
+ bool m_bDisposing; // disables async writing and automatic refresh
+
+ friend class configmgr::OTreeDisposeScheduler;
+ friend class configmgr::OCacheWriteScheduler;
+ friend class OInvalidateTreeThread;
+
+ };
+// ---------------------------------------------------------------------------
+ } // namespace backend
+
+// ---------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/treecache/cachedata.cxx b/configmgr/source/treecache/cachedata.cxx
new file mode 100644
index 000000000000..ee8269e8a803
--- /dev/null
+++ b/configmgr/source/treecache/cachedata.cxx
@@ -0,0 +1,498 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachedata.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "cachedata.hxx"
+#include "node.hxx"
+#include "updatehelper.hxx"
+#include "tracer.hxx"
+#include <osl/diagnose.h>
+#include "configpath.hxx"
+
+namespace configmgr
+{
+ // ---------------------------- Client Acquire helper ----------------------------
+
+ struct CacheLineClientRef
+ {
+ rtl::Reference<CacheLine> xModule;
+
+ CacheLineClientRef(rtl::Reference<CacheLine> const& _xModule)
+ : xModule(_xModule)
+ {
+ if (xModule.is())
+ xModule->clientAcquire();
+ }
+
+ ~CacheLineClientRef() // release the client reference unless it was 'kept'
+ {
+ if (xModule.is())
+ xModule->clientRelease();
+ }
+
+ void rebind(rtl::Reference<CacheLine> const& _xModule)
+ {
+ if (_xModule.is())
+ _xModule->clientAcquire();
+ if (xModule.is())
+ xModule->clientRelease();
+ xModule = _xModule;
+ }
+
+ /// release the contained module so that the client reference will be kept active
+ void keep()
+ {
+ xModule.clear();
+ OSL_ASSERT(!xModule.is());
+ }
+
+ /// return the contained module so that the client reference will be kept active
+ rtl::Reference<CacheLine> keepModule()
+ {
+ rtl::Reference<CacheLine> xRet = xModule;
+ this->keep();
+ return xRet;
+ }
+ private:
+ CacheLineClientRef(CacheLineClientRef const& );
+ CacheLineClientRef& operator=(CacheLineClientRef const& );
+
+ };
+
+// -----------------------------------------------------------------------------
+ static inline rtl::OUString implExtractModuleName(configuration::AbsolutePath const& aConfigPath)
+ {
+ return aConfigPath.getModuleName();
+ }
+
+// -----------------------------------------------------------------------------
+
+ CacheData::CacheData()
+ {
+ }
+// -----------------------------------------------------------------------------
+
+ CacheData::~CacheData()
+ {
+ CFG_TRACE_INFO("Discarding CacheData (Still holding %d module trees)", int (m_aModules.size()) );
+ }
+// -----------------------------------------------------------------------------
+ inline
+ rtl::Reference<CacheLine> CacheData::internalGetModule(rtl::OUString const & _aModuleName ) const
+ {
+ OSL_ASSERT(_aModuleName.getLength() != 0);
+
+ ModuleList::const_iterator it = m_aModules.find(_aModuleName);
+
+ return it!=m_aModules.end() ? it->second : rtl::Reference<CacheLine>();
+ }
+// -----------------------------------------------------------------------------
+ inline
+ rtl::Reference<CacheLine> CacheData::internalGetModule(const configuration::AbsolutePath& _aPath) const
+ {
+ return internalGetModule( implExtractModuleName(_aPath) );
+ }
+// -----------------------------------------------------------------------------
+
+ inline
+ void CacheData::internalAddModule(rtl::OUString const & _aName, const rtl::Reference<CacheLine> & _aModule)
+ {
+ //OSL_PRECOND(m_aModules.find(_aName) == m_aModules.end(), "ERROR: Module already present in CacheData");
+
+ m_aModules[_aName] = _aModule;
+
+ CFG_TRACE_INFO("CacheData Data: Added new module tree for module %s", OUSTRING2ASCII(_aName) );
+ }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+ rtl::Reference<CacheLine> CacheData::internalAttachModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aName) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ rtl::Reference<CacheLine> aNewModule = doCreateAttachedModule(_aLocation,_aName);
+
+ internalAddModule( _aName, aNewModule );
+
+ return aNewModule;
+ }
+
+// -------------------------------------------------------------------------
+
+ void CacheData::attachModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aModule)
+ {
+ this->internalAttachModule(_aLocation,_aModule);
+ }
+// -------------------------------------------------------------------------
+
+ rtl::Reference<CacheLine> CacheData::doCreateAttachedModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aName) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ return CacheLine::createAttached( _aName, _aLocation );
+ }
+// -----------------------------------------------------------------------------
+
+ /// gets a data segment reference for the given path if exists
+ sharable::TreeFragment * CacheData::getTreeAddress(rtl::OUString const & _aModule) const
+ {
+ rtl::Reference<CacheLine> aModule = internalGetModule(_aModule);
+
+ return aModule.is() ? aModule->getTreeAddress() : NULL;
+ }
+// -------------------------------------------------------------------------
+
+ bool CacheData::hasModule(rtl::OUString const & _aModule) const
+ {
+ rtl::Reference<CacheLine> aModule = internalGetModule(_aModule);
+
+ return aModule.is() && !aModule->isEmpty();
+ }
+// -------------------------------------------------------------------------
+
+ bool CacheData::hasModuleDefaults(rtl::OUString const & _aModule) const
+ {
+ rtl::Reference<CacheLine> aModule = internalGetModule(_aModule);
+
+ return aModule.is() && !aModule->hasDefaults();
+ }
+// -------------------------------------------------------------------------
+
+ sharable::TreeFragment * CacheData::internalGetPartialTree(const configuration::AbsolutePath& aComponentName ) const
+ {
+ rtl::Reference<CacheLine> xModule = internalGetModule(aComponentName);
+
+ if ( !xModule.is() )
+ return NULL;
+
+ sharable::TreeFragment * pSubtree = xModule->getPartialTree(aComponentName);
+
+ OSL_ENSURE( pSubtree == NULL || xModule->clientReferences() != 0 ,
+ "WARNING: returning subtree from module without clients\n" );
+#ifdef CFG_ENABLE_TRACING
+ if( pSubtree != NULL && xModule->clientReferences() == 0)
+ {
+ CFG_TRACE_WARNING("CacheData data: returning subtree %s from module without clients", OUSTRING2ASCII( aComponentName.toString() ) );
+ }
+#endif // CFG_ENABLE_TRACING
+
+ return pSubtree;
+ }
+// -----------------------------------------------------------------------------
+ sharable::Node * CacheData::internalGetNode(const configuration::AbsolutePath& aComponentName ) const
+ {
+ rtl::Reference<CacheLine> xModule = internalGetModule(aComponentName);
+
+ if ( !xModule.is() )
+ return 0;
+
+ if ( xModule->isEmpty() )
+ return 0;
+
+ sharable::Node * pNode = xModule->getNode(aComponentName);
+
+ OSL_ENSURE( pNode == NULL || xModule->clientReferences() != 0,
+ "WARNING: returning node from module without clients\n" );
+ #ifdef CFG_ENABLE_TRACING
+ if( pNode != NULL && xModule->clientReferences() == 0)
+ {
+ CFG_TRACE_WARNING("CacheData data: returning node %s from module without clients", OUSTRING2ASCII( aComponentName.toString() ) );
+ }
+#endif // CFG_ENABLE_TRACING
+
+ return pNode;
+ }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ bool CacheData::acquireModule(rtl::OUString const & _aModule)
+ {
+ rtl::Reference<CacheLine> xModule = internalGetModule(_aModule);
+
+ if (xModule.is())
+ {
+ CacheLineClientRef aClientRef(xModule);
+ aClientRef.keep();
+ }
+
+ return xModule.is();
+ }
+// -----------------------------------------------------------------------------
+ sharable::Node * CacheData::acquireNode(configuration::AbsolutePath const& _aPath)
+ {
+ CacheLineClientRef aClientRef(internalGetModule(_aPath));
+
+ sharable::Node * aNodeAddr = internalGetNode(_aPath);
+
+ if (sharable::Node const * pNode = aNodeAddr)
+ {
+ if (pNode->isValue())
+ aNodeAddr = 0; // invalid: cannot acquire single value
+ }
+ else
+ OSL_ASSERT( aNodeAddr == NULL );
+
+ if (aNodeAddr != NULL)
+ aClientRef.keep();
+
+ return aNodeAddr;
+ }
+// -----------------------------------------------------------------------------
+
+ bool CacheData::insertDefaults( backend::NodeInstance const & _aDefaultInstance) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ OSL_PRECOND(_aDefaultInstance.data().get(), "insertDefaults: Data must not be NULL");
+ OSL_PRECOND(_aDefaultInstance.root().getDepth() == 1, "insertDefaults: Default tree being added must be for module");
+
+ // we should already have the module in cache !
+ rtl::Reference<CacheLine> xModule = internalGetModule(_aDefaultInstance.root());
+
+ OSL_ENSURE( xModule.is(), "CacheData::insertDefaults: No module to insert the defaults to - where did the data segment come from ?");
+
+ if (!xModule.is()) return false;
+
+ // make sure to keep the module alive
+ CacheLineClientRef( xModule ).keep();
+
+ sharable::TreeFragment * aResultTree = xModule->insertDefaults(_aDefaultInstance);
+
+ return aResultTree != NULL;
+ }
+// -----------------------------------------------------------------------------
+
+ void CacheData::applyUpdate( backend::UpdateInstance & _anUpdate ) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ // request the subtree, atleast one level must exist!
+ sharable::Node * aNodeAddr = internalGetNode(_anUpdate.root());
+
+ if (aNodeAddr != NULL)
+ {
+ applyUpdateToTree(*_anUpdate.data(),aNodeAddr);
+ }
+ else
+ {
+ OSL_ENSURE(false, "CacheData::applyUpdate called for non-existing tree");
+ rtl::OUString aStr(RTL_CONSTASCII_USTRINGPARAM("CacheData: update to non-existing node: "));
+
+ aStr += _anUpdate.root().toString();
+
+ throw uno::RuntimeException(aStr,0);
+ }
+ }
+// -----------------------------------------------------------------------------
+ oslInterlockedCount CacheData::releaseModule( rtl::OUString const & _aModule, bool _bKeepDeadModule )
+ {
+ rtl::Reference<CacheLine> xModule = internalGetModule(_aModule);
+
+ const oslInterlockedCount c_nErrorCount = -1;
+
+ OSL_ENSURE( xModule.is(), "ERROR: Releasing non-existent subtree");
+ if ( !xModule.is()) return c_nErrorCount;
+
+ OSL_ENSURE( xModule->clientReferences() > 0, "ERROR: Releasing non-referenced subtree");
+
+ oslInterlockedCount nResult = xModule->clientRelease();
+
+ if (nResult == 0 && !_bKeepDeadModule)
+ {
+ m_aModules.erase( _aModule );
+ }
+ return nResult;
+ }
+
+// -----------------------------------------------------------------------------
+ sharable::TreeFragment * CacheData::getTemplateTree(configuration::AbsolutePath const& aTemplateName ) const
+ {
+ return internalGetPartialTree(aTemplateName);
+ }
+// -----------------------------------------------------------------------------
+ sharable::Node * CacheData::getNode(const configuration::AbsolutePath& _rPath)
+ {
+ return internalGetNode(_rPath);
+ }
+// -----------------------------------------------------------------------------
+ bool CacheData::hasNode(const configuration::AbsolutePath& _rPath) const
+ {
+ return internalGetNode(_rPath) != NULL;
+ }
+// -----------------------------------------------------------------------------
+
+ sharable::TreeFragment * TemplateCacheData::addTemplates( backend::ComponentDataStruct const & _aComponentInstance) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ OSL_PRECOND(_aComponentInstance.data.get(), "addTemplates: Data must not be NULL");
+ // we should already have the module in cache !
+ rtl::OUString aModuleName ( _aComponentInstance.name);
+ rtl::Reference<CacheLine> xModule = internalGetModule(aModuleName);
+
+ OSL_ENSURE( xModule.is(), "ExtendedCacheData::addTemplates: No module to add the templates to - where did the data segment come from ?");
+
+ if (!xModule.is()) return NULL;
+
+ // make sure to keep the module alive
+ CacheLineClientRef( xModule ).keep();
+
+ static const rtl::OUString aDummyTemplateName(RTL_CONSTASCII_USTRINGPARAM("cfg:Template"));
+ static const rtl::OUString aDummyTemplateModule(RTL_CONSTASCII_USTRINGPARAM("cfg:Templates"));
+ _aComponentInstance.data->makeSetNode(aDummyTemplateName,aDummyTemplateModule);
+
+ sharable::TreeFragment * aResult = xModule->setComponentData(_aComponentInstance, true);
+
+ OSL_ASSERT(aResult != NULL);
+
+ return aResult;
+ }
+// -----------------------------------------------------------------------------
+
+ rtl::Reference<CacheLine> TemplateCacheData::doCreateAttachedModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aName) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ rtl::Reference<CacheLine> aNewModule = CacheLine::createAttached(_aName, _aLocation);
+
+ return aNewModule.get();
+ }
+// -----------------------------------------------------------------------------
+
+ void TemplateCacheData::createModule(rtl::OUString const & _aModule) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ rtl::Reference<CacheLine> aNewModule = CacheLine::createNew(_aModule);
+
+ internalAddModule( _aModule, aNewModule.get() );
+ }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ inline
+ rtl::Reference<ExtendedCacheLine> ExtendedCacheData::implExtended(const rtl::Reference<CacheLine>& _aSimpleRef) const
+ {
+ CacheLine * pBasic = _aSimpleRef.get();
+ ExtendedCacheLine * pExtended = static_cast<ExtendedCacheLine *>(pBasic);
+ return rtl::Reference<ExtendedCacheLine>(pExtended);
+ }
+
+// -----------------------------------------------------------------------------
+
+ rtl::Reference<CacheLine> ExtendedCacheData::doCreateAttachedModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aName) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ rtl::Reference<ExtendedCacheLine> aNewModule =
+ ExtendedCacheLine::createAttached(_aName, _aLocation);
+
+ return rtl::Reference<CacheLine>( aNewModule.get() );
+ }
+// -----------------------------------------------------------------------------
+
+ void ExtendedCacheData::createModule(rtl::OUString const & _aModule) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ rtl::Reference<ExtendedCacheLine> aNewModule = ExtendedCacheLine::createNew(_aModule);
+
+ internalAddModule( _aModule, aNewModule.get() );
+ }
+// -----------------------------------------------------------------------------
+
+ sharable::TreeFragment * ExtendedCacheData::addComponentData(backend::ComponentInstance const & _aComponentInstance,
+ bool _bWithDefaults) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ OSL_PRECOND(_aComponentInstance.data().get(), "addComponentData: Data must not be NULL");
+ // we should already have the module in cache !
+ //rtl::Reference<CacheLine> xModule = internalGetModule(_aNodeInstance.root().location());
+ rtl::Reference<CacheLine> xModule = internalGetModule(_aComponentInstance.component() );
+
+ OSL_ENSURE( xModule.is(), "ExtendedCacheData::addComponentData: No module to add the subtree to - where did the data segment come from ?");
+
+ if (!xModule.is()) return NULL;
+
+ CacheLineClientRef aClientRef( xModule );
+
+ sharable::TreeFragment * aResult = xModule->setComponentData(_aComponentInstance.componentNodeData(), _bWithDefaults);
+
+ OSL_ASSERT(aResult != NULL);
+
+ if (aResult != NULL) aClientRef.keep();
+
+ return aResult;
+ }
+// -----------------------------------------------------------------------------
+
+ void ExtendedCacheData::addPending(backend::ConstUpdateInstance const & _anUpdate) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ // do we already have the module in cache ?
+ rtl::Reference<CacheLine> xModule = internalGetModule(_anUpdate.root());
+
+ if (xModule.is())
+ {
+ implExtended(xModule)->addPending(_anUpdate);
+ }
+ else
+ {
+ OSL_ENSURE(false, "We can only change Nodes if we already know something about it. So this must be a big bug.");
+ }
+ }
+// -----------------------------------------------------------------------------
+
+ std::auto_ptr<SubtreeChange> ExtendedCacheData::releasePending(rtl::OUString const& _aModule)
+ {
+ rtl::Reference<ExtendedCacheLine> xModule = implExtended(internalGetModule(_aModule));
+
+ if (xModule.is())
+ {
+ if (xModule->hasPending())
+ return xModule->releasePending();
+ else
+ return std::auto_ptr<SubtreeChange>();
+ }
+ else
+ {
+ OSL_ENSURE(false, "We can only get Nodes if we already know something about it.");
+ }
+ return std::auto_ptr<SubtreeChange>();
+ }
+// -----------------------------------------------------------------------------
+
+ bool ExtendedCacheData::hasPending(rtl::OUString const & _aModule)
+ {
+ rtl::Reference<ExtendedCacheLine> xModule = implExtended(internalGetModule(_aModule));
+
+ return xModule.is() && xModule->hasPending();
+ }
+
+// -----------------------------------------------------------------------------
+
+ void ExtendedCacheData::findPendingModules( std::vector< rtl::OUString > & _rPendingList )
+ {
+ ModuleList& rModules = CacheData::accessModuleList();
+ for (ModuleList::iterator it = rModules.begin();
+ it != rModules.end();
+ ++it)
+ {
+ OSL_ASSERT( it->second.is() );
+ if ( implExtended(it->second)->hasPending() )
+ _rPendingList.push_back( it->first );
+ }
+ }
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/treecache/cachedata.hxx b/configmgr/source/treecache/cachedata.hxx
new file mode 100644
index 000000000000..ae1408179635
--- /dev/null
+++ b/configmgr/source/treecache/cachedata.hxx
@@ -0,0 +1,179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachedata.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CACHEDATA_HXX
+#define CONFIGMGR_CACHEDATA_HXX
+
+#include "cacheline.hxx"
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace configmgr
+{
+////////////////////////////////////////////////////////////////////////////////
+ namespace backend
+ {
+ struct NodeInstance;
+ struct TemplateInstance;
+ struct UpdateInstance;
+ struct ConstUpdateInstance;
+ }
+
+////////////////////////////////////////////////////////////////////////////////
+ /** A collection of CacheLines
+ */
+
+ class CacheData
+ {
+ public:
+ CacheData();
+ virtual ~CacheData();
+
+ // attach a module with a given name
+ void attachModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aModule);
+ /// check if the given module exists already (and is not empty)
+ bool hasModule(rtl::OUString const & _aModule) const;
+ /// checks if the given module exists and has defaults available
+ bool hasModuleDefaults(rtl::OUString const & _aModule) const;
+
+ /// gets a tree address for the given module if it exists
+ sharable::TreeFragment * getTreeAddress(rtl::OUString const & _aModule) const;
+
+ /// checks whether a certain node exists in the tree
+ bool hasNode(configuration::AbsolutePath const & _aLocation) const;
+
+ /// retrieve the given node without changing its ref count
+ sharable::Node * getNode(configuration::AbsolutePath const & _rPath);
+ /// retrieve the given template tree without changing its ref count
+ sharable::TreeFragment * getTemplateTree( configuration::AbsolutePath const & aTemplateName ) const;
+
+ /// retrieve the subtree at _aPath and clientAcquire() it
+ sharable::Node * acquireNode(configuration::AbsolutePath const & _aPath );
+ /// retrieve the subtree at _aPath and clientAcquire() it, return true on success
+ bool acquireModule( rtl::OUString const & _aModule );
+ /// clientRelease() the tree at aComponentName, and return the resulting reference count
+ oslInterlockedCount releaseModule( rtl::OUString const & _aModule, bool _bKeepDeadModule = false );
+
+ bool insertDefaults( backend::NodeInstance const & _aDefaultInstance
+ ) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ /// merge the given changes into this tree - reflects old values to _anUpdate
+ void applyUpdate( backend::UpdateInstance & _anUpdate) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ // low-level interface for cache management
+ typedef std::map<rtl::OUString, rtl::Reference<CacheLine> > ModuleList;
+ ModuleList& accessModuleList() { return m_aModules; }
+
+ protected:
+ virtual rtl::Reference<CacheLine> doCreateAttachedModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aName) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ sharable::TreeFragment * internalGetPartialTree(configuration::AbsolutePath const & _aPath ) const;
+ sharable::Node * internalGetNode(const configuration::AbsolutePath& _rPath) const;
+
+ rtl::Reference<CacheLine> internalAttachModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aName) SAL_THROW((com::sun::star::uno::RuntimeException));
+ void internalAddModule(rtl::OUString const & _aName, rtl::Reference<CacheLine> const & _aModule);
+
+ rtl::Reference<CacheLine> internalGetModule(rtl::OUString const & _aName) const;
+ rtl::Reference<CacheLine> internalGetModule(const configuration::AbsolutePath& _aLocation) const;
+
+ private:
+ ModuleList m_aModules;
+ };
+////////////////////////////////////////////////////////////////////////////////
+ /** A collection of CacheLines for templates
+ */
+
+ class TemplateCacheData : public CacheData
+ {
+ public:
+ TemplateCacheData() : CacheData()
+ {
+ }
+
+ /** add the given template tree at the given location,
+ return the tree that is now pertinent and clientAcquire() it once
+ */
+ sharable::TreeFragment * addTemplates( backend::ComponentDataStruct const & _aComponentInstance
+ ) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ // create a new module with the given name
+ void createModule(rtl::OUString const & _aModule) SAL_THROW((com::sun::star::uno::RuntimeException));
+ private:
+ virtual rtl::Reference<CacheLine> doCreateAttachedModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aName) SAL_THROW((com::sun::star::uno::RuntimeException));
+ };
+//-----------------------------------------------------------------------------
+ /** A collection of CacheLines
+ */
+
+ class ExtendedCacheData : public CacheData
+ {
+ public:
+ ExtendedCacheData() : CacheData()
+ {
+ }
+
+ /** add the given subtree at the given location,
+ return the tree that is now pertinent and clientAcquire() it once
+ */
+ sharable::TreeFragment * addComponentData( backend::ComponentInstance const & _aComponentInstance,
+ bool _bWithDefaults
+ ) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ /// find the modules having pending changes
+ bool hasPending(rtl::OUString const & _aModule);
+ /// find the modules having pending changes
+ void findPendingModules( std::vector< rtl::OUString > & _rPendingList );
+
+ /// add or merge the given subtreechange at the given location
+ void addPending(backend::ConstUpdateInstance const & _anUpdate) SAL_THROW((com::sun::star::uno::RuntimeException));
+ /// remove and return pending changes for the given component
+ std::auto_ptr<SubtreeChange> releasePending(rtl::OUString const & _aModule) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ // create a new module with the given name
+ void createModule(rtl::OUString const & _aModule) SAL_THROW((com::sun::star::uno::RuntimeException));
+ private:
+ virtual rtl::Reference<CacheLine> doCreateAttachedModule(sharable::TreeFragment * _aLocation, rtl::OUString const & _aName) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ rtl::Reference<ExtendedCacheLine> implExtended(rtl::Reference<CacheLine> const & _aSimpleRef) const;
+ };
+//-----------------------------------------------------------------------------
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/treecache/cachefactory.cxx b/configmgr/source/treecache/cachefactory.cxx
new file mode 100644
index 000000000000..6f7de4487a27
--- /dev/null
+++ b/configmgr/source/treecache/cachefactory.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachefactory.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "cachefactory.hxx"
+#include "treemanager.hxx"
+#include "cachecontroller.hxx"
+#include "backendfactory.hxx"
+
+namespace configmgr
+{
+// -------------------------------------------------------------------------
+
+ static
+ rtl::Reference<TreeManager> buildCacheManager(rtl::Reference< backend::IMergedDataProvider > const & _xBackend,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & _xContext)
+ {
+ rtl::Reference< TreeManager > xCache;
+
+ if (_xBackend.is())
+ {
+ rtl::Reference< backend::CacheController > xLoader
+ = new backend::CacheController(_xBackend.get(), _xContext);
+
+ xCache.set( new TreeManager(xLoader.get()) );
+ }
+
+ return xCache;
+ }
+// -------------------------------------------------------------------------
+
+ rtl::Reference<TreeManager>
+ CacheFactory::createCacheManager(::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & _xContext)
+ {
+ rtl::Reference< backend::IMergedDataProvider > xBackend = backend::BackendFactory::instance(_xContext).createBackend();
+
+ return buildCacheManager(xBackend, _xContext);
+ }
+
+// -------------------------------------------------------------------------
+
+ CacheFactory & CacheFactory::instance()
+ {
+ static CacheFactory aStaticFactory;
+ return aStaticFactory;
+ }
+
+//-----------------------------------------------------------------------------
+} // namespace
diff --git a/configmgr/source/treecache/cacheline.cxx b/configmgr/source/treecache/cacheline.cxx
new file mode 100644
index 000000000000..e48587e62fa0
--- /dev/null
+++ b/configmgr/source/treecache/cacheline.cxx
@@ -0,0 +1,356 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cacheline.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "cacheline.hxx"
+#include "builddata.hxx"
+#include "treechangefactory.hxx"
+#include "mergechange.hxx"
+#include "configexcept.hxx"
+#include "tracer.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ static inline rtl::OUString implExtractModuleName(configuration::AbsolutePath const& _aConfigPath)
+ {
+ return _aConfigPath.getModuleName();
+ }
+
+
+// -----------------------------------------------------------------------------
+// class CacheLine
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+
+ CacheLine::CacheLine(rtl::OUString const & _aModuleName)
+ : m_base(NULL)
+ , m_name(_aModuleName)
+ , m_nDataRefs(0)
+ {
+ }
+// -----------------------------------------------------------------------------
+
+ CacheLine::CacheLine(rtl::OUString const & _aModuleName, sharable::TreeFragment * _pSegment)
+ : m_base(_pSegment)
+ , m_name(_aModuleName)
+ , m_nDataRefs(0)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+
+ void CacheLine::setBase(sharable::TreeFragment * _base)
+ {
+ OSL_PRECOND(m_base == NULL, "CacheLine: Data base address was already set");
+ OSL_PRECOND( _base != NULL, "CacheLine: Cannot set NULL base address");
+ m_base = _base;
+ }
+// -----------------------------------------------------------------------------
+
+ rtl::Reference<CacheLine> CacheLine::createAttached( rtl::OUString const & _aModuleName,
+ sharable::TreeFragment * _aSegment
+ ) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ if (_aModuleName.getLength() == 0)
+ {
+ OSL_ENSURE(false, "Cannot make a cache line without a name");
+ return NULL;
+ }
+ if (_aSegment == NULL)
+ {
+ OSL_ENSURE(false, "Cannot attach a cache line to a NULL segment");
+ return NULL;
+ }
+
+ rtl::Reference<CacheLine> xResult = new CacheLine(_aModuleName,_aSegment);
+
+ return xResult;
+ }
+// -----------------------------------------------------------------------------
+
+ rtl::Reference<CacheLine> CacheLine::createNew( rtl::OUString const & _aModuleName
+ ) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ if (_aModuleName.getLength() == 0)
+ {
+ OSL_ENSURE(false, "Cannot make a cache line without a name");
+ return NULL;
+ }
+
+ rtl::Reference<CacheLine> xResult = new CacheLine(_aModuleName);
+
+ return xResult;
+ }
+// -------------------------------------------------------------------------
+
+ rtl::OUString CacheLine::getModuleName() const
+ {
+ return m_name;
+ }
+// -----------------------------------------------------------------------------
+
+ sharable::TreeFragment * CacheLine::getPartialTree(configuration::AbsolutePath const& aConfigName) const
+ {
+ sharable::Node * parent = internalGetNode(aConfigName.getParentPath());
+
+ if (parent != 0 && parent->isSet())
+ return parent->set.getElement(aConfigName.getLocalName().getName());
+ else
+ return NULL;
+ }
+// -----------------------------------------------------------------------------
+
+ bool CacheLine::hasDefaults() const
+ {
+ return m_base != 0 && m_base->hasDefaultsAvailable();
+ }
+// -----------------------------------------------------------------------------
+ sharable::Node * CacheLine::internalGetNode(configuration::AbsolutePath const& aConfigName) const
+ {
+ OSL_ASSERT(m_base != 0);
+ sharable::Node * node = m_base->getRootNode();
+ OSL_ASSERT(node != 0);
+ std::vector< configuration::Path::Component >::const_reverse_iterator i(
+ aConfigName.begin());
+ OSL_ASSERT(
+ i != aConfigName.end() && node->getName() == i->getInternalName());
+ while (node != 0 && ++i != aConfigName.end()) {
+ node = node->getSubnode(i->getName());
+ }
+ return node;
+ }
+// -----------------------------------------------------------------------------
+
+ sharable::Node * CacheLine::getNode(configuration::AbsolutePath const& aConfigName) const
+ {
+ return internalGetNode(aConfigName);
+ }
+// -------------------------------------------------------------------------
+
+ sharable::TreeFragment * CacheLine::setComponentData( backend::ComponentDataStruct const & _aComponentInstance,
+ bool _bWithDefaults
+ ) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ OSL_PRECOND(_aComponentInstance.data.get(), "CacheLine::insertDefaults: inserting NULL defaults !");
+ OSL_PRECOND(_aComponentInstance.name == this->getModuleName(),"Data location does not match module");
+
+ OSL_PRECOND(base() == NULL, "Data is already loaded");
+
+ if (base() == NULL) // no data yet
+ {
+ this->setBase( data::buildTree(_aComponentInstance.data->getName(), *_aComponentInstance.data, _bWithDefaults) );
+ }
+
+ return this->base();
+ }
+// -----------------------------------------------------------------------------
+
+ sharable::TreeFragment * CacheLine::insertDefaults( backend::NodeInstance const & _aDefaultInstance
+ ) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ OSL_PRECOND(_aDefaultInstance.data().get(), "CacheLine::insertDefaults: inserting NULL defaults !");
+ OSL_PRECOND(_aDefaultInstance.root().getDepth() == 1, "Should have complete component to fill tree with defaults");
+ OSL_PRECOND(_aDefaultInstance.root().getModuleName() == this->getModuleName(),"Data location does not match module");
+
+ OSL_PRECOND(m_base != NULL, "Data must already be loaded to insert defaults");
+
+ if (m_base != NULL)
+ {
+ data::mergeDefaults(m_base,*_aDefaultInstance.data());
+ }
+
+ return m_base;
+ }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+ ExtendedCacheLine::ExtendedCacheLine(rtl::OUString const & _aModuleName)
+ : CacheLine(_aModuleName)
+ , m_pPending()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+
+ ExtendedCacheLine::ExtendedCacheLine(rtl::OUString const & _aModuleName,
+ sharable::TreeFragment * _aSegment)
+ : CacheLine(_aModuleName,_aSegment)
+ , m_pPending()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+
+ rtl::Reference<ExtendedCacheLine> ExtendedCacheLine::createAttached( rtl::OUString const & _aModuleName,
+ sharable::TreeFragment * _aSegment
+ ) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ if (_aModuleName.getLength() == 0)
+ {
+ OSL_ENSURE(false, "Cannot make a cache line without a name");
+ return NULL;
+ }
+ if (_aSegment == NULL)
+ {
+ OSL_ENSURE(false, "Cannot attach a cache line to a NULL segment");
+ return NULL;
+ }
+
+ rtl::Reference<ExtendedCacheLine> xResult = new ExtendedCacheLine(_aModuleName,_aSegment);
+
+ return xResult;
+ }
+// -----------------------------------------------------------------------------
+
+ rtl::Reference<ExtendedCacheLine> ExtendedCacheLine::createNew( rtl::OUString const & _aModuleName
+ ) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ if (_aModuleName.getLength() == 0)
+ {
+ OSL_ENSURE(false, "Cannot make a cache line without a name");
+ return NULL;
+ }
+
+ rtl::Reference<ExtendedCacheLine> xResult = new ExtendedCacheLine(_aModuleName);
+
+ return xResult;
+ }
+// -------------------------------------------------------------------------
+
+ void ExtendedCacheLine::addPending(backend::ConstUpdateInstance const & _anUpdate) SAL_THROW((com::sun::star::uno::RuntimeException))
+ {
+ configuration::AbsolutePath aRootLocation = _anUpdate.root();
+
+ OSL_PRECOND(!aRootLocation.isRoot(),"Pending change cannot be located at root");
+ OSL_PRECOND(aRootLocation.getModuleName() == this->getModuleName(),"Pending change location does not match module");
+
+ OSL_PRECOND(_anUpdate.data() != NULL,"Adding NULL 'pending' change");
+ OSL_PRECOND(_anUpdate.data()->getNodeName() == aRootLocation.getLocalName().getName(),
+ "Path to pending change does not match change name");
+
+ using std::auto_ptr;
+
+ // first make the _pSubtreeChange a full tree starting at the module root
+ auto_ptr<SubtreeChange> pRootChange;
+ SubtreeChange *pExistingEntry = NULL;
+
+ std::vector<configuration::Path::Component>::const_reverse_iterator last = aRootLocation.end();
+
+ OSL_ASSERT(last != aRootLocation.begin());
+ --last;
+
+ for (std::vector<configuration::Path::Component>::const_reverse_iterator it = aRootLocation.begin();
+ it != last;
+ ++it)
+ {
+ OSL_ASSERT( it != aRootLocation.end());
+ OSL_ASSERT( it+1 != aRootLocation.end());
+ // We need to create a new SubtreeChange
+ rtl::OUString const aChangeName = it->getName();
+ rtl::OUString const aElementTypeName = (it+1)->getTypeName();
+
+ auto_ptr<SubtreeChange> pNewChange =
+ OTreeChangeFactory::createDummyChange(aChangeName, aElementTypeName);
+
+ if (pExistingEntry == NULL)
+ {
+ OSL_ASSERT(pRootChange.get() == NULL);
+
+ pRootChange = pNewChange;
+ pExistingEntry = pRootChange.get();
+ }
+ else
+ {
+ OSL_ASSERT(pRootChange.get() != NULL);
+
+ pExistingEntry->addChange(base_ptr(pNewChange));
+
+ Change* pChange = pExistingEntry->getChange(aChangeName);
+ pExistingEntry = static_cast<SubtreeChange*>(pChange);
+
+ OSL_ENSURE(dynamic_cast< SubtreeChange * >(pChange) != 0, "ERROR: Cannot recover change just added");
+ }
+ }
+
+ auto_ptr<SubtreeChange> pAddedChange( new SubtreeChange(*_anUpdate.data(), treeop::DeepChildCopy()) );
+
+ if (aRootLocation.getDepth() > 1)
+ {
+ OSL_ASSERT(pRootChange.get() != NULL && pExistingEntry != NULL);
+
+ // the _pSubtreeChange did not start at root, so add its clone to the built dummies
+ pExistingEntry->addChange(base_ptr(pAddedChange));
+ }
+ else
+ {
+ OSL_ASSERT(pRootChange.get() == NULL && pExistingEntry == NULL);
+
+ // the _pSubtreeChange starts at root, so just reset pRootChange
+ pRootChange = pAddedChange;
+ }
+ OSL_ASSERT(pRootChange.get() != NULL);
+
+ if (m_pPending.get() == NULL)
+ {
+ // no merge is need, because the existing pending changes are empty
+ m_pPending = pRootChange;
+ }
+ else
+ {
+ try
+ {
+ // We need to merge the new rebased changes into the m_pPending
+ combineUpdates(*pRootChange,*m_pPending);
+ }
+ catch (configuration::Exception& e)
+ {
+ rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM("Update cache for module: Could not add pending changes at"));
+
+ sMessage += aRootLocation.toString();
+
+ sMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(". Internal Exception:")) + e.message();
+
+ throw uno::RuntimeException(sMessage,0);
+ }
+ }
+
+ OSL_POSTCOND(m_pPending.get() != NULL, "Could not insert new pending changes");
+ }
+// -----------------------------------------------------------------------------
+
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/treecache/cacheline.hxx b/configmgr/source/treecache/cacheline.hxx
new file mode 100644
index 000000000000..faf380533cdf
--- /dev/null
+++ b/configmgr/source/treecache/cacheline.hxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cacheline.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CACHELINE_HXX
+#define CONFIGMGR_CACHELINE_HXX
+
+#include "configpath.hxx"
+#include "requesttypes.hxx"
+#include "utility.hxx"
+#include "treefragment.hxx"
+#include <osl/interlck.h>
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+
+namespace configmgr
+{
+ /** This object represents a cache line for a single configuration tree
+ */
+ class CacheLine: public salhelper::SimpleReferenceObject
+ {
+ public:
+ // create a new CacheLine for the given component name
+ static rtl::Reference<CacheLine>
+ createNew( rtl::OUString const & _aModuleName );
+
+ // create a new CacheLine attached to the given memory location
+ static rtl::Reference<CacheLine>
+ createAttached( rtl::OUString const & _aModuleName, sharable::TreeFragment * _aLocation );
+
+ bool hasDefaults() const;
+
+ bool isEmpty() const { return m_base == NULL; }
+ sharable::TreeFragment * getTreeAddress() const { return m_base; }
+ sharable::TreeFragment * getPartialTree(configuration::AbsolutePath const & _aTemplatePath ) const;
+ sharable::Node * getNode(configuration::AbsolutePath const & _aPath) const;
+
+ sharable::TreeFragment * setComponentData( backend::ComponentDataStruct const & _aComponentInstance,
+ bool _bWithDefaults
+ ) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ sharable::TreeFragment * insertDefaults( backend::NodeInstance const & _aDefaultInstance
+ ) SAL_THROW((com::sun::star::uno::RuntimeException));
+
+ // get the module name for this component
+ rtl::OUString getModuleName() const;
+
+ /// add a client for this module's data
+ oslInterlockedCount clientReferences() const { return m_nDataRefs; }
+ /// add a client for this modules data
+ oslInterlockedCount clientAcquire() { return osl_incrementInterlockedCount(&m_nDataRefs); }
+ /// subtract a client for this modules data
+ oslInterlockedCount clientRelease() { return osl_decrementInterlockedCount(&m_nDataRefs); }
+
+ protected:
+ // create a new CacheLine attached to the given memory location
+ explicit
+ CacheLine( rtl::OUString const & _aModuleName, sharable::TreeFragment * _pLocation );
+
+ // create a new empty CacheLine for the given component name
+ explicit
+ CacheLine( rtl::OUString const & _aModuleName );
+
+ sharable::Node * internalGetNode(configuration::AbsolutePath const & _rPath) const;
+
+ sharable::TreeFragment * base() const { return m_base; }
+ void setBase(sharable::TreeFragment * _base);
+
+ private:
+ sharable::TreeFragment * m_base;
+ rtl::OUString m_name;
+
+ oslInterlockedCount m_nDataRefs; /// the number of clients on this modules data
+ };
+
+////////////////////////////////////////////////////////////////////////////////
+ /** This object represents a cache line and associated data for a single configuration tree
+ */
+ class ExtendedCacheLine : public CacheLine
+ {
+ public:
+ // create a new CacheLine for the given component name
+ static rtl::Reference<ExtendedCacheLine>
+ createNew( rtl::OUString const & _aModuleName );
+
+ // create a new CacheLine attached to the given memory location
+ static rtl::Reference<ExtendedCacheLine>
+ createAttached( rtl::OUString const & _aModuleName,
+ sharable::TreeFragment * _aLocation );
+
+ // management of pending changes
+ bool hasPending() const {return m_pPending.get() != NULL;}
+
+ void addPending(backend::ConstUpdateInstance const & _anUpdate) SAL_THROW((com::sun::star::uno::RuntimeException));
+ std::auto_ptr<SubtreeChange> releasePending() {return m_pPending;}
+
+ private:
+ // create a new empty CacheLine for the given component name
+ explicit
+ ExtendedCacheLine( rtl::OUString const & _aModuleName );
+
+ // create a new CacheLine attached to the given memory location
+ explicit
+ ExtendedCacheLine( rtl::OUString const & _aModuleName,
+ sharable::TreeFragment * _aLocation );
+
+ private:
+ std::auto_ptr<SubtreeChange> m_pPending;
+ };
+
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/treecache/cachemulticaster.cxx b/configmgr/source/treecache/cachemulticaster.cxx
new file mode 100644
index 000000000000..4aa2d7c93180
--- /dev/null
+++ b/configmgr/source/treecache/cachemulticaster.cxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachemulticaster.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "cachemulticaster.hxx"
+#include "treemanager.hxx"
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+#ifndef INCLUDED_FUNCTIONAL
+#include <functional>
+#define INCLUDED_FUNCTIONAL
+#endif
+
+namespace configmgr
+{
+// ---------------------------------------------------------------------------
+ namespace backend
+ {
+// ---------------------------------------------------------------------------
+namespace
+{
+// manually implemented helpers, as rtl::References don't work well with std binders
+
+// ---------------------------------------------------------------------------
+
+ // replacing std::bind2nd( std::mem_fun(&TreeManager::componentCreated), _aComponentName )
+ struct NotifyCreated : std::unary_function<rtl::Reference<TreeManager>,void>
+ {
+ ComponentRequest const & m_arg;
+
+ NotifyCreated(ComponentRequest const * _pComponent) SAL_THROW(())
+ : m_arg(*_pComponent)
+ {}
+
+ void operator()(rtl::Reference<TreeManager> const & _xListener) const SAL_THROW(())
+ { _xListener->componentCreated(m_arg); }
+ };
+// ---------------------------------------------------------------------------
+
+ // replacing std::bind2nd( std::mem_fun(&TreeManager::componentChanged), _aComponentName )
+ struct NotifyChanged : std::unary_function<rtl::Reference<TreeManager>,void>
+ {
+ UpdateRequest const & m_arg;
+
+ NotifyChanged(UpdateRequest const * _pUpdate) SAL_THROW(())
+ : m_arg(*_pUpdate)
+ {}
+
+ void operator()(rtl::Reference<TreeManager> const & _xListener) const SAL_THROW(())
+ { _xListener->componentChanged(m_arg); }
+ };
+// ---------------------------------------------------------------------------
+} // anonymous namespace
+//----------------------------------------------------------------------------
+
+CacheChangeMulticaster::CacheChangeMulticaster()
+: m_aMutex()
+, m_aListeners()
+{
+}
+// ---------------------------------------------------------------------------
+
+CacheChangeMulticaster::~CacheChangeMulticaster()
+{
+ OSL_ENSURE( m_aListeners.empty(), "Forgot to dispose multicaster" );
+}
+// ---------------------------------------------------------------------------
+
+inline std::list< rtl::Reference<TreeManager> > CacheChangeMulticaster::copyListenerList()
+{
+ osl::MutexGuard aListGuard(m_aMutex);
+ return m_aListeners;
+}
+// ---------------------------------------------------------------------------
+
+void CacheChangeMulticaster::notifyCreated(ComponentRequest const & _aComponent) SAL_THROW(())
+{
+ std::list< rtl::Reference<TreeManager> > aNotifyListeners( this->copyListenerList() );
+
+ std::for_each( aNotifyListeners.begin(), aNotifyListeners.end(), NotifyCreated(&_aComponent) );
+}
+// ---------------------------------------------------------------------------
+
+void CacheChangeMulticaster::notifyChanged(UpdateRequest const & _anUpdate) SAL_THROW(())
+{
+ std::list< rtl::Reference<TreeManager> > aNotifyListeners( this->copyListenerList() );
+
+ std::for_each( aNotifyListeners.begin(), aNotifyListeners.end(), NotifyChanged(&_anUpdate) );
+}
+// ---------------------------------------------------------------------------
+
+void CacheChangeMulticaster::addListener(rtl::Reference<TreeManager> _xListener) SAL_THROW(())
+{
+ osl::MutexGuard aListGuard(m_aMutex);
+
+ OSL_PRECOND(std::find(m_aListeners.begin(),m_aListeners.end(),_xListener) == m_aListeners.end(),
+ "WARNING: Cache Change Listener was already registered - will be notified multiply.");
+
+ OSL_PRECOND(_xListener.is(), "ERROR: trying to register a NULL listener");
+
+ if (_xListener.is())
+ m_aListeners.push_front(_xListener);
+}
+// ---------------------------------------------------------------------------
+
+void CacheChangeMulticaster::removeListener(rtl::Reference<TreeManager> _xListener) SAL_THROW(())
+{
+ osl::MutexGuard aListGuard(m_aMutex);
+ m_aListeners.remove(_xListener);
+}
+// ---------------------------------------------------------------------------
+ } // namespace backend
+
+// ---------------------------------------------------------------------------
+} // namespace configmgr
diff --git a/configmgr/source/treecache/cachemulticaster.hxx b/configmgr/source/treecache/cachemulticaster.hxx
new file mode 100644
index 000000000000..4805c9077f12
--- /dev/null
+++ b/configmgr/source/treecache/cachemulticaster.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachemulticaster.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_BACKEND_CACHEMULTICASTER_HXX
+#define CONFIGMGR_BACKEND_CACHEMULTICASTER_HXX
+
+#include "sal/config.h"
+
+#include <list>
+
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+
+#include "utility.hxx"
+
+namespace configmgr
+{
+ class TreeManager;
+
+ namespace backend
+ {
+ class ComponentRequest;
+ class UpdateRequest;
+// ---------------------------------------------------------------------------
+
+ /** Interface providing a multicasting service for changes to the cache
+ managed by a <type>CacheController</type>
+ */
+ class CacheChangeMulticaster
+ {
+ public:
+ CacheChangeMulticaster();
+ virtual ~CacheChangeMulticaster();
+
+ /** notify a new component to all registered listeners.
+ <p> Must be called after the component has been created in the cache.</p>
+ */
+ void notifyCreated(ComponentRequest const & _aComponentName) SAL_THROW(());
+
+ /** notify changed data to all registered listeners.
+ <p> Must be called after the change has been applied to the cache
+ and before any subsequent changes to the same component.</p>
+ */
+ void notifyChanged(UpdateRequest const & _anUpdate) SAL_THROW(());
+
+ // notification support.
+ /// register a listener for observing changes to the cached data
+ void addListener(rtl::Reference<TreeManager> _xListener) SAL_THROW(());
+ /// unregister a listener previously registered
+ void removeListener(rtl::Reference<TreeManager> _xListener) SAL_THROW(());
+ private:
+ std::list< rtl::Reference<TreeManager> > copyListenerList();
+
+ osl::Mutex m_aMutex;
+ std::list< rtl::Reference<TreeManager> > m_aListeners;
+ };
+// ---------------------------------------------------------------------------
+ } // namespace backend
+
+// ---------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/treecache/cachewritescheduler.cxx b/configmgr/source/treecache/cachewritescheduler.cxx
new file mode 100644
index 000000000000..e199bef73236
--- /dev/null
+++ b/configmgr/source/treecache/cachewritescheduler.cxx
@@ -0,0 +1,216 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachewritescheduler.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "cachewritescheduler.hxx"
+#include "cachecontroller.hxx"
+#include "tracer.hxx"
+
+
+namespace configmgr
+{
+// =========================================================================
+OCacheWriteScheduler::~OCacheWriteScheduler()
+{
+ stopAndWriteCache();// last chance - violates precond
+}
+
+void OCacheWriteScheduler::stopAndWriteCache()
+{
+ OSL_ASSERT(UnoApiLock::isHeld());
+ CFG_TRACE_INFO("Cancelling all cache writings, Stopping timer");
+
+ if (m_xTimer.isValid())
+ m_xTimer->dispose(); // just to be sure
+
+ runWriter();
+
+ m_aWriteList.clear();
+}
+
+// -------------------------------------------------------------------------
+void OCacheWriteScheduler::Timer::onShot()
+{
+ UnoApiLock aLock;
+
+ if (pParent)
+ pParent->onTimerShot();
+ else
+ CFG_TRACE_WARNING("Timer shot for disposed cache writer");
+}
+
+// -----------------------------------------------------------------------------
+void OCacheWriteScheduler::onTimerShot()
+{
+ //m_aTimer.stop();
+
+ CFG_TRACE_INFO("Write Timer invoked - executing write task");
+
+ try
+ {
+ runWriter();
+ CFG_TRACE_INFO_NI("Write timer: writing ended");
+ }
+ catch (...)
+ {
+ CFG_TRACE_ERROR_NI("Write timer: writing failed with an unknown exception");
+ OSL_ENSURE(false, "ERROR: Unknown Exception left a writer");
+ }
+
+ TimeStamp aNewTime = implGetScheduleTime(TimeStamp::getCurrentTime(), m_aWriteInterval);
+
+ implStartBefore(aNewTime);
+}
+// -------------------------------------------------------------------------
+void OCacheWriteScheduler::runWriter()
+{
+ // Write Cache
+ OSL_ASSERT(UnoApiLock::isHeld());
+ CFG_TRACE_INFO("Running write operations");
+
+ CacheWriteList aPendingWrites;
+ m_aWriteList.swap(aPendingWrites);
+
+ CFG_TRACE_INFO_NI("Found %d sections to write", int(aPendingWrites.size()));
+ for (CacheWriteList::iterator it = aPendingWrites.begin();
+ it != aPendingWrites.end();
+ ++it)
+ {
+ RequestOptions aTaskOption = *it;
+ try
+ {
+ writeOneTreeFoundByOption(aTaskOption);
+ }
+ catch (uno::Exception& e)
+ {
+ (void)e;
+ CFG_TRACE_ERROR_NI("TreeCacheWriteScheduler: Attempt to write data failed - error is '%s' (currently ignored)",OUSTRING2ASCII(e.Message));
+ }
+ }
+ // m_aWriteList.clear();
+ CFG_TRACE_INFO_NI("DONE: Running write operations");
+}
+
+// -----------------------------------------------------------------------------
+void OCacheWriteScheduler::writeOneTreeFoundByOption(RequestOptions const& _aOptions) SAL_THROW((com::sun::star::uno::Exception))
+{
+ CFG_TRACE_INFO("Writeing one cache tree for user '%s' with locale '%s'",
+ OUSTRING2ASCII(_aOptions.getEntity()),
+ OUSTRING2ASCII(_aOptions.getLocale()));
+
+ rtl::Reference<CacheLoadingAccess> aCache;
+ aCache = m_rTreeManager.m_aCacheMap.get(_aOptions);
+
+ if (aCache.is())
+ {
+ CFG_TRACE_INFO_NI("- Found matching data container - starting write task");
+ if (!m_rTreeManager.saveAllPendingChanges(aCache,_aOptions))
+ {
+ m_aWriteList.insert(_aOptions);
+
+ CFG_TRACE_INFO_NI("- Write task incomplete -reregistering");
+ }
+ // we got a pending list with pointers from TreeInfo.
+ }
+ else
+ {
+ CFG_TRACE_WARNING_NI("- Data container (TreeInfo) to write not found: Ignoring task");
+ }
+
+ CFG_TRACE_INFO_NI("Removing written cache tree (for user '%s' with locale '%s')",
+ OUSTRING2ASCII(_aOptions.getEntity()),
+ OUSTRING2ASCII(_aOptions.getLocale()));
+}
+
+// -----------------------------------------------------------------------------
+bool OCacheWriteScheduler::clearTasks(RequestOptions const& _aOptions)
+{
+ // sadly list::remove doesn't return an indication of what it did
+ bool bFound = m_aWriteList.erase(_aOptions) !=0;
+ if (bFound)
+ {
+ CFG_TRACE_INFO("Write Scheduler: Dropped cache tree (for user '%s' with locale '%s') from task list",
+ OUSTRING2ASCII(_aOptions.getEntity()),
+ OUSTRING2ASCII(_aOptions.getLocale()));
+ }
+
+ return bFound;
+}
+
+// -----------------------------------------------------------------------------
+// should be called guarded only
+void OCacheWriteScheduler::implStartBefore(TimeStamp const& _aTime)
+{
+ CFG_TRACE_INFO("Triggering write timer");
+ // check if we were cleared
+ if (!m_aWriteList.empty())
+ {
+ if (!m_xTimer->isTicking())
+ {
+ m_xTimer->setAbsoluteTime(_aTime.getTimeValue());
+
+ if (!m_xTimer->isTicking())
+ m_xTimer->start();
+
+ OSL_ASSERT( m_xTimer->isTicking() );
+ }
+ CFG_TRACE_INFO_NI("- Write timer running - next execution in %d seconds", int (m_xTimer->getRemainingTime().Seconds) );
+ CFG_TRACE_INFO_NI("- %d write tasks are pending", int(m_aWriteList.size()) );
+ }
+ else
+ {
+ m_xTimer->stop();
+ CFG_TRACE_INFO_NI("- Stopped timer - no more open write tasks");
+ }
+}
+
+// -----------------------------------------------------------------------------
+void OCacheWriteScheduler::scheduleWrite(backend::ComponentRequest _aComponent) SAL_THROW((com::sun::star::uno::Exception))
+{
+ OSL_ENSURE(_aComponent.getOptions().hasLocale(), "ERROR: OTreeDisposeScheduler: cannot handle complete user scheduling");
+
+ CFG_TRACE_INFO("Scheduling cache write for user '%s' with locale '%s'",
+ OUSTRING2ASCII(_aComponent.getOptions().getEntity()),
+ OUSTRING2ASCII(_aComponent.getOptions().getLocale()));
+
+ // lasy writing
+ m_aWriteList.insert(_aComponent.getOptions());
+
+ TimeStamp aNewTime = implGetScheduleTime(TimeStamp::getCurrentTime(), m_aWriteInterval);
+ implStartBefore(aNewTime);
+}
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/treecache/cachewritescheduler.hxx b/configmgr/source/treecache/cachewritescheduler.hxx
new file mode 100644
index 000000000000..135b897da634
--- /dev/null
+++ b/configmgr/source/treecache/cachewritescheduler.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cachewritescheduler.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CACHEWRITESCHEDULER_HXX
+#define CONFIGMGR_CACHEWRITESCHEDULER_HXX
+
+#include "datalock.hxx"
+#include "requestoptions.hxx"
+#include "timestamp.hxx"
+#include "utility.hxx"
+
+#ifndef INCLUDED_SET
+#include <set>
+#define INCLUDED_SET
+#endif
+#include <vos/timer.hxx>
+#ifndef _VOS_REF_HXX_
+#include <vos/ref.hxx>
+
+#endif
+#include <osl/mutex.hxx>
+
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+ class RequestOptions;
+ namespace backend { class ComponentRequest; class CacheController; }
+
+ // Write down the Cache, much less complex than caching Nodes
+ // (better control)
+ class OCacheWriteScheduler
+ {
+ typedef std::set< RequestOptions, lessRequestOptions > CacheWriteList; // fire and forget!
+
+ class Timer : public vos::OTimer
+ {
+ public:
+ OCacheWriteScheduler* pParent;
+
+ Timer(OCacheWriteScheduler& _rParent) : pParent(&_rParent) {};
+
+ // vos::OTimer
+ virtual void SAL_CALL onShot();
+
+ // stop the scheduling
+ void dispose() {
+ stop();
+ pParent = NULL;
+ }
+
+ };
+ friend void Timer::onShot();
+ private:
+ vos::ORef<Timer> m_xTimer;
+ backend::CacheController &m_rTreeManager;
+ CacheWriteList m_aWriteList;
+ TimeInterval m_aWriteInterval;
+
+ public:
+ //-------- Construction and destruction -----------------------------------
+ explicit
+ OCacheWriteScheduler(backend::CacheController& _rTreeManager, TimeInterval const& _aWriteInterval)
+ : m_rTreeManager(_rTreeManager)
+ , m_aWriteInterval(_aWriteInterval)
+ {
+ m_xTimer = new Timer(*this);
+ }
+ ~OCacheWriteScheduler();
+
+ //-------- Delay and Interval ---------------------------------------------
+ /// retrieves the recurrance interval used for cleanup
+ TimeInterval const& getWriteInterval() const
+ {
+ UnoApiLock aLock;
+ return m_aWriteInterval;
+ }
+
+ static TimeStamp implGetScheduleTime(TimeStamp const& aBaseTime, TimeInterval const& aDelay)
+ {
+ return aBaseTime + aDelay;
+ }
+ //-------- Control of execution ------------------------------------------
+ void scheduleWrite(backend::ComponentRequest _aComponent) SAL_THROW((com::sun::star::uno::Exception));
+
+ /// stop pending activities for one set of options (do not discard them)
+ bool clearTasks(RequestOptions const& _xOptions);
+
+ /// stop and discard pending activities
+ void stopAndWriteCache();
+ private:
+ // vos::OTimer
+ void onTimerShot();
+
+ void runWriter();
+ void implStartBefore(TimeStamp const& _aTime);
+ void writeOneTreeFoundByOption(RequestOptions const& _aOption) SAL_THROW((com::sun::star::uno::Exception));
+ };
+} // namespace configmgr
+
+#endif // CONFIGMGR_DISPOSETIMER_HXX
+
diff --git a/configmgr/source/treecache/disposetimer.cxx b/configmgr/source/treecache/disposetimer.cxx
new file mode 100644
index 000000000000..5f6e9a8603e4
--- /dev/null
+++ b/configmgr/source/treecache/disposetimer.cxx
@@ -0,0 +1,305 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: disposetimer.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "datalock.hxx"
+#include "disposetimer.hxx"
+#include "cachecontroller.hxx"
+#include "configexcept.hxx"
+#include "tracer.hxx"
+#include <osl/diagnose.h>
+
+
+namespace configmgr
+{
+//==========================================================================
+//=
+//==========================================================================
+
+
+void OTreeDisposeScheduler::scheduleCleanup(RequestOptions const& _aOptions)
+{
+ OSL_ENSURE(_aOptions.hasLocale(), "ERROR: OTreeDisposeScheduler: cannot handle complete user scheduling");
+
+ CFG_TRACE_INFO("Scheduling data cleanup for user '%s' with locale '%s'",
+ OUSTRING2ASCII(_aOptions.getEntity()),
+ OUSTRING2ASCII(_aOptions.getLocale()));
+
+ CFG_TRACE_INFO_NI("- Cleanup will be started in about %d seconds", int(m_aCleanupDelay.getTimeValue().Seconds));
+
+ TimeStamp aNewTime = implGetCleanupTime(TimeStamp::getCurrentTime(), m_aCleanupDelay);
+ OSL_ASSERT(!aNewTime.isNever());
+
+ TimeStamp aScheduleTime = implAddTask(_aOptions, aNewTime);
+
+ OSL_ASSERT(aScheduleTime <= aNewTime);
+ OSL_ASSERT(!aScheduleTime.isNever());
+
+ implStartBefore(aNewTime);
+}
+// -------------------------------------------------------------------------
+
+static
+inline
+bool equivalentOptions(RequestOptions const& lhs, RequestOptions const& rhs)
+{
+ lessRequestOptions lessThan;
+ return ! (lessThan(lhs,rhs) || lessThan(rhs,lhs));
+}
+// -------------------------------------------------------------------------
+
+void OTreeDisposeScheduler::stopAndClearTasks()
+{
+ CFG_TRACE_INFO("Cancelling all data cleanup tasks, Stopping Cleanup timer");
+ CFG_TRACE_INFO_NI("- %d cleanup tasks were pending", int(m_aAgenda.size()) );
+
+ if (m_xTimer.isValid())
+ m_xTimer->dispose(); // just to be sure
+
+ m_aAgenda.clear();
+}
+// -------------------------------------------------------------------------
+
+std::pair<bool,RequestOptions> OTreeDisposeScheduler::getTask(TimeStamp const& _aActualTime, TimeStamp& _rNextTime)
+{
+ OSL_ASSERT( _rNextTime.isNever() ); // internal contract, we set this only in the positive case
+
+ std::pair<bool,RequestOptions> aTask( false, RequestOptions() );
+
+ if (!m_aAgenda.empty())
+ {
+ Agenda::iterator const it = m_aAgenda.begin();
+
+ if (it->first <= _aActualTime)
+ {
+ aTask = std::make_pair(true,it->second);
+ m_aAgenda.erase(it);
+ }
+ }
+
+ if (!m_aAgenda.empty())
+ {
+ Agenda::iterator const it = m_aAgenda.begin();
+
+ _rNextTime = it->first;
+ }
+
+ return aTask;
+}
+// -------------------------------------------------------------------------
+
+void OTreeDisposeScheduler::Timer::onShot()
+{
+ UnoApiLock aLock;
+ if (pParent)
+ pParent->onTimerShot();
+}
+// -------------------------------------------------------------------------
+
+void OTreeDisposeScheduler::onTimerShot()
+{
+ CFG_TRACE_INFO("Cleanup Timer invoked - executing dispose task");
+
+ TimeStamp aActualTime = TimeStamp::getCurrentTime();
+ TimeStamp aNextTime = implGetCleanupTime(aActualTime, getCleanupInterval());
+
+ try
+ {
+ TimeStamp aNextDisposeTime = runDisposer(aActualTime);
+
+ if (aNextTime < aNextDisposeTime)
+ aNextTime = aNextDisposeTime;
+ }
+
+ catch (uno::Exception& )
+ {
+ OSL_ENSURE(false, "ERROR: UNO Exception left a disposer");
+ }
+ catch (configuration::Exception& )
+ {
+ OSL_ENSURE(false, "ERROR: configuration::Exception left a disposer");
+ }
+ catch (...)
+ {
+ OSL_ENSURE(false, "ERROR: Unknown Exception left a disposer");
+ }
+
+ OSL_ASSERT(UnoApiLock::isHeld());
+ implStartBefore(aNextTime);
+}
+// -------------------------------------------------------------------------
+
+// this really should be a member of the TreeManager (see TreeManager::disposeOne etc.)
+TimeStamp OTreeDisposeScheduler::runDisposer(TimeStamp const& _aActualTime)
+{
+ TimeStamp aNextTime = TimeStamp::never();
+ OSL_ASSERT(aNextTime.isNever());
+
+ OSL_ASSERT(UnoApiLock::isHeld());
+
+ std::pair<bool,RequestOptions> aTask = this->getTask( _aActualTime, aNextTime );
+ if (aTask.first)
+ {
+ RequestOptions & rTaskOptions = aTask.second;
+
+ CFG_TRACE_INFO("Found cleanup task for user %s and locale %s",
+ OUSTRING2ASCII(rTaskOptions.getEntity()),
+ OUSTRING2ASCII(rTaskOptions.getLocale()));
+
+ rtl::Reference<CacheLoadingAccess> aCache = m_rTreeManager.m_aCacheMap.get(rTaskOptions);
+ if (aCache.is())
+ {
+ CFG_TRACE_INFO_NI("- Found matching data container (TreeInfo) - collecting data");
+
+ std::vector< rtl::Reference<CacheLine> > aDisposeList;
+
+ TimeStamp aNextTaskTime = aCache->collectDisposeList(aDisposeList, _aActualTime, m_aCleanupDelay);
+
+ CFG_TRACE_INFO_NI("- Found %d module trees to dispose", int(aDisposeList.size()) );
+
+ if (!aNextTaskTime.isNever())
+ {
+ OSL_ENSURE( !aCache->isEmpty(), "ERROR: Empty TreeInfo returning finite dispose time");
+
+ // repost with new time
+ OSL_ASSERT(UnoApiLock::isHeld());
+
+ CFG_TRACE_INFO_NI("- Rescheduling current option set" );
+
+ aNextTime = this->implAddTask(rTaskOptions,aNextTaskTime);
+ }
+
+ else if (aCache->isEmpty())// may have been the last one - check that
+ {
+ // currently it is not possible to release options which are
+ // because it is not save to delete the info if another thread is running in
+ // a read request
+ }
+ else
+ CFG_TRACE_INFO_NI("- Currently no more cleanup tasks for this options set" );
+
+ if (!aDisposeList.empty())
+ {
+ CFG_TRACE_INFO_NI("- Closing %d modules", int(aDisposeList.size()) );
+ m_rTreeManager.closeModules(aDisposeList,rTaskOptions);
+ }
+ else
+ CFG_TRACE_INFO_NI("- No modules trees to dispose");
+ }
+ else
+ CFG_TRACE_INFO_NI("- No matching data container (TreeInfo) found - task is obsolete");
+ }
+ else
+ CFG_TRACE_INFO("No eligible task found - may reschedule");
+
+ return aNextTime;
+}
+// -------------------------------------------------------------------------
+
+static inline
+TimeStamp getExpirationTime( vos::OTimer const& aTimer )
+{
+ OSL_ENSURE(aTimer.isTicking(), "Timer is already expired !");
+
+ // note: order ensures that result time may be earlier, but not later
+ TimeStamp const now ( TimeStamp::getCurrentTime() );
+ TimeInterval const left( aTimer.getRemainingTime() );
+ TimeStamp const expires = now + left;
+
+ return expires;
+}
+
+// -------------------------------------------------------------------------
+
+#if OSL_DEBUG_LEVEL > 0
+static
+void checkTimerStarted( vos::OTimer const& aTimer, TimeStamp const& _aLimit)
+{
+ const TimeInterval tolerance( vos::TTimeValue(1) ); // milliseconds
+ if (aTimer.isTicking())
+ {
+ TimeStamp const expires = getExpirationTime(aTimer);
+ TimeStamp const limit = _aLimit + tolerance;
+
+ OSL_ENSURE(expires <= limit, "Timer does not expire within expected time (tolerance 1 ms) !");
+ // OSL_ENSURE(expires <= _aLimit, "Timer does not expire within expected time !");
+ OSL_ENSURE(aTimer.isTicking(), "Timer just started already expired ?!");
+ }
+ else
+ {
+ OSL_ENSURE(false, "Timer just started is not ticking ?!");
+ }
+}
+#endif
+
+// -------------------------------------------------------------------------
+// should be called guarded only
+void OTreeDisposeScheduler::implStartBefore(TimeStamp const& _aTime)
+{
+ // check if we were cleared
+ if (!m_aAgenda.empty() && !_aTime.isNever())
+ {
+ if (!m_xTimer->isTicking() || _aTime < getExpirationTime(*m_xTimer))
+ {
+ m_xTimer->setAbsoluteTime(_aTime.getTimeValue());
+
+ if (!m_xTimer->isTicking()) m_xTimer->start();
+
+ OSL_DEBUG_ONLY( checkTimerStarted(*m_xTimer,_aTime) );
+ }
+ CFG_TRACE_INFO_NI("- Cleanup timer running - next execution in %d seconds", int (m_xTimer->getRemainingTime().Seconds) );
+ CFG_TRACE_INFO_NI("- %d cleanup tasks are pending", int(m_aAgenda.size()) );
+ }
+ else
+ {
+ m_xTimer->stop();
+ CFG_TRACE_INFO_NI("- Stopped timer - no more open cleanup tasks");
+ }
+}
+// -------------------------------------------------------------------------
+
+TimeStamp OTreeDisposeScheduler::implAddTask(RequestOptions const& _aOptions, TimeStamp const& _aTime)
+{
+ OSL_ASSERT(UnoApiLock::isHeld());
+
+ // try to insert after euivalent entries (but STL may ignore the hint)
+ Agenda::iterator where = m_aAgenda.upper_bound(_aTime);
+
+ m_aAgenda.insert(where, Agenda::value_type(_aTime,_aOptions));
+
+ OSL_ASSERT(!m_aAgenda.empty());
+
+ return m_aAgenda.begin()->first;
+}
+// -------------------------------------------------------------------------
+
+} // namespace
diff --git a/configmgr/source/treecache/disposetimer.hxx b/configmgr/source/treecache/disposetimer.hxx
new file mode 100644
index 000000000000..41c8e8681c57
--- /dev/null
+++ b/configmgr/source/treecache/disposetimer.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: disposetimer.hxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_DISPOSETIMER_HXX
+#define CONFIGMGR_DISPOSETIMER_HXX
+
+#include "timestamp.hxx"
+#include "requestoptions.hxx"
+#include <osl/mutex.hxx>
+#include <vos/timer.hxx>
+#include <vos/ref.hxx>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+#ifndef INCLUDED_UTILITY
+#include <utility>
+#define INCLUDED_UTILITY
+#endif
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+namespace uno = ::com::sun::star::uno;
+namespace lang = ::com::sun::star::lang;
+
+namespace configmgr
+{
+ namespace backend { class CacheController; }
+////////////////////////////////////////////////////////////////////////////////
+/* OTreeDisposeScheduler:
+ does something special????
+*/
+
+ class OTreeDisposeScheduler
+ {
+ typedef std::multimap< TimeStamp, RequestOptions, ltTimeStamp > Agenda;
+
+ class Timer : public vos::OTimer
+ {
+ public:
+ OTreeDisposeScheduler* pParent;
+
+ Timer(OTreeDisposeScheduler& _rParent) : pParent(&_rParent) {};
+
+ // vos::OTimer
+ virtual void SAL_CALL onShot();
+
+ // stop the scheduling
+ void dispose() {stop(); pParent = NULL;}
+ };
+ friend void Timer::onShot();
+
+ private:
+ Agenda m_aAgenda;
+ vos::ORef<Timer> m_xTimer;
+ backend::CacheController& m_rTreeManager;
+
+ TimeInterval m_aCleanupDelay;
+ TimeInterval m_aCleanupInterval;
+ public:
+ //-------- Construction and destruction -----------------------------------
+ explicit
+ OTreeDisposeScheduler(backend::CacheController& _rTreeManager, TimeInterval const& _aCleanupDelay)
+ : m_rTreeManager(_rTreeManager)
+ , m_aCleanupDelay(_aCleanupDelay)
+ , m_aCleanupInterval(_aCleanupDelay)
+ {
+ m_xTimer = new Timer(*this);
+ }
+
+ explicit
+ OTreeDisposeScheduler(backend::CacheController& _rTreeManager, TimeInterval const& _aCleanupDelay, TimeInterval const& _aCleanupInterval)
+ : m_rTreeManager(_rTreeManager)
+ , m_aCleanupDelay(_aCleanupDelay)
+ , m_aCleanupInterval(_aCleanupInterval)
+ {
+ m_xTimer = new Timer(*this);
+ }
+
+ ~OTreeDisposeScheduler() { stopAndClearTasks(); }
+
+ //-------- Delay and Interval ---------------------------------------------
+ /// sets the initial delay to be used for cleanup in the future, does not affect an already started process
+ void setCleanupDelay(TimeInterval const& _aCleanupDelay)
+ {
+ m_aCleanupDelay = _aCleanupDelay;
+ }
+
+ /// sets the initial delay and recurrance interval to be used for cleanup in the future, does not affect an already started process
+ void setCleanupDelay(TimeInterval const& _aCleanupDelay, TimeInterval const& _aCleanupInterval)
+ {
+ m_aCleanupDelay = _aCleanupDelay;
+ m_aCleanupInterval = _aCleanupInterval;
+ }
+
+ /// sets the recurrance interval to be used for cleanup in the future, does not affect an already started process
+ void setCleanupInterval(TimeInterval const& _aCleanupInterval)
+ {
+ m_aCleanupInterval = _aCleanupInterval;
+ }
+
+ /// retrieves the initial delay used for cleanup
+ TimeInterval const& getCleanupDelay() const
+ {
+ return m_aCleanupDelay;
+ }
+
+ /// retrieves the recurrance interval used for cleanup
+ TimeInterval const& getCleanupInterval() const
+ {
+ return m_aCleanupInterval;
+ }
+
+ //-------- Control of execution ------------------------------------------
+ /// ensure this will execute cleanup duties for _xOptions (no later than after getCleanupDelay() has elapsed)
+ void scheduleCleanup(RequestOptions const & _aOptions);
+
+ /// stop and discard pending activities
+ void stopAndClearTasks();
+
+ private:
+ // vos::OTimer
+ void onTimerShot();
+
+ std::pair<bool,RequestOptions> getTask(TimeStamp const& _aActualTime, TimeStamp& _aNextTime);
+
+ /// ensure this will execute cleanup duties for _xOptions (no later than after getCleanupDelay() has elapsed)
+ // TimeStamp fillDisposeList(CacheLoadingAccess & _aCache, DisposeList& _rList, TimeStamp const& aLimitTime)
+
+ TimeStamp runDisposer(TimeStamp const& _aActualTime);
+ private:
+ TimeStamp implAddTask(RequestOptions const& _xOptions, TimeStamp const& _aTime);
+ void implStartBefore(TimeStamp const& _aTime);
+
+ static TimeStamp implGetCleanupTime(TimeStamp const& aPostingTime, TimeInterval const& aDelay)
+ { return aPostingTime + aDelay; }
+ };
+
+
+////////////////////////////////////////////////////////////////////////////////
+} // namespace configmgr
+
+#endif // CONFIGMGR_DISPOSETIMER_HXX
+
diff --git a/configmgr/source/treecache/invalidatetree.cxx b/configmgr/source/treecache/invalidatetree.cxx
new file mode 100644
index 000000000000..b8d1afb4db07
--- /dev/null
+++ b/configmgr/source/treecache/invalidatetree.cxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: invalidatetree.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+
+#include "cachecontroller.hxx"
+#include "change.hxx"
+#include "valuenode.hxx"
+#include "updatehelper.hxx"
+#include "treeactions.hxx"
+#include "tracer.hxx"
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+
+namespace configmgr
+{
+
+ namespace container = com::sun::star::container;
+// -----------------------------------------------------------------------------
+// ------------------------------- invalidateTree -------------------------------
+// -----------------------------------------------------------------------------
+
+namespace backend
+{
+// -----------------------------------------------------------------------------
+std::auto_ptr<SubtreeChange> createDiffs(sharable::Node * cachedNode,
+ ISubtree const * _pLoadedSubtree,
+ configuration::AbsolutePath const& _aAbsoluteSubtreePath)
+{
+ OSL_PRECOND(cachedNode != 0, "Need an existing node to create a diff");
+ OSL_PRECOND(_pLoadedSubtree != 0, "Need a result node to create a diff");
+ // Create a TreeChangeList with the right name, parentname and ConfigurationProperties
+ std::auto_ptr<SubtreeChange> aNewChange(new SubtreeChange(_aAbsoluteSubtreePath.getLocalName().getName(),
+ node::Attributes()) );
+
+ if (!createUpdateFromDifference(*aNewChange, cachedNode, *_pLoadedSubtree))
+ aNewChange.reset();
+
+ return aNewChange;
+}
+// -----------------------------------------------------------------------------
+#if 0
+std::auto_ptr<ISubtree> TreeManager::loadNodeFromSession( configuration::AbsolutePath const& _aAbsoluteSubtreePath,
+ const vos::ORef < OOptions >& _xOptions,
+ sal_Int16 _nMinLevels) SAL_THROW((com::sun::star::uno::Exception))
+{
+ TreeInfo* pInfo = this->requestTreeInfo(_xOptions,true /*create TreeInfo*/);
+
+ CFG_TRACE_INFO_NI("cache manager: cache miss. going to load the node");
+ rtl::Reference< OTreeLoader > xLoader = pInfo->getNewLoaderWithoutPending(_aAbsoluteSubtreePath, _nMinLevels, _xOptions, m_xBackend.get());
+
+ OSL_ENSURE(xLoader.is(), "Did not receive a loader for retrieving the node");
+ CFG_TRACE_INFO_NI("cache manager: cache miss. going to load the node");
+ if (!xLoader.is())
+ throw container::NoSuchElementException((::rtl::OUString::createFromAscii("Error while retrieving the node")), NULL);
+
+ // now block for reading
+ std::auto_ptr<ISubtree> pResponse;
+ try
+ {
+ pResponse = xLoader->waitToResponse();
+ }
+ catch (uno::Exception& e)
+ {
+ pInfo->releaseLoader(xLoader);
+ throw;
+ }
+
+ pInfo->releaseLoader(xLoader);
+
+ return pResponse;
+}
+#endif
+// -----------------------------------------------------------------------------
+
+sharable::TreeFragment * CacheController::refreshComponent(ComponentRequest const & _aRequest) SAL_THROW((com::sun::star::uno::Exception))
+{
+ if (m_bDisposing) return NULL;
+
+ rtl::Reference<CacheLoadingAccess> aCache = this->getCacheAlways(_aRequest.getOptions());
+
+ if (!aCache.is()) return NULL;
+
+ // load the Node direct from the session, without using the cache
+ ComponentRequest aForcedRequest(_aRequest);
+ aForcedRequest.forceReload();
+
+ ResultHolder< ComponentInstance > aLoadedInstance = this->getComponentData(aForcedRequest,false);
+ configuration::AbsolutePath aRequestPath = configuration::AbsolutePath::makeModulePath(_aRequest.getComponentName());
+ NodeInstance aNodeInstance(aLoadedInstance.mutableInstance().mutableData(),aRequestPath) ;
+ ResultHolder< NodeInstance > aLoadedNodeInstance(aNodeInstance) ;
+
+ sharable::TreeFragment * aResult = NULL;
+ if (aLoadedNodeInstance.is())
+ {
+ rtl::OUString aModuleName = aLoadedNodeInstance->root().getModuleName();
+
+ bool bAcquired = aCache->acquireModule(aModuleName);
+ aResult = (sharable::TreeFragment *)( aCache->getTreeAddress(aModuleName) );
+
+ if (bAcquired)
+ try
+ {
+ std::auto_ptr<SubtreeChange> aTreeChanges;
+ sharable::Node * aRootAddress;
+
+ {
+ sharable::Node * rootNode = aResult == 0 ? 0 : aResult->getRootNode();
+
+ aTreeChanges = createDiffs(rootNode, aLoadedNodeInstance->data().get(), aLoadedNodeInstance->root());
+ aRootAddress = rootNode;
+ }
+
+ if (aTreeChanges.get() != NULL)
+ {
+ // change all Values... found in the Subtree in the CacheTree
+ applyUpdateWithAdjustmentToTree(*aTreeChanges, aRootAddress);
+
+ UpdateRequest anUpdateReq( aTreeChanges.get(),
+ aLoadedNodeInstance->root(),
+ _aRequest.getOptions()
+ );
+
+ m_aNotifier.notifyChanged(anUpdateReq);
+ }
+ aCache->releaseModule(aModuleName);
+ }
+ catch (...)
+ {
+ aCache->releaseModule(aModuleName);
+ throw;
+ }
+ }
+ return aResult;
+}
+
+// -----------------------------------------------------------------------------
+ } // namespace backend
+
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
diff --git a/configmgr/source/treecache/makefile.mk b/configmgr/source/treecache/makefile.mk
new file mode 100644
index 000000000000..d8649085bbe7
--- /dev/null
+++ b/configmgr/source/treecache/makefile.mk
@@ -0,0 +1,62 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.12 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source
+PRJNAME=configmgr
+TARGET=treecache
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/timestamp.obj \
+ $(SLO)$/disposetimer.obj \
+ $(SLO)$/cachewritescheduler.obj \
+ $(SLO)$/invalidatetree.obj \
+ $(SLO)$/cachefactory.obj \
+ $(SLO)$/cacheaccess.obj \
+ $(SLO)$/cachedata.obj \
+ $(SLO)$/cacheline.obj \
+ $(SLO)$/cachemulticaster.obj \
+ $(SLO)$/cachecontroller.obj \
+ $(SLO)$/treemanager.obj \
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/treecache/timestamp.cxx b/configmgr/source/treecache/timestamp.cxx
new file mode 100644
index 000000000000..37eabada1079
--- /dev/null
+++ b/configmgr/source/treecache/timestamp.cxx
@@ -0,0 +1,63 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: timestamp.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "timestamp.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ const sal_uInt32 maxTimeValueSeconds = 0xFF000000ul; // catches accidetally added values as well
+ const sal_uInt32 maxTimeValueNanos = 999999999ul;
+ const sal_uInt32 minTimeValueSeconds = 0ul;
+ const sal_uInt32 minTimeValueNanos = 0ul;
+// -------------------------------------------------------------------------
+ TimeStamp TimeStamp::never()
+ {
+ const ::TimeValue maxTimeValue = { maxTimeValueSeconds, maxTimeValueNanos };
+
+ return TimeStamp( maxTimeValue );
+ }
+// -------------------------------------------------------------------------
+ TimeStamp TimeStamp::getCurrentTime()
+ {
+ TimeStamp aResult;
+ if (! ::osl_getSystemTime( &aResult.m_aTime ) )
+ return never();
+ return aResult;
+ }
+// -------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/treecache/timestamp.hxx b/configmgr/source/treecache/timestamp.hxx
new file mode 100644
index 000000000000..34dde74e4380
--- /dev/null
+++ b/configmgr/source/treecache/timestamp.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: timestamp.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_TIMESTAMP_HXX
+#define CONFIGMGR_TIMESTAMP_HXX
+
+#include <vos/timer.hxx>
+
+namespace configmgr
+{
+////////////////////////////////////////////////////////////////////////////////
+
+ class TimeInterval
+ {
+ vos::TTimeValue m_aTime;
+ public:
+ TimeInterval() : m_aTime()
+ {}
+
+ explicit
+ TimeInterval(sal_uInt32 nSeconds) : m_aTime(nSeconds,0)
+ {}
+
+ explicit
+ TimeInterval(const TimeValue& rTimeValue) : m_aTime(rTimeValue)
+ {}
+
+ sal_Bool isEmpty() const { return m_aTime.isEmpty(); }
+
+ vos::TTimeValue const& getTimeValue() const { return m_aTime; }
+ };
+////////////////////////////////////////////////////////////////////////////////
+
+ class TimeStamp
+ {
+ vos::TTimeValue m_aTime;
+ public:
+ TimeStamp() : m_aTime()
+ {}
+
+ explicit
+ TimeStamp(TimeValue const& rTimeValue) : m_aTime(rTimeValue)
+ {}
+
+ TimeStamp& operator += (TimeInterval const& aInterval)
+ { m_aTime.addTime(aInterval.getTimeValue()); return *this; }
+
+ vos::TTimeValue const& getTimeValue() const { return m_aTime; }
+
+ sal_Bool isNever() const;
+
+ static TimeStamp getCurrentTime();
+ static TimeStamp never(); // is later than (>) any other TimeStamp
+ };
+
+ inline
+ TimeStamp operator +(TimeStamp const& aTime, TimeInterval const& aInterval)
+ {
+ TimeStamp aResult(aTime);
+ aResult += aInterval;
+ return aResult;
+ }
+ inline
+ TimeStamp operator +(TimeInterval const& aInterval, TimeStamp const& aTime)
+ {
+ TimeStamp aResult(aTime);
+ aResult += aInterval;
+ return aResult;
+ }
+////////////////////////////////////////////////////////////////////////////////
+ inline sal_Bool operator ==(TimeStamp const& lhs, TimeStamp const& rhs)
+ { return lhs.getTimeValue() == rhs.getTimeValue(); }
+ inline sal_Bool operator < (TimeStamp const& lhs, TimeStamp const& rhs)
+ { return lhs.getTimeValue() < rhs.getTimeValue(); }
+ inline sal_Bool operator > (TimeStamp const& lhs, TimeStamp const& rhs)
+ { return lhs.getTimeValue() > rhs.getTimeValue(); }
+
+ inline sal_Bool operator !=(TimeStamp const& lhs, TimeStamp const& rhs)
+ { return !(lhs == rhs); }
+ inline sal_Bool operator <=(TimeStamp const& lhs, TimeStamp const& rhs)
+ { return !(rhs < lhs); }
+ inline sal_Bool operator >=(TimeStamp const& lhs, TimeStamp const& rhs)
+ { return !(lhs < rhs); }
+
+ inline sal_Bool TimeStamp::isNever() const
+ {
+ return never() <= *this;
+ }
+////////////////////////////////////////////////////////////////////////////////
+
+ struct ltTimeStamp //: std::binary_function<TimeStamp,TimeStamp,bool>
+ {
+ bool operator()(TimeStamp const& lhs, TimeStamp const& rhs) const
+ { return !!(lhs < rhs); }
+ };
+
+////////////////////////////////////////////////////////////////////////////////
+} // namespace configmgr
+
+#endif // CONFIGMGR_TIMESTAMP_HXX
+
diff --git a/configmgr/source/treecache/treemanager.cxx b/configmgr/source/treecache/treemanager.cxx
new file mode 100644
index 000000000000..99bcd21892b2
--- /dev/null
+++ b/configmgr/source/treecache/treemanager.cxx
@@ -0,0 +1,515 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treemanager.cxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "treemanager.hxx"
+#include "mergeddataprovider.hxx"
+#include "cacheaccess.hxx"
+#include "cachecontroller.hxx"
+#include "cachemulticaster.hxx"
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include "tracer.hxx"
+#include <osl/diagnose.h>
+#include <rtl/logfile.hxx>
+
+namespace configmgr
+{
+
+ namespace uno = ::com::sun::star::uno;
+ namespace lang= ::com::sun::star::lang;
+
+ namespace Path = configuration::Path;
+// =========================================================================
+//#if OSL_DEBUG_LEVEL > 0
+#if 0 // currently not used in debug build!
+static void test_complete(memory::HeapManager & _rDummy)
+{ new TreeManager(NULL,_rDummy); }
+#endif
+// =========================================================================
+
+#define MAKEUSTRING( char_array ) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( char_array ) )
+// =========================================================================
+
+static inline
+configuration::AbsolutePath extractModulePath(configuration::AbsolutePath const & _aPath)
+{
+ if (_aPath.getDepth() <= 1) return _aPath;
+
+ rtl::OUString aModule = _aPath.getModuleName();
+
+ return configuration::AbsolutePath::makeModulePath(aModule);
+}
+// =========================================================================
+
+// disposing
+// -------------------------------------------------------------------------
+void TreeManager::disposeAll()
+{
+ CFG_TRACE_INFO("TreeManager: Disposing all data" );
+ CacheList::Map aReleaseList;
+
+ m_aCacheList.swap(aReleaseList); // move data out of m_aCacheList
+
+ // free all the trees - not exception safe !! (i.e. disposeBroadcastHelper() must not throw)
+ for (CacheList::Map::iterator i = aReleaseList.begin(); i != aReleaseList.end(); ++i)
+ {
+ if (ConfigChangeBroadcastHelper * pHelper = i->second->releaseBroadcaster())
+ disposeBroadcastHelper(pHelper);
+ i->second.clear();
+ }
+}
+
+// -------------------------------------------------------------------------
+void TreeManager::dispose()
+{
+ CFG_TRACE_INFO("TreeManager: dispoing the treemanager" );
+
+ RTL_LOGFILE_CONTEXT_AUTHOR(aLog, "configmgr::TreeManager", "jb99855", "configmgr: TreeManager::dispose().");
+
+ rtl::Reference< backend::CacheController > xBackendCache = maybeGetBackendCache();
+
+ if (xBackendCache.is()) xBackendCache->getNotifier().removeListener(this);
+
+ // cleaning the cache
+ disposeAll();
+
+ disposeBackendCache();
+}
+
+// -------------------------------------------------------------------------
+ConfigChangeBroadcastHelper* TreeManager::getBroadcastHelper(RequestOptions const& _aOptions, bool bCreate)
+{
+ rtl::Reference<CacheClientAccess> aCache = bCreate ? this->getCacheAlways(_aOptions)
+ : m_aCacheList.get(_aOptions);
+
+ return aCache.is() ? aCache->getBroadcaster() : NULL;
+}
+
+
+// -------------------------------------------------------------------------
+TreeManager::TreeManager(rtl::Reference< backend::CacheController > const & _xBackend)
+: m_xCacheController(_xBackend)
+, m_aCacheList()
+, m_aTemplates(new CacheData())
+, m_bEnableAsync(true)
+{
+ OSL_PRECOND(_xBackend.is(),"Trying to create a TreeManager without a backend");
+
+ if (m_xCacheController.is()) m_xCacheController->getNotifier().addListener(this);
+}
+
+// -------------------------------------------------------------------------
+TreeManager::~TreeManager()
+{
+}
+
+// -------------------------------------------------------------------------
+rtl::Reference< backend::CacheController > TreeManager::maybeGetBackendCache() SAL_THROW(())
+{
+ osl::MutexGuard aGuard(m_aCacheControllerMutex);
+ rtl::Reference< backend::CacheController > xResult(m_xCacheController);
+ return xResult;
+}
+
+// -------------------------------------------------------------------------
+rtl::Reference< backend::CacheController > TreeManager::getCacheLoader() SAL_THROW((com::sun::star::uno::RuntimeException))
+{
+ osl::MutexGuard aGuard(m_aCacheControllerMutex);
+ if (!m_xCacheController.is())
+ {
+ rtl::OUString sMsg = rtl::OUString::createFromAscii("TreeManager: No backend available - tree manager was already disposed.");
+ throw com::sun::star::lang::DisposedException(sMsg,NULL);
+ }
+ rtl::Reference< backend::CacheController > xResult(m_xCacheController);
+ return xResult;
+}
+
+// -------------------------------------------------------------------------
+void TreeManager::disposeBackendCache() SAL_THROW(())
+{
+ osl::ClearableMutexGuard aGuard(m_aCacheControllerMutex);
+ if (m_xCacheController.is())
+ {
+ rtl::Reference< backend::CacheController > xBackendCache(m_xCacheController);
+ m_xCacheController.clear();
+ aGuard.clear();
+ xBackendCache->dispose();
+ }
+}
+
+// -------------------------------------------------------------------------
+
+rtl::Reference<CacheClientAccess> TreeManager::getCacheAlways(RequestOptions const & _aOptions)
+{
+ rtl::Reference<CacheClientAccess> aResult = m_aCacheList.get(_aOptions);
+ if (!aResult.is())
+ {
+ rtl::Reference<CacheClientAccess> aNewCache( new CacheClientAccess(new ConfigChangeBroadcastHelper()) );
+ aResult = m_aCacheList.insert(_aOptions,aNewCache);
+ }
+ return aResult;
+}
+
+// -------------------------------------------------------------------------
+
+sharable::Node * TreeManager::requestSubtree(configuration::AbsolutePath const& aSubtreePath,
+ const RequestOptions& _aOptions)
+ SAL_THROW((com::sun::star::uno::Exception))
+{
+ CFG_TRACE_INFO("TreeManager: request for subtree '%s'", OUSTRING2ASCII(aSubtreePath.toString()));
+
+ rtl::Reference<CacheClientAccess> aCache = getCacheAlways(_aOptions);
+ OSL_ENSURE(aCache.is(),"TreeManager: Cannot create cache access for loading node");
+
+ if (!aCache->hasModule(aSubtreePath))
+ {
+ CFG_TRACE_INFO_NI("TreeManager: cache miss. going to load the node");
+ backend::ComponentRequest aQuery( aSubtreePath.getModuleName(), _aOptions );
+
+ sharable::TreeFragment * aLoadedLocation = getCacheLoader()->loadComponent(aQuery);
+ if (aLoadedLocation == NULL)
+ {
+ CFG_TRACE_WARNING_NI("TreeManager: requested component not found");
+ throw com::sun::star::container::
+ NoSuchElementException( MAKEUSTRING("Requested component not found"), NULL);
+ }
+
+ CFG_TRACE_INFO_NI("TreeManager: attaching loaded cache segment ");
+ aCache->attachModule(aLoadedLocation,aSubtreePath.getModuleName());
+ }
+ else
+ {
+ CFG_TRACE_INFO_NI("TreeManager: found node in cache");
+ if (_aOptions.isRefreshEnabled())
+ {
+ backend::ComponentRequest aRequest( aSubtreePath.getModuleName(), _aOptions );
+ getCacheLoader()->refreshComponent(aRequest);
+ }
+ }
+
+ return aCache->acquireNode(aSubtreePath);
+}
+
+// -------------------------------------------------------------------------
+void TreeManager::fetchSubtree(configuration::AbsolutePath const& aSubtreePath, const RequestOptions& ) SAL_THROW(())
+{
+ (void) aSubtreePath; // avoid warning about unused parameter
+ CFG_TRACE_WARNING("TreeManager: Prefetching not implemented. (Request to prefetch component %s.", OUSTRING2ASCII(aSubtreePath.toString()));
+}
+
+// -------------------------------------------------------------------------
+sal_Bool TreeManager::fetchDefaultData( configuration::AbsolutePath const& aSubtreePath,
+ const RequestOptions& _aOptions
+ ) SAL_THROW((com::sun::star::uno::Exception))
+{
+ CFG_TRACE_INFO("tree manager: checking the cache for defaults");
+
+ rtl::Reference<CacheClientAccess> aCache = m_aCacheList.get(_aOptions);
+
+ if (!aCache.is())
+ {
+ OSL_ENSURE(aCache.is(),"TreeManager: Cache access to fetch defaults for does not exist ! Where does the node access come from ?");
+ return false;
+ }
+
+ if (aCache->hasModuleDefaults(aSubtreePath))
+ {
+ CFG_TRACE_INFO_NI("TreeManager: found default data in cache");
+ return true;
+ }
+
+ configuration::AbsolutePath aRequestPath = extractModulePath(aSubtreePath);
+
+ backend::NodeRequest aRequest(aRequestPath,_aOptions);
+
+ backend::ResultHolder< backend::NodeInstance > aDefaults = getCacheLoader()->getDefaultData( aRequest );
+
+ if (!aDefaults.is())
+ {
+ CFG_TRACE_INFO_NI("TreeManager: merging loaded defaults into cache");
+ return aCache->insertDefaults(aDefaults.instance());
+ }
+ else
+ {
+ CFG_TRACE_WARNING_NI("TreeManager: cannot load defaults: no data available or not supported");
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------------
+std::auto_ptr<ISubtree> TreeManager::requestDefaultData(configuration::AbsolutePath const& aSubtreePath,
+ const RequestOptions& _aOptions
+ ) SAL_THROW((com::sun::star::uno::Exception))
+{
+ // to do: check cache for existing default data (?!)
+ CFG_TRACE_INFO_NI("TreeManager: loading default data directly");
+
+ backend::NodeRequest aRequest(aSubtreePath,_aOptions);
+
+ backend::ResultHolder< backend::NodeInstance > aDefaults = getCacheLoader()->getDefaultData( aRequest );
+
+ return aDefaults.extractDataAndClear();
+}
+
+// -------------------------------------------------------------------------
+configuration::AbsolutePath TreeManager::encodeTemplateLocation(const rtl::OUString& _rLogicalTemplateName, const rtl::OUString &_rModule)
+{
+// static const
+// configuration::Path::Component aTemplateRoot = configuration::Path::wrapSimpleName(rtl::OUString::createFromAscii("org.openoffice.Templates"));
+
+ configuration::Path::Component aTemplateModule = configuration::Path::wrapSimpleName(_rModule);
+ configuration::Path::Component aTemplateName = configuration::Path::wrapSimpleName(_rLogicalTemplateName);
+
+ Path::Rep aResult(aTemplateName);
+ aResult.prepend(aTemplateModule);
+// aResult.prepend(aTemplateRoot);
+
+ return configuration::AbsolutePath(aResult);
+}
+
+// -------------------------------------------------------------------------
+sharable::TreeFragment * TreeManager::requestTemplate(rtl::OUString const& _rName,
+ rtl::OUString const& _rModule) SAL_THROW((com::sun::star::uno::Exception))
+{
+ OSL_ENSURE(_rName.getLength() != 0, "TreeManager::requestTemplate : invalid template name !");
+
+ CFG_TRACE_INFO("TreeManager: going to get a template named %s", OUSTRING2ASCII(_rName));
+
+ configuration::AbsolutePath aTemplateLocation = encodeTemplateLocation(_rName, _rModule);
+ rtl::OUString aCacheModule = aTemplateLocation.getModuleName();
+
+ if (!getTemplates().hasNode(aTemplateLocation))
+ {
+ CFG_TRACE_INFO_NI("TreeManager: cache miss. going to load the template");
+ backend::TemplateRequest aQuery( _rName, _rModule );
+
+ sharable::TreeFragment * aLoadedLocation = getCacheLoader()->loadTemplate(aQuery);
+ if (aLoadedLocation == NULL)
+ {
+ CFG_TRACE_ERROR_NI("TreeManager: requested template module not found");
+ throw com::sun::star::container::
+ NoSuchElementException( MAKEUSTRING("Requested template module not found"), NULL);
+ }
+
+ CFG_TRACE_INFO_NI("TreeManager: attaching to loaded template module");
+
+ getTemplates().attachModule(aLoadedLocation,aCacheModule);
+
+ // create a client ref count on the template module
+ getTemplates().acquireNode(aTemplateLocation);
+ }
+ else
+ {
+ CFG_TRACE_INFO_NI("TreeManager: template module found in cache");
+ }
+
+ sharable::TreeFragment * aTemplateAddr = getTemplates().getTemplateTree(aTemplateLocation);
+ if (aTemplateAddr == NULL)
+ {
+ CFG_TRACE_ERROR_NI("TreeManager: template not found in module");
+ throw com::sun::star::container::
+ NoSuchElementException( MAKEUSTRING("Unknown template. Type description could not be found in the given module."), NULL);
+ }
+ return aTemplateAddr;
+}
+
+// -------------------------------------------------------------------------
+void TreeManager::saveAndNotifyUpdate(TreeChangeList const& aChangeTree) SAL_THROW((com::sun::star::uno::Exception))
+{
+ {
+ CFG_TRACE_INFO("TreeManager: committing an Update to the cache controller");
+ RequestOptions aOptions = aChangeTree.getOptions();;
+ //Modify RequestOptions - suppress async commit, if disabled
+ if(!m_bEnableAsync)
+ aOptions.enableAsync(false);
+
+ backend::UpdateRequest anUpdate(
+ & aChangeTree.root,
+ aChangeTree.getRootNodePath(),
+ aOptions);
+
+ getCacheLoader()->saveAndNotify(anUpdate);
+ CFG_TRACE_INFO_NI("TreeManager: committing done");
+ }
+}
+
+// -----------------------------------------------------------------------------
+void TreeManager::updateTree(TreeChangeList& _aChanges) SAL_THROW((com::sun::star::uno::Exception))
+{
+ CFG_TRACE_INFO("TreeManager: updating the cache from a changes list");
+
+ backend::UpdateInstance anUpdate(&_aChanges.root,_aChanges.getRootNodePath());
+
+ rtl::Reference<CacheClientAccess> aCache = m_aCacheList.get(_aChanges.getOptions());
+
+ if (!aCache.is())
+ {
+ CFG_TRACE_ERROR_NI("TreeManager: Cache access to update into does not exist !");
+ OSL_ENSURE(aCache.is(),"TreeManager: Cache access to update into does not exist ! Where does the update access come from ?");
+ throw lang::DisposedException(rtl::OUString::createFromAscii("Tree to be updated was already disposed"), NULL);
+ }
+
+ // merge the changes into the tree
+ aCache->applyUpdate(anUpdate);
+
+ CFG_TRACE_INFO_NI("TreeManager: cache update done");
+}
+
+// -----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+void TreeManager::releaseSubtree( configuration::AbsolutePath const& aSubtreePath, const RequestOptions& _aOptions ) SAL_THROW(())
+{
+ CFG_TRACE_INFO("TreeManager: releasing subtree '%s' for entity '%s' with locale '%s'", OUSTRING2ASCII(aSubtreePath.toString()), OUSTRING2ASCII(_aOptions.getEntity()), OUSTRING2ASCII(_aOptions.getLocale()) );
+
+ rtl::Reference<CacheClientAccess> aCache = m_aCacheList.get(_aOptions);
+
+ OSL_ENSURE(aCache.is(),"TreeManager: No local data to release");
+
+ if (aCache.is())
+ {
+ CFG_TRACE_INFO_NI("TreeManager: decrementing refcount for subtree '%s'", OUSTRING2ASCII(aSubtreePath.toString()) );
+ if (aCache->releaseNode(aSubtreePath) == 0)
+ {
+ backend::ComponentRequest aComponentDesc(aSubtreePath.getModuleName(),_aOptions);
+ rtl::Reference< backend::CacheController > xBackendCache = maybeGetBackendCache();
+ if (xBackendCache.is()) xBackendCache->freeComponent(aComponentDesc);
+ }
+ }
+}
+// ----------------------------------------------------------------------------
+void TreeManager::refreshAll() SAL_THROW((com::sun::star::uno::Exception))
+{
+ //Find what components are in cache and that have client references and reload
+ //such components.
+ rtl::Reference< backend::CacheController > aCacheRef = maybeGetBackendCache();
+ if (aCacheRef.is()) aCacheRef->refreshAllComponents();
+}
+// ----------------------------------------------------------------------------
+void TreeManager::flushAll()SAL_THROW(())
+{
+ rtl::Reference< backend::CacheController > aCacheRef = maybeGetBackendCache();
+ if (aCacheRef.is()) aCacheRef->flushPendingUpdates();
+}
+//-----------------------------------------------------------------------------
+void TreeManager::enableAsync(const sal_Bool& bEnableAsync) SAL_THROW(())
+{
+ m_bEnableAsync = bEnableAsync;
+}
+
+ /////////////////////////////////////////////////////////////////////////
+ void TreeManager::addListener(configuration::AbsolutePath const& aName, RequestOptions const & _aOptions, rtl::Reference<INodeListener> const& pHandler)
+ {
+ if (ConfigChangeBroadcastHelper* pHelper = getBroadcastHelper(_aOptions,true))
+ {
+ pHelper->addListener(aName, pHandler);
+ }
+ else
+ OSL_ASSERT(false);
+ }
+
+ void TreeManager::removeListener(RequestOptions const & _aOptions, rtl::Reference<INodeListener> const& pHandler)
+ {
+ if (ConfigChangeBroadcastHelper* pHelper = getBroadcastHelper(_aOptions,false))
+ {
+ pHelper->removeListener( pHandler);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ void TreeManager::fireChanges(TreeChangeList const& rList_, sal_Bool bError_)
+ {
+ if (ConfigChangeBroadcastHelper* pHelper = getBroadcastHelper(rList_.getOptions(),false))
+ {
+ pHelper->broadcast(rList_, bError_, this);
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ void TreeManager::disposeBroadcastHelper(ConfigChangeBroadcastHelper* pHelper)
+ {
+ if (pHelper)
+ {
+ pHelper->dispose(this);
+ delete pHelper;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+void TreeManager::nodeUpdated(TreeChangeList& _rChanges)
+{
+ CFG_TRACE_INFO("TreeManager: nodeUpdated");
+ try
+ {
+ rtl::Reference<CacheClientAccess> aCache = m_aCacheList.get(_rChanges.getOptions());
+
+ if (aCache.is())
+ {
+ // first approve the changes and merge them with the current tree
+ configuration::AbsolutePath aSubtreeName = _rChanges.getRootNodePath();
+
+ sharable::Node * aCacheTree = aCache->findInnerNode(aSubtreeName);
+ //OSL_ENSURE(aCacheTree != NULL, "TreeManager::nodeUpdated : node not found in cache!");
+
+ if (aCacheTree != NULL)
+ this->fireChanges(_rChanges,false);
+ }
+ }
+ catch (uno::RuntimeException&)
+ {
+ CFG_TRACE_ERROR_NI("TreeManager::nodeUpdated : could not notify !");
+ }
+ CFG_TRACE_INFO_NI("TreeManager: nodeUpdated done");
+}
+
+// ----------------------------------------------------------------------------
+
+void TreeManager::componentCreated(backend::ComponentRequest const & ) SAL_THROW(())
+{
+ CFG_TRACE_INFO("TreeManager: component was created");
+}
+// ----------------------------------------------------------------------------
+
+void TreeManager::componentChanged(backend::UpdateRequest const & _anUpdate) SAL_THROW(())
+{
+ TreeChangeList aChanges(_anUpdate.getOptions(),
+ _anUpdate.getUpdateRoot(),
+ *_anUpdate.getUpdateData(),
+ treeop::DeepChildCopy() );
+
+ this->nodeUpdated(aChanges);
+}
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+} // namespace
diff --git a/configmgr/source/treemgr/collectchanges.cxx b/configmgr/source/treemgr/collectchanges.cxx
new file mode 100644
index 000000000000..625a2bbb9b0b
--- /dev/null
+++ b/configmgr/source/treemgr/collectchanges.cxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: collectchanges.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <string.h>
+#include "collectchanges.hxx"
+
+#include "nodechangeinfo.hxx"
+
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+
+//-----------------------------------------------------------------------------
+// conversion helper function
+//-----------------------------------------------------------------------------
+bool convertNodeChange(NodeChangeData& aData_, ValueChange const& aChange_)
+{
+ switch(aChange_.getMode())
+ {
+ case ValueChange::wasDefault:
+ case ValueChange::changeValue:
+ aData_.type = NodeChangeData::eSetValue;
+ break;
+
+ case ValueChange::setToDefault:
+ aData_.type = NodeChangeData::eSetDefault;
+ break;
+
+ case ValueChange::changeDefault:
+ aData_.type = NodeChangeData::eNoChange; // ??
+ break;
+
+ default:
+ OSL_ENSURE(false,"Unknown change type found");
+ return false;
+ }
+
+ aData_.unoData.newValue = aChange_.getNewValue();
+ aData_.unoData.oldValue = aChange_.getOldValue();
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+bool convertNodeChange(NodeChangeData& aData_, AddNode const& aChange_)
+{
+ aData_.type = aChange_.isReplacing()
+ ? NodeChangeData::eReplaceElement
+ : NodeChangeData::eInsertElement;
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+bool convertNodeChange(NodeChangeData& aData_, RemoveNode const& /*aChange_*/)
+{
+ aData_.type = NodeChangeData::eRemoveElement;
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// CollectChanges visitor class
+//-----------------------------------------------------------------------------
+
+CollectChanges::CollectChanges( NodeChangesInformation& rTargetList_,
+ Tree& rStartTree_, unsigned int nStartNode_,
+ rtl::Reference<Template> aElementTemplate_,
+ unsigned int nMaxDepth)
+: m_rTargetList(rTargetList_)
+, m_aAccessor()
+, m_aContextTypeName()
+, m_pBaseTree(&rStartTree_)
+, m_nBaseNode(nStartNode_)
+, m_nDepthLeft( nMaxDepth )
+{
+ if (aElementTemplate_.is())
+ m_aContextTypeName = aElementTemplate_->getName();
+}
+
+//-----------------------------------------------------------------------------
+CollectChanges::CollectChanges( CollectChanges const& rBase, Path::Component const& rChildName, rtl::OUString const& aSubTypeName_)
+: m_rTargetList(rBase.m_rTargetList)
+, m_aAccessor(rBase.m_aAccessor.compose(rChildName))
+, m_aContextTypeName(aSubTypeName_)
+, m_pBaseTree(rBase.m_pBaseTree)
+, m_nBaseNode(rBase.m_nBaseNode)
+, m_nDepthLeft(childDepth(rBase.m_nDepthLeft))
+{
+ OSL_ASSERT(rBase.m_nDepthLeft > 0);
+}
+
+//-----------------------------------------------------------------------------
+inline
+Path::Component CollectChanges::implGetNodeName(Change const& aChange_) const
+{
+ rtl::OUString aSimpleNodeName( aChange_.getNodeName() );
+
+ if (m_aContextTypeName.getLength() == 0)
+ {
+ OSL_ENSURE(isSimpleName(aSimpleNodeName),"Unexpected: Found non-simple name without a type");
+ return Path::wrapSafeName(aSimpleNodeName);
+ }
+ else
+ return Path::makeCompositeName(aSimpleNodeName, m_aContextTypeName);
+}
+
+//-----------------------------------------------------------------------------
+void CollectChanges::collectFrom(ValueChange const& aChange_)
+{
+ NodeChangeInformation aInfo;
+
+ if ( convertNodeChange( aInfo.change, aChange_ ) &&
+ implSetLocation( aInfo.location, aChange_, false ) )
+ {
+ implAdd( aInfo );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CollectChanges::collectFrom(AddNode const& aChange_)
+{
+ NodeChangeInformation aInfo;
+
+ if ( convertNodeChange( aInfo.change, aChange_ ) &&
+ implSetLocation( aInfo.location, aChange_, true ) )
+ {
+ implAdd( aInfo );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CollectChanges::collectFrom(RemoveNode const& aChange_)
+{
+ NodeChangeInformation aInfo;
+
+ if ( convertNodeChange( aInfo.change, aChange_ ) &&
+ implSetLocation( aInfo.location, aChange_, true ) )
+ {
+ implAdd( aInfo );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CollectChanges::collectFrom(SubtreeChange const& aChanges_)
+{
+ if (m_nDepthLeft > 0)
+ {
+ rtl::OUString aSubTypeName( aChanges_.getElementTemplateName() );
+
+ CollectChanges aSubcollector( *this, implGetNodeName(aChanges_), aSubTypeName );
+
+ aSubcollector.applyToChildren(aChanges_);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CollectChanges::implAdd(NodeChangeInformation const& aChangeInfo_)
+{
+ m_rTargetList.push_back(aChangeInfo_);
+}
+
+//-----------------------------------------------------------------------------
+bool CollectChanges::implSetLocation(NodeChangeLocation& rLocation_, Change const& aOriginal_, bool bSet_) const
+{
+ NodeID aBaseID(m_pBaseTree,m_nBaseNode);
+ if (aBaseID.isEmpty())
+ return false;
+
+ rLocation_.setBase( aBaseID );
+
+ if (bSet_ && m_aAccessor.isEmpty()) // It is a set change affecting the base ...
+ rLocation_.setAffected( aBaseID );
+
+ Path::Component aChangeName = implGetNodeName( aOriginal_ );
+ rLocation_.setAccessor( m_aAccessor.compose( aChangeName ) );
+
+ return true;
+}
+
+// ChangeTreeAction implementations
+//-----------------------------------------------------------------------------
+void CollectChanges::handle(ValueChange const& aValueNode_)
+{
+ collectFrom(aValueNode_);
+}
+
+//-----------------------------------------------------------------------------
+void CollectChanges::handle(AddNode const& aAddNode_)
+{
+ collectFrom(aAddNode_);
+}
+
+//-----------------------------------------------------------------------------
+void CollectChanges::handle(RemoveNode const& aRemoveNode_)
+{
+ collectFrom(aRemoveNode_);
+}
+
+//-----------------------------------------------------------------------------
+void CollectChanges::handle(SubtreeChange const& aSubtree_)
+{
+ collectFrom( aSubtree_ );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+ }
+}
+
diff --git a/configmgr/source/treemgr/collectchanges.hxx b/configmgr/source/treemgr/collectchanges.hxx
new file mode 100644
index 000000000000..c11c6ec020c2
--- /dev/null
+++ b/configmgr/source/treemgr/collectchanges.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: collectchanges.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_COLLECTCHANGES_HXX_
+#define CONFIGMGR_COLLECTCHANGES_HXX_
+
+// low.level (cache model) changes (needed for change tree action class)
+#include "change.hxx"
+
+// pathes for accessors
+#include "configpath.hxx"
+
+// need c_TreeDepthAll
+#include "tree.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ class NodeChangeData;
+ class NodeChangeLocation;
+ class NodeChangeInformation;
+ class NodeChangesInformation;
+//-----------------------------------------------------------------------------
+
+ /// Change model translation: Create a NodeChangeData from a ValueChange object
+ bool convertNodeChange(NodeChangeData& aData_, ValueChange const& aChange_);
+ /// Change model translation: Create a NodeChangeData from an AddNode change object
+ bool convertNodeChange(NodeChangeData& aData_, AddNode const& aChange_);
+ /// Change model translation: Create a NodeChangeData from a RemoveNode change object
+ bool convertNodeChange(NodeChangeData& aData_, RemoveNode const& aChange_);
+
+ /** Change Tree Visitor that appends all changes in the changes tree
+ to a NodeChanges list, optionally restricted to a given depth
+ */
+ class CollectChanges : private ChangeTreeAction
+ {
+ NodeChangesInformation& m_rTargetList;
+ RelativePath m_aAccessor;
+ rtl::OUString m_aContextTypeName;
+ Tree* m_pBaseTree;
+ unsigned int m_nBaseNode;
+ unsigned int m_nDepthLeft;
+
+ public:
+ /// Constructs a Visitor object, sets the output target list and context
+ CollectChanges( NodeChangesInformation& rTargetList_,
+ Tree& rStartTree_, unsigned int nStartNode_,
+ rtl::Reference<Template> aElementTemplate_,
+ unsigned int nMaxDepth = c_TreeDepthAll);
+
+ /// Adds a (translated) ValueChange to the target list
+ void collectFrom(ValueChange const& aChange_);
+
+ /// Adds a (translated) AddNode to the target list
+ void collectFrom(AddNode const& aChange_);
+
+ /// Adds a (translated) RemoveNode to the target list
+ void collectFrom(RemoveNode const& aChange_);
+
+ /// Appends (translated) Changes from the subtree to the target list, possibly with a depth limit
+ void collectFrom(SubtreeChange const& aChange_);
+
+ /// Appends the given Change and its descendants to the target list, possibly with a depth limit
+ void collectFrom(Change const& aChange_)
+ {
+ this->applyToChange( aChange_ );
+ }
+
+ /// Appends the descendants of the given Change to the target list, possibly with a depth limit
+ void collectFromChildren(SubtreeChange const& aParent_)
+ {
+ this->applyToChildren( aParent_ );
+ }
+
+ protected:
+ /// Constructs a Visitor object for a child of another one's context
+ CollectChanges( CollectChanges const& rBase, Path::Component const& rChildName, rtl::OUString const& aSubTypeName );
+
+ private:
+ // ChangeTreeAction implementations
+ virtual void handle(ValueChange const& aValueNode);
+ virtual void handle(AddNode const& aAddNode);
+ virtual void handle(RemoveNode const& aRemoveNode);
+ virtual void handle(SubtreeChange const& aSubtree);
+
+ bool implSetLocation(NodeChangeLocation& rLocation_, Change const& aOriginal_, bool bSet_) const;
+ void implAdd(NodeChangeInformation const& aChangeInfo_);
+ Path::Component implGetNodeName(Change const& _aChange_) const;
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_COLLECTCHANGES_HXX_
diff --git a/configmgr/source/treemgr/configdefaultprovider.cxx b/configmgr/source/treemgr/configdefaultprovider.cxx
new file mode 100644
index 000000000000..d83ea2340171
--- /dev/null
+++ b/configmgr/source/treemgr/configdefaultprovider.cxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configdefaultprovider.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "configdefaultprovider.hxx"
+#include "defaultproviderproxy.hxx"
+#include "noderef.hxx"
+#include "valuenode.hxx"
+#include "tree.hxx"
+#include "options.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+// class DefaultProvider
+//-----------------------------------------------------------------------------
+
+// standard c/d-tors to make compiler barrier
+DefaultProvider DefaultProvider::createEmpty()
+{
+ return DefaultProvider(NULL);
+}
+//-----------------------------------------------------------------------------
+
+DefaultProvider DefaultProvider::create(rtl::Reference< Tree > const& _aRootTree, RequestOptions const& _aOptions,
+ rtl::Reference< TreeManager > const & _xDefaultProvider,
+ IDefaultableTreeManager* _pDefaultableTree)
+{
+ OSL_PRECOND( !isEmpty(_aRootTree.get()), "ERROR: Cannot create DefaultProvider for NULL tree");
+
+ rtl::Reference< DefaultProviderProxy > xNewProxy;
+
+ if (!isEmpty(_aRootTree.get()))
+ {
+ xNewProxy = new DefaultProviderProxy(_xDefaultProvider,_pDefaultableTree,
+ _aRootTree->getRootPath(), _aOptions );
+ }
+
+ return DefaultProvider( xNewProxy );
+}
+//-----------------------------------------------------------------------------
+
+DefaultProvider::DefaultProvider(DefaultProvider const& _aOther)
+: m_aProxy(_aOther.m_aProxy)
+{
+}
+//-----------------------------------------------------------------------------
+
+DefaultProvider& DefaultProvider::operator=(DefaultProvider const& _aOther)
+{
+ m_aProxy = _aOther.m_aProxy;
+ return *this;
+}
+//-----------------------------------------------------------------------------
+
+DefaultProvider::~DefaultProvider()
+{
+}
+//-----------------------------------------------------------------------------
+
+DefaultProvider::DefaultProvider(rtl::Reference< DefaultProviderProxy > const& _xProviderProxy)
+: m_aProxy(_xProviderProxy)
+{
+}
+//-----------------------------------------------------------------------------
+
+/// tries to load a default instance of the specified node
+std::auto_ptr<ISubtree> DefaultProvider::getDefaultTree(
+ rtl::Reference< Tree > const& _aTree, NodeRef const& _aNode
+ ) const SAL_THROW((com::sun::star::uno::Exception))
+{
+ std::auto_ptr<ISubtree> aRet;
+
+ node::Attributes aAttributes = _aTree->getAttributes(_aNode);
+
+// if (aAttributes.bDefaulted)
+// clone the ISubtree (no interface for that) :-(
+
+ if (m_aProxy.is() && aAttributes.existsInDefault())
+ aRet = m_aProxy->getDefaultTree(_aTree->getAbsolutePath(_aNode));
+
+ return aRet;
+}
+
+//-----------------------------------------------------------------------------
+/// tries to load default data into the specified tree
+static bool shouldFetchDefaultData(rtl::Reference< Tree > const& _aTreeRef, bool & _rbHasDefaults)
+{
+ bool bShouldFetch = false;
+
+ node::Attributes aAttributes = _aTreeRef->getAttributes(_aTreeRef->getRootNode());
+
+ if (aAttributes.isDefault())
+ _rbHasDefaults = true;
+
+ // in replaced/added parts, defaults are considered non-existing
+ else if (!aAttributes.isReplacedForUser())
+ _rbHasDefaults = false;
+
+ else
+ bShouldFetch = true;
+
+ return bShouldFetch;
+}
+
+//-----------------------------------------------------------------------------
+/// tries to load default data into the specified tree
+bool DefaultProvider::fetchDefaultData(rtl::Reference< Tree > const& _aTreeRef) const SAL_THROW((com::sun::star::uno::Exception))
+{
+ bool bHasDefaults = false;
+
+ if (shouldFetchDefaultData(_aTreeRef,bHasDefaults) && m_aProxy.is() )
+ bHasDefaults = m_aProxy->fetchDefaultData();
+
+ return bHasDefaults;
+}
+
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/configexcept.cxx b/configmgr/source/treemgr/configexcept.cxx
new file mode 100644
index 000000000000..3c8bf664cbcc
--- /dev/null
+++ b/configmgr/source/treemgr/configexcept.cxx
@@ -0,0 +1,184 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configexcept.cxx,v $
+ * $Revision: 1.7.10.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "configexcept.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+ //---------------------------------------------------------------------
+ Exception::Exception(char const* sAsciiMessage)
+ : m_sAsciiMessage(sAsciiMessage)
+ {
+ }
+ //---------------------------------------------------------------------
+ Exception::Exception(rtl::OString const& sAsciiMessage)
+ : m_sAsciiMessage(sAsciiMessage)
+ {
+ }
+ //---------------------------------------------------------------------
+
+ rtl::OUString Exception::message() const
+ {
+
+ return rtl::OStringToOUString( m_sAsciiMessage, RTL_TEXTENCODING_ASCII_US );
+ }
+ //---------------------------------------------------------------------
+ char const* Exception::what() const
+ {
+ return m_sAsciiMessage.getLength() ? m_sAsciiMessage.getStr() : "FAILURE in CONFIGURATION: No description available";
+ }
+ //---------------------------------------------------------------------
+
+ static const char c_sInvalidNamePre[] = "CONFIGURATION: Invalid path or name: ";
+ static const char c_sInvalidName[] = "CONFIGURATION: <Invalid path or name>";
+//-----------------------------------------------------------------------------
+
+ //---------------------------------------------------------------------
+
+ InvalidName::InvalidName(rtl::OUString const& sName, char const* sAsciiDescription)
+ : Exception( rtl::OString(RTL_CONSTASCII_STRINGPARAM(c_sInvalidName)) += sAsciiDescription )
+ , m_sName( sName.concat(rtl::OUString::createFromAscii(sAsciiDescription)) )
+ {
+ }
+ //---------------------------------------------------------------------
+
+ rtl::OUString InvalidName::message() const
+ {
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(c_sInvalidNamePre)).concat( m_sName );
+ }
+//-----------------------------------------------------------------------------
+
+ static const char c_sViolation[] = "CONFIGURATION: Update Violates Constraint: ";
+ //---------------------------------------------------------------------
+
+ ConstraintViolation::ConstraintViolation(char const* sConstraint)
+ : Exception( rtl::OString(RTL_CONSTASCII_STRINGPARAM(c_sViolation)) += sConstraint)
+ {
+ }
+
+//-----------------------------------------------------------------------------
+
+ static const char c_sTypeMismatch[] = "CONFIGURATION: Data Types do not match: ";
+ //---------------------------------------------------------------------
+ rtl::OUString TypeMismatch::describe(rtl::OUString const& sFoundType, rtl::OUString const& sExpectedType)
+ {
+ rtl::OUString sRet = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Found Type: '"));
+ sRet += sFoundType;
+ if (sExpectedType.getLength() != 0)
+ {
+ sRet += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("' - Expected Type: '"));
+ sRet += sExpectedType;
+ sRet += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("'"));
+ }
+ else
+ {
+ sRet += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("' is not valid in this context"));
+ }
+ return sRet;
+ }
+ //---------------------------------------------------------------------
+
+ //---------------------------------------------------------------------
+
+ TypeMismatch::TypeMismatch(rtl::OUString const& sType1, rtl::OUString const& sType2)
+ : Exception( rtl::OString(RTL_CONSTASCII_STRINGPARAM(c_sTypeMismatch)) )
+ , m_sTypes( describe(sType1,sType2) )
+ {
+ }
+ //---------------------------------------------------------------------
+ TypeMismatch::TypeMismatch(rtl::OUString const& sType1, rtl::OUString const& sType2, char const* sAsciiDescription)
+ : Exception( rtl::OString(RTL_CONSTASCII_STRINGPARAM(c_sTypeMismatch)) += sAsciiDescription)
+ , m_sTypes( describe(sType1,sType2).concat(rtl::OUString::createFromAscii(sAsciiDescription)) )
+ {
+ }
+ //---------------------------------------------------------------------
+
+ rtl::OUString TypeMismatch::message() const
+ {
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(c_sTypeMismatch)).concat( m_sTypes );
+ }
+//-----------------------------------------------------------------------------
+ }
+
+ namespace configapi
+ {
+//-----------------------------------------------------------------------------
+ ExceptionMapper::ExceptionMapper(configuration::Exception& e)
+ : m_eOriginal(e)
+ , m_xContext()
+ , m_sMessage(e.message())
+ {
+ }
+ //---------------------------------------------------------------------
+
+ ExceptionMapper::~ExceptionMapper()
+ {
+ }
+ //---------------------------------------------------------------------
+
+ void ExceptionMapper::setContext(uno::XInterface* pContext)
+ {
+ m_xContext = pContext;
+ }
+ //---------------------------------------------------------------------
+
+ rtl::OUString ExceptionMapper::message() const
+ {
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FAILURE in CONFIGMGR: ")).concat( m_sMessage );
+ }
+ //---------------------------------------------------------------------
+
+ uno::Reference<uno::XInterface> ExceptionMapper::context() const
+ {
+ return m_xContext;
+ }
+ //---------------------------------------------------------------------
+
+ void ExceptionMapper::illegalArgument(sal_Int16 nArgument) throw(lang::IllegalArgumentException)
+ {
+ throw lang::IllegalArgumentException(message(),context(),nArgument);
+ }
+ //---------------------------------------------------------------------
+
+ void ExceptionMapper::unhandled() throw(uno::RuntimeException)
+ {
+ throw uno::RuntimeException(message(),context());
+ }
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/treemgr/configgroup.cxx b/configmgr/source/treemgr/configgroup.cxx
new file mode 100644
index 000000000000..79eb3b09ab94
--- /dev/null
+++ b/configmgr/source/treemgr/configgroup.cxx
@@ -0,0 +1,407 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configgroup.cxx,v $
+ * $Revision: 1.14.14.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "configgroup.hxx"
+#include "configset.hxx"
+#include "valueref.hxx"
+#include "anynoderef.hxx"
+#include "nodechange.hxx"
+#include "nodechangeimpl.hxx"
+#include "tree.hxx"
+#include "groupnodeimpl.hxx"
+#include "valuenodeimpl.hxx"
+#include "typeconverter.hxx"
+#include "tracer.hxx"
+#include <com/sun/star/script/XTypeConverter.hpp>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+
+//-----------------------------------------------------------------------------
+// class GroupUpdateHelper
+//-----------------------------------------------------------------------------
+
+GroupUpdateHelper::GroupUpdateHelper(rtl::Reference< Tree > const& aParentTree, NodeRef const& aGroupNode)
+: m_aTree(aParentTree)
+, m_aNode(aGroupNode)
+{
+ implValidateTree(m_aTree);
+ implValidateNode(m_aTree,m_aNode);
+
+ if (! view::ViewTreeAccess(m_aTree.get()).isGroupNode(m_aNode) )
+ throw Exception("INTERNAL ERROR: Group Member Update: node is not a group");
+}
+//-----------------------------------------------------------------------------
+
+void GroupUpdateHelper::implValidateTree(rtl::Reference< Tree > const& aTree) const
+{
+ if (isEmpty(aTree.get()))
+ throw Exception("INTERNAL ERROR: Group Member Update: Unexpected NULL tree");
+
+ // check for proper nesting
+ for(rtl::Reference<Tree> aTestTree = aTree;
+ aTestTree != m_aTree; // search this as ancestor tree
+ aTestTree = aTestTree->getContextTree() )
+ {
+ if (!aTestTree.is()) // no more trees to look for
+ throw Exception("INTERNAL ERROR: Group Member Update: improper tree relationship");
+ }
+}
+//-----------------------------------------------------------------------------
+
+void GroupUpdateHelper::implValidateNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode) const
+{
+ if (!aNode.isValid())
+ throw Exception("INTERNAL ERROR: Group Member Update: Unexpected NULL node");
+
+ if (!aTree->isValidNode(aNode.getOffset()))
+ throw Exception("INTERNAL ERROR: Group Member Update: node does not match tree");
+}
+//-----------------------------------------------------------------------------
+
+void GroupUpdateHelper::implValidateNode(rtl::Reference< Tree > const& aTree, ValueRef const& aNode) const
+{
+ if (!aNode.isValid())
+ throw Exception("INTERNAL ERROR: Group Member Update: Unexpected NULL node");
+
+ if (!aTree->isValidValueNode(aNode))
+ throw Exception("INTERNAL ERROR: Group Member Update: changed node does not match tree");
+
+ if (aTree->getAttributes(aNode).isReadonly())
+ throw ConstraintViolation( "Group Member Update: Node is read-only !" );
+
+}
+//-----------------------------------------------------------------------------
+
+void GroupUpdateHelper::validateNode(ValueRef const& aNode) const
+{
+ implValidateNode(m_aTree,aNode);
+}
+//-----------------------------------------------------------------------------
+
+void GroupUpdateHelper::validateNode(NodeRef const& aNode) const
+{
+ implValidateNode(m_aTree,aNode);
+}
+//-----------------------------------------------------------------------------
+
+/** a helper that gets the UNO <type scope='com::sun::star::uno'>Type</type>
+ for a UNO <type scope='com::sun::star::uno'>Any</type>.
+*/
+static inline com::sun::star::uno::Type getUnoAnyType()
+{
+ com::sun::star::uno::Any const * const selectAny = 0;
+ return ::getCppuType(selectAny);
+}
+//-----------------------------------------------------------------------------
+
+bool isPossibleValueType(com::sun::star::uno::Type const& aValueType)
+{
+ switch(aValueType.getTypeClass())
+ {
+ case uno::TypeClass_BOOLEAN:
+ case uno::TypeClass_SHORT:
+ case uno::TypeClass_LONG:
+ case uno::TypeClass_HYPER:
+ case uno::TypeClass_DOUBLE:
+ case uno::TypeClass_STRING:
+ return true;
+
+ case uno::TypeClass_SEQUENCE:
+ switch(getSequenceElementType(aValueType).getTypeClass())
+ {
+ case uno::TypeClass_BYTE: // scalar binary
+
+ case uno::TypeClass_BOOLEAN:
+ case uno::TypeClass_SHORT:
+ case uno::TypeClass_LONG:
+ case uno::TypeClass_HYPER:
+ case uno::TypeClass_DOUBLE:
+ case uno::TypeClass_STRING:
+ return true;
+
+ case uno::TypeClass_SEQUENCE:
+ {
+ uno::Sequence< uno::Sequence< sal_Int8 > > const * const forBinaryList = 0;
+ return !!(aValueType == ::getCppuType(forBinaryList));
+ }
+
+ default:
+ return false;
+ }
+
+ default:
+ return false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+bool convertCompatibleValue(com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> const& xTypeConverter, uno::Any& rConverted, com::sun::star::uno::Any const& rNewValue, com::sun::star::uno::Type const& rTargetType)
+{
+ OSL_ASSERT( isPossibleValueType(rTargetType) );
+
+ if (rTargetType == rNewValue.getValueType())
+ {
+ rConverted = rNewValue;
+ return true;
+ }
+
+ if (xTypeConverter.is())
+ try
+ {
+ rConverted = xTypeConverter->convertTo(rNewValue,rTargetType);
+
+ OSL_ASSERT( rConverted.getValueType() == rTargetType );
+ }
+ catch(uno::RuntimeException&) { throw; }
+ catch(css::lang::IllegalArgumentException&)
+ {
+ // try to do more conversion here ?!
+ return false;
+ }
+ catch(css::script::CannotConvertException&)
+ {
+ // try to do more conversion here ?!
+ return false;
+ }
+ catch(uno::Exception&)
+ {
+ OSL_ENSURE(sal_False, "ValueUpdater::convertValue : generic exception ... thought we caught all allowed exceptions !");
+ // try to do more conversion here ?!
+ return false;
+ }
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class GroupUpdater
+//-----------------------------------------------------------------------------
+
+GroupUpdater::GroupUpdater(rtl::Reference< Tree > const& aParentTree, NodeRef const& aGroupNode, com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> const& xConverter)
+: m_aHelper(aParentTree,aGroupNode)
+, m_xTypeConverter(xConverter)
+{
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any GroupUpdater::implValidateValue(rtl::Reference< Tree > const& aTree, ValueRef const& aNode, com::sun::star::uno::Any const& aValue) const
+{
+ com::sun::star::uno::Type aValueType = aValue.getValueType();
+ com::sun::star::uno::Type aTargetType = aTree->getUnoType(aNode);
+
+ OSL_ENSURE( aTargetType.getTypeClass() == uno::TypeClass_ANY || isPossibleValueType(aTargetType),
+ "Invalid value type found on existing property" );
+
+ OSL_ASSERT( aValueType.getTypeClass() != uno::TypeClass_ANY);
+
+ com::sun::star::uno::Any aRet;
+
+ if (!aValue.hasValue())
+ {
+ if (!aTree->getAttributes(aNode).isNullable())
+ {
+ rtl::OString sError("Group Member Update: Node (");
+ sError += OUSTRING2ASCII(aNode.m_sNodeName);
+ sError += ") is not nullable !";
+ throw ConstraintViolation( sError );
+ }
+ OSL_ASSERT( !aRet.hasValue() );
+ }
+
+ else if (aValueType == aTargetType)
+ {
+ aRet = aValue;
+ }
+
+ else if (aTargetType == getUnoAnyType())
+ {
+ if ( ! isPossibleValueType(aValueType) )
+ throw TypeMismatch(aValueType.getTypeName(), aTargetType.getTypeName(), " - new property value has no legal configuration data type");
+
+ // OK - any type
+ aRet = aValue;
+ }
+
+ else
+ {
+ if (!convertCompatibleValue(m_xTypeConverter, aRet, aValue,aTargetType))
+ throw TypeMismatch(aValueType.getTypeName(), aTargetType.getTypeName(), " cannot set incompatible value");
+ }
+
+
+ OSL_ASSERT( !aRet.hasValue() || isPossibleValueType(aRet.getValueType()) );
+
+ return aRet;
+}
+//-----------------------------------------------------------------------------
+
+NodeChange GroupUpdater::validateSetValue(ValueRef const& aValueNode, com::sun::star::uno::Any const& newValue )
+{
+ m_aHelper.validateNode(aValueNode);
+
+ com::sun::star::uno::Any aNewValue = implValidateValue(m_aHelper.tree(), aValueNode, newValue);
+
+ // now build the specific change
+ std::auto_ptr<ValueChangeImpl> pChange( new ValueReplaceImpl(aNewValue) );
+
+ NodeRef aParent = m_aHelper.tree()->getParent(aValueNode);
+ pChange->setTarget(
+ view::ViewTreeAccess(m_aHelper.tree().get()).toGroupNode(aParent),
+ aValueNode.m_sNodeName
+ );
+
+ return NodeChange(pChange.release());
+}
+
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// helper class NodeDefaulter
+//-----------------------------------------------------------------------------
+
+namespace
+{
+ struct NodeDefaulter : NodeVisitor
+ {
+ GroupDefaulter& updater;
+ NodeChanges result;
+
+ explicit
+ NodeDefaulter(GroupDefaulter& _rUpdater) : updater(_rUpdater), result() {}
+
+ /// do the operation on <var>aNode</var>. needs to be implemented by concrete visitor classes
+ Result handle(rtl::Reference< Tree > const& aTree, NodeRef const& aNode);
+
+ /// do the operation on <var>aValue</var>. needs to be implemented by concrete visitor classes
+ Result handle(rtl::Reference< Tree > const& aTree, ValueRef const& aValue);
+
+ inline void addResult(NodeChange const& aChange)
+ {
+ if (aChange.maybeChange())
+ this->result.add(aChange);
+ }
+ };
+
+ NodeVisitor::Result NodeDefaulter::handle(rtl::Reference< Tree > const& , NodeRef const& aNode)
+ {
+ addResult( updater.validateSetToDefaultState(aNode) );
+ return CONTINUE;
+ }
+
+ NodeVisitor::Result NodeDefaulter::handle(rtl::Reference< Tree > const& , ValueRef const& aValue)
+ {
+ addResult( updater.validateSetToDefaultValue(aValue) );
+ return CONTINUE;
+ }
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class GroupDefaulter
+//-----------------------------------------------------------------------------
+
+GroupDefaulter::GroupDefaulter(rtl::Reference< Tree > const& _aParentTree, NodeRef const& _aGroupNode, DefaultProvider const& _aProvider)
+: m_aHelper(_aParentTree,_aGroupNode)
+, m_aDefaultProvider(_aProvider)
+, m_bHasDoneSet(false)
+{
+}
+//-----------------------------------------------------------------------------
+bool GroupDefaulter::isDataAvailable(rtl::Reference< Tree > const& _aParentTree, NodeRef const& _aGroupNode)
+{
+ return _aParentTree->areValueDefaultsAvailable(_aGroupNode);
+}
+//-----------------------------------------------------------------------------
+bool GroupDefaulter::ensureDataAvailable(rtl::Reference< Tree > const& _aParentTree, NodeRef const& _aGroupNode, DefaultProvider const& _aDataSource)
+{
+ return isDataAvailable(_aParentTree, _aGroupNode) ||
+ _aDataSource.fetchDefaultData( _aParentTree );
+}
+//-----------------------------------------------------------------------------
+
+NodeChange GroupDefaulter::validateSetToDefaultValue(ValueRef const& aValueNode)
+{
+ m_aHelper.validateNode(aValueNode);
+
+ if (!m_aHelper.tree()->hasNodeDefault(aValueNode))
+ throw Exception("INTERNAL ERROR: Group Member Update: Node has no default value" );
+
+ // now build the specific change
+ std::auto_ptr<ValueChangeImpl> pChange( new ValueResetImpl() );
+
+ NodeRef aParent = m_aHelper.tree()->getParent(aValueNode);
+ pChange->setTarget(
+ view::ViewTreeAccess(m_aHelper.tree().get()).toGroupNode(aParent),
+ aValueNode.m_sNodeName
+ );
+
+ return NodeChange(pChange.release());
+}
+//-----------------------------------------------------------------------------
+
+NodeChange GroupDefaulter::validateSetToDefaultState(NodeRef const& aNode)
+{
+ m_aHelper.validateNode(aNode);
+
+ NodeChange aResult;
+
+ // only works for set nodes - groups are left alone
+ if ( view::ViewTreeAccess(m_aHelper.tree().get()).isSetNode(aNode) )
+ {
+ aResult = SetDefaulter( m_aHelper.tree(), aNode, m_aDefaultProvider ).validateSetToDefaultState();
+ }
+
+ m_bHasDoneSet = aResult.maybeChange();
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+NodeChanges GroupDefaulter::validateSetAllToDefault()
+{
+ NodeDefaulter aDefaulter(*this);
+
+ m_aHelper.tree()->dispatchToChildren(m_aHelper.node(),aDefaulter);
+
+ return aDefaulter.result;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/configpath.cxx b/configmgr/source/treemgr/configpath.cxx
new file mode 100644
index 000000000000..1691245e611c
--- /dev/null
+++ b/configmgr/source/treemgr/configpath.cxx
@@ -0,0 +1,1001 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configpath.cxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "configpath.hxx"
+#include "configexcept.hxx"
+#include <rtl/ustrbuf.hxx>
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+
+#ifndef CFG_PATH_STRICT
+//#define CFG_PATH_STRICT 1
+#endif
+
+#define dprint(a,b,c)
+
+namespace configmgr
+{
+ namespace configuration
+ {
+
+ //-------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Name validation
+//-----------------------------------------------------------------------------
+namespace
+{
+ //-------------------------------------------------------------------------
+ inline
+ bool isValidNameStart(sal_Unicode ch) SAL_THROW(())
+ {
+ return (sal_Unicode('A') <= ch && ch <= sal_Unicode('Z')) ||
+ (sal_Unicode('a') <= ch && ch <= sal_Unicode('z')) ||
+ sal_Unicode('_') == ch;
+ }
+ inline
+ bool isValidNameCont(sal_Unicode ch) SAL_THROW(())
+ {
+ return ( (sal_Unicode('0') <= ch && ch <= sal_Unicode('9'))
+ || (sal_Unicode('.') == ch) // eg for module names
+ || (sal_Unicode('-') == ch) // eg for locale names
+ || (sal_Unicode(':') == ch) // support special namespaced names
+ );
+ }
+
+ //-------------------------------------------------------------------------
+}
+//-----------------------------------------------------------------------------
+
+bool isSimpleName(rtl::OUString const& sName) SAL_THROW(())
+{
+ sal_Unicode const* const pStr = sName.getStr();
+ sal_Unicode const* const pEnd = pStr + sName.getLength();
+
+ if ( (pStr == pEnd) || !isValidNameStart(*pStr) )
+ return false;
+
+ for (sal_Unicode const* pValidate = pStr+1; pValidate != pEnd; ++pValidate)
+ {
+ if (!isValidNameStart(*pValidate) && !isValidNameCont(*pValidate))
+ return false;
+ }
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString validateNodeName(rtl::OUString const& sName)
+{
+ if (!isSimpleName(sName))
+ throw InvalidName(sName, "is not a valid name for a configuration node");
+
+ return sName;
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString validateElementName(rtl::OUString const& sName)
+{
+ if (sName.getLength() == 0)
+ throw InvalidName(sName, "is not a valid name for a configuration item (empty names are not permitted)");
+
+ return sName;
+}
+//-----------------------------------------------------------------------------
+
+namespace // path helpers I
+{
+//-----------------------------------------------------------------------------
+ const sal_Unicode c_cDelimiter = '/';
+
+ const sal_Unicode c_lBracket = '[', c_rBracket = ']';
+
+ const sal_Unicode c_cAnytype = '*';
+//-----------------------------------------------------------------------------
+
+ // Textually an Absolute path starts with a slash
+ static
+ inline
+ bool detectAbsolutePath(sal_Unicode const* _pPath) SAL_THROW(())
+ {
+ OSL_ASSERT( _pPath != NULL );
+ return *_pPath == c_cDelimiter;
+ }
+//-----------------------------------------------------------------------------
+
+ static
+ inline
+ rtl::OUString makeWildcardType() SAL_THROW(())
+ {
+ return rtl::OUString(&c_cAnytype,1);
+ }
+//-----------------------------------------------------------------------------
+
+ // even handles empty strings (if NUL-terminated)
+ static
+ inline
+ bool isWildcardType(sal_Unicode const* _sType) SAL_THROW(())
+ {
+ OSL_ASSERT( _sType != NULL );
+ return _sType[0] == c_cAnytype &&
+ _sType[1] == 0;
+ }
+//-----------------------------------------------------------------------------
+
+ static
+ inline
+ bool isEmptyString(sal_Unicode const* _sType) SAL_THROW(())
+ {
+ OSL_ASSERT( _sType != NULL );
+ return _sType[0] == 0;
+ }
+//-----------------------------------------------------------------------------
+ static
+ inline
+ sal_Unicode lastChar(rtl::OUString const& _sString) SAL_THROW(())
+ {
+ sal_Int32 const nLen = _sString.getLength();
+
+ OSL_PRECOND( nLen > 0, "Non-empty string expected");
+
+ return _sString[nLen-1];
+ }
+//-----------------------------------------------------------------------------
+
+ rtl::OUString implMakeCompositeName(rtl::OUString const& _sBaseName, rtl::OUString const& _sPredicate) SAL_THROW((InvalidName));
+ void implSplitCompositeName(rtl::OUString const& _aCompositeName, rtl::OUString& _rBaseName, rtl::OUString& _rPredicate) SAL_THROW(());
+//-----------------------------------------------------------------------------
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+namespace Path
+{
+//-----------------------------------------------------------------------------
+// class configuration::Path::Component
+//-----------------------------------------------------------------------------
+
+inline // though public, this method is not available outside this translation unit
+Component::Component(rtl::OUString const& _sName) SAL_THROW(())
+: m_aName(_sName)
+{
+}
+//-----------------------------------------------------------------------------
+
+bool Component::isSimpleName() const SAL_THROW(())
+{
+ return m_aName.getLength() != 0 && lastChar(m_aName) != c_rBracket;
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString Component::getName() const SAL_THROW(())
+{
+ if (isSimpleName()) return m_aName;
+
+ rtl::OUString sName, sType;
+ implSplitCompositeName(m_aName,sType,sName);
+
+ return sName;
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString Component::getTypeName() const SAL_THROW(())
+{
+ if (isSimpleName()) return rtl::OUString();
+
+ rtl::OUString sName, sType;
+ implSplitCompositeName(m_aName,sType,sName);
+
+ return sType;
+}
+//-----------------------------------------------------------------------------
+
+Component makeEmptyComponent() SAL_THROW(())
+{
+ return Component( rtl::OUString() );
+}
+//-----------------------------------------------------------------------------
+
+Component wrapSimpleName(rtl::OUString const& _sName)
+{
+ OSL_ENSURE( isSimpleName(_sName), "Simple name expected creating path component");
+ if (!isSimpleName(_sName))
+ throw InvalidName(_sName, "is not a simple name. Cannot convert to path component");
+
+ return Component( _sName );
+}
+//-----------------------------------------------------------------------------
+
+Component makeCompositeName(rtl::OUString const& _sElementName, rtl::OUString const& _sTypeName)
+{
+ return Component( implMakeCompositeName(_sTypeName,_sElementName) );
+}
+//-----------------------------------------------------------------------------
+
+
+bool matches(Component const& lhs,Component const& rhs) SAL_THROW(())
+{
+ // this extra preflight check might be left out (is it good for performance ?)
+ if (lhs.getInternalName() == rhs.getInternalName())
+ return true;
+
+ if (lhs.getName() != rhs.getName())
+ return false;
+
+ // simple names are considered equivalent to wildcard namess
+ if (lhs.isSimpleName() || rhs.isSimpleName())
+ return true;
+
+ rtl::OUString aTypeLHS = lhs.getTypeName();
+ rtl::OUString aTypeRHS = rhs.getTypeName();
+
+ // this would need an extra test without our preflight check
+ OSL_ASSERT(aTypeLHS != aTypeRHS); // would have been dicovered by first check
+
+ if ( isWildcardType(aTypeLHS) || isWildcardType(aTypeRHS) )
+ return true;
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// weak comparison of components
+//-----------------------------------------------------------------------------
+bool before(Component const& lhs, Component const& rhs) SAL_THROW(())
+{ return lhs.getName() < rhs.getName(); }
+
+//-----------------------------------------------------------------------------
+bool equiv(Component const& lhs, Component const& rhs) SAL_THROW(())
+{ return lhs.getName() == rhs.getName(); }
+
+//-----------------------------------------------------------------------------
+size_t hashCode(Component const& comp) SAL_THROW(())
+{ return comp.getName().hashCode(); }
+
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class configuration::Path::Rep
+//-----------------------------------------------------------------------------
+void Rep::check_not_empty() const
+{
+ if (m_aComponents.empty())
+ {
+ OSL_ENSURE(!m_aComponents.empty(),"Trying to access components of an empty path");
+ throw Exception("Trying to access components of an empty path");
+ }
+}
+//-----------------------------------------------------------------------------
+
+void Rep::prepend(Rep const& _aOther) SAL_THROW(())
+{
+ // to prepend the other path append its components
+ m_aComponents.insert( m_aComponents.end(),
+ _aOther.m_aComponents.begin(),
+ _aOther.m_aComponents.end());
+
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString Rep::toString(bool _bAbsolute) const SAL_THROW(())
+{
+ std::vector<Component>::const_reverse_iterator cur = begin();
+ std::vector<Component>::const_reverse_iterator const stop = end();
+
+ rtl::OUStringBuffer sRet;
+
+ if (!_bAbsolute && cur != stop)
+ sRet = cur++->toPathString();
+
+ for ( ;cur != stop; ++cur)
+ sRet.append( c_cDelimiter ).append( cur->toPathString() );
+
+ return sRet.makeStringAndClear();
+}
+//-----------------------------------------------------------------------------
+
+size_t Rep::hashCode() const SAL_THROW(())
+{
+ const unsigned long mangle_factor = 11; // 1011 (2)
+ unsigned long nHash = 0;
+ for (std::vector<Component>::const_reverse_iterator it = begin(), stop = end(); it != stop; ++it)
+ {
+ nHash = mangle_factor*nHash + Path::hashCode(*it);
+ }
+ return nHash;
+}
+//-----------------------------------------------------------------------------
+
+bool before(Rep const& lhs, Rep const& rhs) SAL_THROW(())
+{
+ return std::lexicographical_compare(lhs.begin(),lhs.end(),rhs.begin(),rhs.end(), Before());
+}
+//-----------------------------------------------------------------------------
+
+bool equiv(Rep const& lhs, Rep const& rhs) SAL_THROW(())
+{
+ return (lhs.countComponents() == rhs.countComponents()) &&
+ std::equal(lhs.begin(),lhs.end(),rhs.begin(),Equiv());
+}
+//-----------------------------------------------------------------------------
+
+bool matches(Rep const& lhs, Rep const& rhs) SAL_THROW(())
+{
+ return (lhs.countComponents() == rhs.countComponents()) &&
+ std::equal(lhs.begin(),lhs.end(),rhs.begin(),Matches());
+}
+//-----------------------------------------------------------------------------
+
+bool isAbsolutePath(rtl::OUString const& _sPath) SAL_THROW(())
+{
+ return detectAbsolutePath(_sPath);
+}
+//-----------------------------------------------------------------------------
+
+bool hasMatchingPrefix(Rep const& _aPath, Rep const& _aPrefix) SAL_THROW(())
+{
+ return (_aPath.countComponents() >= _aPrefix.countComponents()) &&
+ std::equal( _aPrefix.begin(), _aPrefix.end(), _aPath.begin(), Matches());
+}
+//-----------------------------------------------------------------------------
+
+Rep stripMatchingPrefix(Rep const& _aPath,Rep const& _aPrefix) // SAL_THROW((InvalidName))
+{
+ Rep aResult(_aPath);
+
+ for (std::vector<Component>::const_reverse_iterator it = _aPrefix.begin(); it != _aPrefix.end(); ++it)
+ {
+ if (aResult.isEmpty() || !matches(*it,aResult.getFirstName()))
+ throw InvalidName(aResult.getFirstName().toPathString(), "does not match the expected location.");
+
+ aResult.dropFirstName();
+ }
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+} // namespace Path
+//-----------------------------------------------------------------------------
+
+namespace
+{
+//-----------------------------------------------------------------------------
+ const sal_Unicode c_quot = '\"';
+ const sal_Unicode c_apos = '\'';
+ const sal_Unicode c_amp = '&';
+
+ const sal_Unicode c_end_escape = ';';
+
+ const sal_Unicode c_normal_quot = c_apos;
+ //-------------------------------------------
+ static sal_Char const c_amp_name[] = "&amp;";
+ static sal_Char const c_apos_name[] = "&apos;";
+ static sal_Char const c_quot_name[] = "&quot;";
+
+ const sal_Int32 c_nMinEscapeLen = sizeof c_amp_name - 1;
+ const sal_Int32 c_nMaxEscapeLen = sizeof c_quot_name - 1;
+//-------------------------------------------------------------------------
+ /// distinguishes which kind of path is held in a path object
+ enum PathType { eRELATIVE = 1, eABSOLUTE = 2 };
+
+//-----------------------------------------------------------------------------
+ // missing or mis leading in SAL/rtl: pStr1[nLength] must NOT be evaluated
+ static
+ sal_Int32 cfg_ustr_ascii_compare_WithLength( const sal_Unicode* pStr1,
+ sal_Int32 nStr1Len,
+ const sal_Char* pStr2 )
+ {
+ while( nStr1Len )
+ {
+ sal_Int32 nRet = static_cast<sal_Int32>(*pStr1)-
+ static_cast<sal_Int32>(static_cast<unsigned char>(*pStr2));
+
+ if (nRet != 0 || *pStr2 == 0) return nRet;
+
+ ++pStr1;
+ ++pStr2;
+ --nStr1Len;
+ }
+
+ return -static_cast<sal_Int32>(static_cast<unsigned char>(*pStr2));
+ }
+//-----------------------------------------------------------------------------
+
+
+ /** find the char being escaped by the escape sequence in the given string range
+ @return
+ the char being escaped or zero, if the range is no known escape
+ */
+ sal_Unicode implParseEscape(sal_Unicode const * pBegin, sal_Unicode const * pEnd) SAL_THROW(())
+ {
+ OSL_PRECOND( pBegin < pEnd, "Nonempty string range expected" );
+ OSL_PRECOND( pBegin[0] == c_amp, "String range is not a possible escape: missing start marker" );
+ OSL_PRECOND( pEnd[-1] == c_end_escape, "String range is not a possible escape: missing end marker" );
+
+ sal_Int32 const nLen = pEnd - pBegin;
+
+ sal_Unicode chResult;
+
+ if ( c_nMinEscapeLen > nLen || nLen > c_nMaxEscapeLen) // quick check, if there is no possible match
+ chResult = 0;
+ // the standard escapes
+ else if (0 == cfg_ustr_ascii_compare_WithLength(pBegin,nLen,c_amp_name)) chResult = c_amp;
+ else if (0 == cfg_ustr_ascii_compare_WithLength(pBegin,nLen,c_apos_name)) chResult = c_apos;
+ else if (0 == cfg_ustr_ascii_compare_WithLength(pBegin,nLen,c_quot_name)) chResult = c_quot;
+ // extra escapes for XML compatibility
+ else if (0 == cfg_ustr_ascii_compare_WithLength(pBegin,nLen,"&lt;")) chResult = sal_Unicode('<');
+ else if (0 == cfg_ustr_ascii_compare_WithLength(pBegin,nLen,"&gt;")) chResult = sal_Unicode('>');
+ else chResult = 0;
+
+ return chResult;
+ }
+
+//-----------------------------------------------------------------------------
+
+ /** find the escape sequence to use for the given char
+ @return
+ an escape sequence, or NULL, if the char should not be escaped
+ */
+ inline
+ sal_Char const* implGetEscape(sal_Unicode ch ) SAL_THROW(())
+ {
+ switch (ch)
+ {
+ case c_amp: return c_amp_name;
+ case c_apos: return c_apos_name;
+ case c_quot: return c_quot_name;
+
+ default: return NULL;
+ }
+ }
+
+//-----------------------------------------------------------------------------
+
+ /** find the start of the path component ending before pEnd in the string starting at pBegin
+ @return
+ a pointer to the last character before pEnd that is not a name delimiter
+ */
+ sal_Unicode const * implFindNameStart(sal_Unicode const * pBegin, sal_Unicode const * pEnd) SAL_THROW(())
+ {
+ OSL_PRECOND(pBegin <= pEnd, "Invalid string range");
+
+ sal_Int32 const nLen = pEnd-pBegin;
+ sal_Int32 const nPos = rtl_ustr_lastIndexOfChar_WithLength(pBegin, nLen, c_cDelimiter) + 1;
+
+ OSL_ASSERT(0 <= nPos && nPos <= nLen);
+
+ return pBegin + nPos;
+ }
+//-----------------------------------------------------------------------------
+
+ /** find the start of the bracketed & quoted predicate ending before pEnd in the string starting at pBegin
+ @return
+ <ul><li>a pointer to the opening bracket matching the closing bracket at pEnd[-1], if found</li>
+ <li><var>pEnd</var>, if no bracketed string was found</li>
+ <li>NULL, if there was a closing bracket, but the beginning could not be discovered</li></ul>
+ */
+ sal_Unicode const * implFindPredicateStart(sal_Unicode const * pBegin, sal_Unicode const * pEnd) SAL_THROW(())
+ {
+ OSL_PRECOND(pBegin < pEnd, "Nonempty string range required");
+
+ if (pEnd == pBegin || pEnd[-1] != c_rBracket) return pEnd;
+
+ if (--pEnd == pBegin)
+ {
+ OSL_ENSURE(false, "Invalid path component: single ']'");
+ return NULL; // string was only "]"
+ }
+
+ sal_Unicode chQuote = *--pEnd;
+
+ if (chQuote != c_quot && chQuote != c_apos)
+ {
+ // should we support empty brackets ?
+ if (chQuote == c_lBracket)
+ {
+ OSL_ENSURE(false, "Empty predicate brackets found");
+ return NULL; // for now we don't
+
+ }
+
+ // should we support brackets with non-quoted strings ?
+ chQuote = c_lBracket; // for now we do
+ }
+
+ sal_Int32 nStart = rtl_ustr_lastIndexOfChar_WithLength(pBegin, pEnd-pBegin, chQuote);
+
+ if (chQuote != c_lBracket) // needed to support non-quoted strings
+ --nStart;
+
+ if (nStart < 0)
+ {
+ OSL_ENSURE(false, "Could not find opening quote or bracket for bracketed predicate");
+ return NULL;
+ }
+
+ if (pBegin[nStart] != c_lBracket)
+ {
+ OSL_ENSURE(false, "Illegal quote character in string");
+ return NULL; // for now we don't
+ }
+
+ return pBegin + nStart;
+ }
+//-----------------------------------------------------------------------------
+
+ /// find the position of the given char in the range given.
+ inline
+ sal_Int32 indexOfCharInRange(sal_Unicode const * pBegin, sal_Unicode const * pEnd, sal_Unicode ch) SAL_THROW(())
+ {
+ return rtl_ustr_indexOfChar_WithLength(pBegin, pEnd-pBegin, ch);
+ }
+//-----------------------------------------------------------------------------
+
+ /// find the position of the given char in the range given.
+ inline
+ bool containsChar(sal_Unicode const * pString, sal_Unicode ch) SAL_THROW(())
+ {
+ return rtl_ustr_indexOfChar(pString, ch) >= 0;
+ }
+//-----------------------------------------------------------------------------
+
+ /** validate and normalize a bracketed & quoted predicate from content the string range [pBegin,pEnd)
+ @param pRequiredEscapes
+ contains a list of characters that must be preescaped or are otherwise invalid
+ if NULL is passed, the source range is presumed to contain no escaped data
+ otherwise the ampersand (&) and all characters in the list are required to be escaped
+ @return
+ the normalized, bracketed and quoted predicate
+ @throw
+ InvalidName, if the predicate data is not valid
+ */
+ rtl::OUString implMakeNormalizedPredicate(sal_Unicode const * pBeginContent, sal_Unicode const * pEndContent, sal_Unicode const* pRequiredEscapes) SAL_THROW((InvalidName))
+ {
+ OSL_PRECOND(pBeginContent <= pEndContent, "Invalid string range");
+ if (pBeginContent == pEndContent)
+ return rtl::OUString();
+
+ rtl::OUStringBuffer aNormalized(pEndContent-pBeginContent + 4); // reserve approximate size initially
+
+ // prefix: opening bracket and quote
+ aNormalized.append(c_lBracket).append(c_normal_quot);
+
+ // content: copy over each char and handle escaping
+ for(sal_Unicode const * pCur = pBeginContent; pCur != pEndContent; ++pCur)
+ {
+ sal_Unicode ch = *pCur;
+
+ // maybe parse contained escaping
+ if (pRequiredEscapes)
+ {
+ if (ch == c_amp)
+ {
+ // find an escape end marker (after pCur). Result is pCur, if the end marker is not there
+ sal_Unicode const * pEndEscape = pCur + 1 + indexOfCharInRange(pCur+1,pEndContent,c_end_escape);
+ sal_Unicode ch2 = pCur != pEndEscape ? implParseEscape(pCur,pEndEscape+1) : 0;
+
+ if (ch2 != 0) // found and read a valid escape sequence
+ {
+ ch = ch2;
+ pCur = pEndEscape;
+ OSL_ASSERT(*pCur == c_end_escape);
+ }
+ else
+ {
+ OSL_ENSURE(false, "Character '&' must be escaped in this context");
+ #if 0
+ throw InvalidName(rtl::OUString(pBeginContent,pEndContent-pBeginContent),
+ "is not a valid element name string. "
+ "Character '&' must be escaped in this context");
+ #endif
+ }
+ }
+ else if ( containsChar(pRequiredEscapes, ch) )
+ {
+ throw InvalidName(rtl::OUString(pBeginContent,pEndContent-pBeginContent),
+ "is not a valid element name string. "
+ "Some characters must be escaped in this context");
+ }
+ }
+
+ // now append (escape if normal)
+ if (sal_Char const * pEscape = implGetEscape(ch))
+ aNormalized.appendAscii( pEscape );
+
+ else
+ aNormalized.append( ch );
+ }
+
+ // suffix: closing quote and bracket
+ aNormalized.append(c_normal_quot).append(c_rBracket);
+
+ return aNormalized.makeStringAndClear();
+ }
+//-----------------------------------------------------------------------------
+
+ /** extract and unescape the normalized predicate content in the string range [pBegin,pEnd)
+ @return
+ the denormalized predicate content
+ */
+ rtl::OUString implReadPredicate(sal_Unicode const * pBegin, sal_Unicode const * pEnd) SAL_THROW(())
+ {
+ OSL_PRECOND(pBegin <= pEnd, "Invalid string range");
+
+ rtl::OUStringBuffer aContent(pEnd-pBegin); // reserve approximate size initially
+
+ sal_Unicode const * pReadPos = pBegin;
+
+ // content: copy data, handling escapes
+ for(sal_Unicode const * pCur = pReadPos; pCur != pEnd; ++pCur)
+ {
+ if (*pCur != c_amp) continue; // no escape here
+
+ // handle an escape
+ // find an escape end marker (after pCur). Result is pCur, if the end marker is not there
+ sal_Unicode const * pEndEscape = pCur + 1 + indexOfCharInRange(pCur+1,pEnd,c_end_escape);
+
+ OSL_ENSURE(pEndEscape != pCur, "Found dangling ampersand in normalized data");
+
+ sal_Unicode ch = implParseEscape(pCur,pEndEscape+1);
+
+ OSL_ENSURE(ch != 0, "Found unreckognized escape in normalized data");
+
+ if (ch != 0) // found and read a valid escape sequence
+ {
+ // do copy of preceding data
+ aContent.append(pReadPos, pCur-pReadPos).append(ch);
+ pCur = pReadPos = pEndEscape;
+
+ ++pReadPos;
+
+ OSL_ASSERT(*pCur == c_end_escape);
+ }
+ // otherwise just treat the ampersand as a mormal character
+ }
+
+ // do copy of remaining data
+ if (pReadPos != pEnd)
+ aContent.append(pReadPos, pEnd-pReadPos);
+
+ return aContent.makeStringAndClear();
+ }
+//-----------------------------------------------------------------------------
+
+ /** validate and normalize the bracketed & quoted predicate in the string range [pBegin,pEnd)
+ @return
+ the normalized predicate
+ @throw
+ InvalidName, if the predicate is not valid
+ */
+ rtl::OUString implNormalizePredicate(sal_Unicode const * pBegin, sal_Unicode const * pEnd) SAL_THROW((InvalidName))
+ {
+ sal_Unicode sStopCharBuf[2];
+ sal_Unicode const * pStopChars;
+
+ OSL_PRECOND(pBegin < pEnd, "Nonempty string range expected");
+ OSL_PRECOND(pEnd-pBegin >= 2, "Bracketed string range expected");
+ OSL_PRECOND(pBegin[0] == c_lBracket,"Bracketed string range expected");
+ OSL_PRECOND(pEnd[-1] == c_rBracket, "Bracketed string range expected");
+
+ ++pBegin; --pEnd; // skip brackets
+
+ sal_Unicode const chUsedQuot = *pBegin;
+ if (chUsedQuot == c_apos || chUsedQuot == c_quot)
+ {
+ OSL_PRECOND(pBegin < pEnd && pEnd-pBegin >= 2, "Bracketed quoted string range expected");
+ OSL_PRECOND(pEnd[-1] == chUsedQuot, "Non-matching quotes in bracketed quoted string");
+
+ if (pEnd-pBegin <= 1 || pEnd[-1] != chUsedQuot)
+ throw InvalidName( rtl::OUString(pBegin, pEnd-pBegin), "is not a valid element predicate: quotes do not match");
+
+ ++pBegin; --pEnd; // skip quotes
+
+ sStopCharBuf[0] = chUsedQuot;
+ sStopCharBuf[1] = 0;
+
+ pStopChars = sStopCharBuf;
+ }
+
+ // non-quoted strings are not really valid, but we tolerate them
+ else
+ {
+ OSL_ENSURE(false, "Warning: Invalid path - non-quoted data in bracketed predicate");
+
+ static sal_Unicode const sGeneralStoppers[] = { c_quot, c_apos, c_rBracket, c_lBracket, 0 };
+
+ pStopChars = sGeneralStoppers;
+ }
+
+ if (pBegin == pEnd)
+ throw InvalidName(rtl::OUString(pBegin-1,2),"Empty element name in predicate");
+
+ return implMakeNormalizedPredicate(pBegin, pEnd, pStopChars);
+ }
+//-----------------------------------------------------------------------------
+ /// parse a path into a sequence of components
+ Path::Rep implParsePath(rtl::OUString const& _aPathString, PathType eType) SAL_THROW((InvalidName))
+ {
+ Path::Rep aResult;
+
+ dprint (stderr, "implParsePath '%s' ",
+ rtl::OUStringToOString(_aPathString, RTL_TEXTENCODING_UTF8).getStr());
+
+ sal_Unicode const * pBegin = _aPathString.getStr();
+ sal_Unicode const * pEnd = pBegin + _aPathString.getLength();
+
+ if (eType == eABSOLUTE)
+ {
+ if ( detectAbsolutePath(_aPathString) )
+ ++pBegin; // skip the leading slash
+
+#ifdef CFG_PATH_STRICT
+ else
+ OSL_ENSURE(false, "Warning: trying to parse relative path as absolute");
+#endif
+ }
+ else
+ OSL_ENSURE(!detectAbsolutePath(_aPathString), "ERROR: trying to parse absolute path as relative one");
+
+ if (detectAbsolutePath(pBegin))
+ throw InvalidName(_aPathString, "is not a valid path. Illegal empty first component");
+
+ else if (pBegin != pEnd && pEnd[-1] == '/')
+ {
+#ifdef CFG_PATH_STRICT
+ OSL_ENSURE(false, "Illegal configuration path. Terminating '/' found.");
+#endif
+ --pEnd;
+ }
+
+ while (pEnd != pBegin)
+ {
+ // check for predicate
+ sal_Unicode const * pQuoteStart = implFindPredicateStart(pBegin, pEnd);
+ if (pQuoteStart == NULL)
+ throw InvalidName(_aPathString, "is not a valid path. Invalid name or predicate syntax");
+
+ sal_Unicode const * pNameStart = implFindNameStart(pBegin, pQuoteStart);
+
+ rtl::OUString aElementName(pNameStart, pQuoteStart-pNameStart);
+
+ if (!isSimpleName(aElementName))
+ {
+ // this is OK only for few cases WITH predicate
+ if (pQuoteStart == pEnd)
+ throw InvalidName(_aPathString, "is not a valid path. Invalid name");
+
+ if (isEmptyString(aElementName))
+ aElementName = makeWildcardType();
+
+ else if ( !isWildcardType(aElementName))
+ throw InvalidName(_aPathString, "is not a valid path. Invalid type tag for predicate");
+ }
+ if (pQuoteStart != pEnd)
+ {
+ dprint (stderr, "add 'normalize predicate'", "");
+ rtl::OUString aPred = implNormalizePredicate(pQuoteStart,pEnd);
+ aElementName += aPred;
+ dprint (stderr, " [result pred '%s']",
+ rtl::OUStringToOString(aPred, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ aResult.prepend( Path::Component(aElementName) );
+
+ pEnd = pNameStart;
+ if (pNameStart != pBegin) --pEnd;
+ }
+ dprint (stderr, "\n", "");
+ return aResult;
+ }
+//-----------------------------------------------------------------------------
+
+ /// build a composite path component from a base name (type) and a (somewhat optional) predicate
+ rtl::OUString implMakeCompositeName(rtl::OUString const& _sBaseName, rtl::OUString const& _sPredicate) SAL_THROW((InvalidName))
+ {
+ rtl::OUString sComposite(_sBaseName);
+
+ if (isEmptyString(_sBaseName))
+ sComposite = makeWildcardType();
+
+ else if (!isWildcardType(_sBaseName) && !isSimpleName(_sBaseName))
+ throw InvalidName(_sBaseName, "The base-name (type) part of a composite node name must be a simple word");
+
+ dprint (stderr, "implMakeNormalizePred '%s' ",
+ rtl::OUStringToOString(_sPredicate, RTL_TEXTENCODING_UTF8).getStr());
+
+ sal_Unicode const * pPredStart = _sPredicate.getStr();
+ sal_Unicode const * pPredEnd = pPredStart + _sPredicate.getLength();
+
+ if (pPredStart != pPredEnd)
+ sComposite += implMakeNormalizedPredicate(pPredStart, pPredEnd, NULL);
+
+ dprint (stderr, " [result pred '%s']\n",
+ rtl::OUStringToOString(sComposite, RTL_TEXTENCODING_UTF8).getStr());
+
+ return sComposite;
+ }
+//-----------------------------------------------------------------------------
+
+ /// split a composite path component into a base name (type) and a predicate (if present)
+ void implSplitCompositeName(rtl::OUString const& _aCompositeName, rtl::OUString& _rBaseName, rtl::OUString& _rPredicate) SAL_THROW(())
+ {
+ sal_Int32 nPos = _aCompositeName.indexOf(c_lBracket);
+
+ if (nPos >= 0)
+ {
+ OSL_ENSURE( nPos > 0, "Invalid name: Only predicate, no base type");
+
+ _rBaseName = _aCompositeName.copy(0,nPos);
+
+ sal_Unicode const * pBeginPred = _aCompositeName.getStr() + nPos;
+ sal_Unicode const * pEndPred = _aCompositeName.getStr() + _aCompositeName.getLength();
+
+ OSL_ASSERT(pBeginPred[0] == c_lBracket);
+ OSL_ENSURE(pBeginPred[1] == c_normal_quot, "Missing or unexpected quote mark");
+ OSL_ENSURE(pEndPred[-1] == c_rBracket, "Invalid name: Predicate brackets not closed");
+ OSL_ENSURE(pEndPred[-2] == c_normal_quot, "Missing or unexpected quote mark");
+
+ // skip brackets and quotes - then read data
+ _rPredicate = implReadPredicate(pBeginPred+2, pEndPred-2);
+ }
+ else
+ {
+ OSL_ENSURE( _aCompositeName.indexOf(c_rBracket) < 0, "Invalid name: Predicate brackets not opened");
+ _rBaseName = _aCompositeName;
+ _rPredicate = rtl::OUString();
+ }
+ }
+//-----------------------------------------------------------------------------
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class RelativePath
+//-----------------------------------------------------------------------------
+
+// Currently unused method to check/ensure validity
+void RelativePath::init() SAL_THROW(())
+{
+}
+//-----------------------------------------------------------------------------
+
+RelativePath RelativePath::parse(rtl::OUString const& aString)
+{
+ return RelativePath( implParsePath(aString, eRELATIVE) );
+}
+//-----------------------------------------------------------------------------
+
+RelativePath::RelativePath(Path::Component const& aName) SAL_THROW(())
+: m_aRep(aName)
+{
+ if (aName.isEmpty()) m_aRep.clearComponents();
+}
+//-----------------------------------------------------------------------------
+
+RelativePath RelativePath::compose(RelativePath const& aPath) const SAL_THROW(())
+{
+ Path::Rep aResult = aPath.rep();
+ aResult.prepend( this->m_aRep );
+ return RelativePath( aResult );
+}
+//-----------------------------------------------------------------------------
+rtl::OUString RelativePath::toString() const SAL_THROW(())
+{
+ return m_aRep.toString(false);
+}
+
+//-----------------------------------------------------------------------------
+// class AbsolutePath
+//-----------------------------------------------------------------------------
+
+// Currently unused method to check/ensure validity
+void AbsolutePath::init() SAL_THROW(())
+{
+}
+//-----------------------------------------------------------------------------
+
+AbsolutePath AbsolutePath::parse(rtl::OUString const& aString)
+{
+ return AbsolutePath( implParsePath(aString, eABSOLUTE) );
+}
+//-----------------------------------------------------------------------------
+
+AbsolutePath AbsolutePath::root() SAL_THROW(())
+{
+ return AbsolutePath( Path::Rep() );
+}
+//-----------------------------------------------------------------------------
+
+AbsolutePath AbsolutePath::detachedRoot() SAL_THROW(())
+{
+ Path::Rep aRep( Path::makeEmptyComponent() ); // use 1 empty component here, to start detached names
+ return AbsolutePath( aRep );
+}
+//-----------------------------------------------------------------------------
+
+static inline Path::Component implMakeSafeModuleName(rtl::OUString const& _sModuleName) SAL_THROW(())
+{
+ OSL_ENSURE( isSimpleName(_sModuleName), "A module name must be a simple name");
+
+ // if (isSimpleName(_sModuleName)) sModuleName = escape_name( _sModuleName );
+
+ return Path::Component(_sModuleName);
+}
+//-----------------------------------------------------------------------------
+
+AbsolutePath AbsolutePath::makeModulePath(rtl::OUString const& _sModuleName) SAL_THROW(())
+{
+ return AbsolutePath( Path::Rep( implMakeSafeModuleName(_sModuleName) ) );
+}
+//-----------------------------------------------------------------------------
+
+AbsolutePath AbsolutePath::compose(RelativePath const& aPath) const SAL_THROW(())
+{
+ Path::Rep aResult = aPath.rep();
+ aResult.prepend( this->m_aRep );
+ return AbsolutePath( aResult );
+}
+//-----------------------------------------------------------------------------
+
+AbsolutePath AbsolutePath::getParentPath() const
+{
+ // or: m_aRep.check_not_empty();
+ OSL_ENSURE(!isRoot(), "ERROR: Requesting the parent of a root path");
+ if (isRoot()) return *this;
+
+ OSL_ENSURE(!isDetached(), "ERROR: Requesting the parent of a detached path");
+
+ return AbsolutePath( Path::Rep(begin(),end()-1) );
+}
+#if OSL_DEBUG_LEVEL > 0
+//-----------------------------------------------------------------------------
+
+bool AbsolutePath::isDetached() const SAL_THROW(())
+{
+ return !m_aRep.isEmpty() && begin()->isEmpty();
+}
+#endif
+//-----------------------------------------------------------------------------
+
+rtl::OUString AbsolutePath::toString() const SAL_THROW(())
+{
+ return m_aRep.toString(true);
+}
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/configset.cxx b/configmgr/source/treemgr/configset.cxx
new file mode 100644
index 000000000000..3869fb58eb5a
--- /dev/null
+++ b/configmgr/source/treemgr/configset.cxx
@@ -0,0 +1,577 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: configset.cxx,v $
+ * $Revision: 1.32 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h> // needed for Solaris 8
+#include "configset.hxx"
+#include "nodechange.hxx"
+#include "nodechangeimpl.hxx"
+#include "tree.hxx"
+#include "treefragment.hxx"
+#include "template.hxx"
+#include "templateimpl.hxx"
+#include "configgroup.hxx"
+#include "valuenode.hxx"
+#include "valuenodeimpl.hxx"
+#include "setnodeimpl.hxx"
+#include <vos/refernce.hxx>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+// class SetElementFactory
+//-----------------------------------------------------------------------------
+
+SetElementFactory::SetElementFactory(TemplateProvider const& aProvider)
+: m_aProvider(aProvider)
+{
+ OSL_ENSURE(aProvider.m_aImpl.is(), "WARNING: Template Instance Factory created without template provider - cannot instantiate elements");
+}
+//-----------------------------------------------------------------------------
+
+SetElementFactory::SetElementFactory(SetElementFactory const& aOther)
+: m_aProvider(aOther.m_aProvider)
+{
+}
+//-----------------------------------------------------------------------------
+
+SetElementFactory& SetElementFactory::operator=(SetElementFactory const& aOther)
+{
+ m_aProvider = aOther.m_aProvider;
+ return *this;
+}
+//-----------------------------------------------------------------------------
+
+SetElementFactory::~SetElementFactory()
+{
+}
+
+//-----------------------------------------------------------------------------
+rtl::Reference< ElementTree > SetElementFactory::instantiateTemplate(rtl::Reference<Template> const& aTemplate)
+{
+ OSL_ENSURE(m_aProvider.m_aImpl.is(), "ERROR: Template Instance Factory has no template provider - cannot instantiate element");
+ OSL_ENSURE(aTemplate.is(), "ERROR: Template is NULL - cannot instantiate element");
+
+ rtl::Reference< data::TreeSegment > aInstanceTree( m_aProvider.m_aImpl->instantiate(aTemplate) );
+ OSL_ENSURE(aInstanceTree.is(), "ERROR: Cannot create Element Instance: Provider could not instantiate template");
+
+ //set removable state
+ aInstanceTree->fragment->header.state |= data::State::flag_removable;
+
+ return new ElementTree( aInstanceTree, aTemplate, m_aProvider );
+}
+//-----------------------------------------------------------------------------
+rtl::Reference< ElementTree > SetElementFactory::instantiateOnDefault(rtl::Reference< data::TreeSegment > const& _aElementData, rtl::Reference<Template> const& aDummyTemplate)
+{
+// OSL_ENSURE(m_aProvider.m_aImpl(), "ERROR: Template Instance Factory has no template provider - cannot instantiate element");
+ OSL_ENSURE(_aElementData.is(), "ERROR: Tree is NULL - cannot instantiate element");
+ OSL_ENSURE(aDummyTemplate.is(), "ERROR: Template is NULL - cannot instantiate element");
+
+ return new ElementTree( _aElementData, aDummyTemplate, m_aProvider );
+}
+//-----------------------------------------------------------------------------
+
+TemplateProvider SetElementFactory::findTemplateProvider(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ OSL_ENSURE(!isEmpty(aTree.get()), "ERROR: Getting Element Factory requires a valid tree");
+ OSL_ENSURE(aNode.isValid(), "ERROR: Getting Element Factory requires a valid node");
+ OSL_ENSURE(aTree->isValidNode(aNode.getOffset()), "ERROR: Tree/Node mismatch");
+ if (aNode.isValid() )
+ {
+ view::ViewTreeAccess aView(aTree.get());
+
+ OSL_ENSURE (aView.isSetNode(aNode), "WARNING: Getting Element Factory requires a SET node");
+ if (aView.isSetNode(aNode))
+ return aView.getTemplateProvider(aView.toSetNode(aNode));
+ }
+ return TemplateProvider();
+}
+
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class TreeSetUpdater and ValueSetUpdater
+//-----------------------------------------------------------------------------
+
+static node::Attributes getNewElementAttributes(bool bInserting)
+{
+ node::Attributes aResult;
+ aResult.setState( node::isReplaced );
+ //Check if you are inserting new dynamic property
+ if(bInserting)
+ {
+ aResult.markRemovable();
+ }
+ return aResult;
+}
+
+// Value Element Factory methods
+//-----------------------------------------------------------------------------
+
+rtl::Reference<ElementTree> ValueSetUpdater::makeValueElement(rtl::OUString const& aName, com::sun::star::uno::Any const& aValue, bool bInserting)
+{
+
+ const node::Attributes aNewValueAttributes = getNewElementAttributes(bInserting); // TODO: get real value
+
+ com::sun::star::uno::Type aType = m_aTemplate->getInstanceType();
+
+ rtl::OUString aTypeName = m_aTemplate->getName();
+
+ std::auto_ptr<INode> pNode;
+ if (aValue.hasValue())
+ pNode.reset( new ValueNode(aTypeName, aValue, aNewValueAttributes) );
+ else
+ pNode.reset( new ValueNode(aTypeName, aType, aNewValueAttributes) );
+
+ rtl::Reference< data::TreeSegment > aValueTree = data::TreeSegment::create(aName, pNode);
+
+ return new ElementTree(aValueTree, m_aTemplate, TemplateProvider() );
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference<ElementTree> ValueSetUpdater::makeValueElement(rtl::OUString const& aName, rtl::Reference< Tree > const& , com::sun::star::uno::Any const& aValue, bool bInserting)
+{
+ // for now ignoring the node.
+ // TODO: merge attributes etc. from that node's value
+ return makeValueElement(aName, aValue,bInserting);
+}
+//-----------------------------------------------------------------------------
+
+
+TreeSetUpdater::TreeSetUpdater(rtl::Reference< Tree > const& aParentTree, NodeRef const& aSetNode, rtl::Reference< Template > const& aTemplate)
+: m_aParentTree(aParentTree)
+, m_aSetNode(aSetNode)
+, m_aTemplate(aTemplate)
+{
+ implValidateSet();
+}
+//-----------------------------------------------------------------------------
+
+ValueSetUpdater::ValueSetUpdater(rtl::Reference< Tree > const& aParentTree, NodeRef const& aSetNode,
+ rtl::Reference< Template > const& aTemplate, com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> const& xConverter)
+: m_aParentTree(aParentTree)
+, m_aSetNode(aSetNode)
+, m_aTemplate(aTemplate)
+, m_xTypeConverter(xConverter)
+{
+ implValidateSet();
+}
+//-----------------------------------------------------------------------------
+
+SetDefaulter::SetDefaulter(rtl::Reference< Tree > const& aParentTree, NodeRef const& aSetNode,
+ DefaultProvider const& aDefaultProvider)
+: m_aParentTree(aParentTree)
+, m_aSetNode(aSetNode)
+, m_aDefaultProvider(aDefaultProvider)
+{
+ implValidateSet();
+}
+//-----------------------------------------------------------------------------
+
+/// validates that a actual set and an updater's construction parameters match
+static void doValidateSet(rtl::Reference< Tree > const& aParentTree, NodeRef const& aSetNode)
+{
+ if (isEmpty(aParentTree.get()))
+ throw Exception("INTERNAL ERROR: Set Update: Unexpected NULL tree");
+
+ if (!aSetNode.isValid())
+ throw Exception("INTERNAL ERROR: Set Update: Unexpected NULL node");
+
+ if (!aParentTree->isValidNode(aSetNode.getOffset()))
+ throw Exception("INTERNAL ERROR: Set Update: node does not match tree");
+
+ if (! view::ViewTreeAccess(aParentTree.get()).isSetNode(aSetNode))
+ throw Exception("INTERNAL ERROR: Set Update: node is not a set");
+
+ if (aParentTree->getAttributes(aSetNode).isReadonly())
+ throw ConstraintViolation( "Set Update: Set is read-only !" );
+}
+//-----------------------------------------------------------------------------
+
+/// validates that the actual set and the construction parameters match
+void TreeSetUpdater::implValidateSet()
+{
+ doValidateSet(m_aParentTree,m_aSetNode);
+
+ if (!m_aTemplate.is())
+ throw Exception("INTERNAL ERROR: No template available for tree set update");
+
+ if (m_aTemplate->isInstanceValue())
+ throw Exception("INTERNAL ERROR: Tree set update invoked on a value-set");
+
+ view::ViewTreeAccess aParentView(m_aParentTree.get());
+
+ if ( aParentView.getElementTemplate(aParentView.toSetNode(m_aSetNode)) != m_aTemplate)
+ throw Exception("INTERNAL ERROR: Set Update: template mismatch");
+}
+//-----------------------------------------------------------------------------
+
+/// validates that the actual set and the construction parameters match
+void ValueSetUpdater::implValidateSet()
+{
+ doValidateSet(m_aParentTree,m_aSetNode);
+
+ com::sun::star::uno::Type aThisType = m_aTemplate->getInstanceType();
+
+ switch ( aThisType.getTypeClass())
+ {
+ case uno::TypeClass_VOID: throw Exception("INTERNAL ERROR: Value set element type is void");
+ case uno::TypeClass_INTERFACE: throw Exception("INTERNAL ERROR: Value update invoked on a complex set");
+
+ case uno::TypeClass_STRUCT:
+ case uno::TypeClass_EXCEPTION: throw Exception("INTERNAL ERROR: Unexpected/Invalid type for set elements");
+
+ default: break;
+ }
+
+ view::ViewTreeAccess aParentView(m_aParentTree.get());
+
+ if ( aParentView.getElementTemplate(aParentView.toSetNode(m_aSetNode))->getInstanceType() != aThisType)
+ throw Exception("INTERNAL ERROR: Set Update: element type mismatch");
+}
+//-----------------------------------------------------------------------------
+
+/// validates that the actual set and the construction parameters match
+void SetDefaulter::implValidateSet()
+{
+ doValidateSet(m_aParentTree,m_aSetNode);
+
+ if (!m_aDefaultProvider.isValid())
+ throw Exception("INTERNAL ERROR: No default provider available for restoring set default state");
+}
+//-----------------------------------------------------------------------------
+
+static void doValidateElement(rtl::Reference< ElementTree > const& aElement, bool bReqRemovable)
+{
+ if (!aElement.is())
+ throw Exception("INTERNAL ERROR: Set Update: Unexpected NULL element");
+
+ if ( bReqRemovable)
+ {
+ rtl::Reference< Tree > aElementTree = aElement.get();
+
+ if(!aElementTree->getAttributes(aElementTree->getRootNode()).isRemovable())
+ throw ConstraintViolation( "New Set Update: Existing element cannot be removed (or replaced) !" );
+ }
+}
+//-----------------------------------------------------------------------------
+
+/// validates that the given element is valid in this context and returns its name
+Path::Component TreeSetUpdater::implValidateElement(rtl::Reference< ElementTree > const& aElement, bool bReqRemovable)
+{
+ doValidateElement(aElement,bReqRemovable);
+ return aElement->getExtendedRootName();
+}
+//-----------------------------------------------------------------------------
+
+/// validates that the given element is valid and can be replaced in this context and returns its name
+Path::Component ValueSetUpdater::implValidateElement(rtl::Reference< ElementTree > const& aElement, bool mReqRemovable)
+{
+ doValidateElement(aElement,mReqRemovable);
+
+#if OSL_DEBUG_LEVEL > 0
+ com::sun::star::uno::Type aNodeType = ElementHelper::getUnoType(aElement);
+
+ OSL_ENSURE(aNodeType.getTypeClass() != uno::TypeClass_VOID, "INTERNAL ERROR: Set Element without associated type found");
+ OSL_ENSURE(aNodeType.getTypeClass() != uno::TypeClass_INTERFACE,"INTERNAL ERROR: Set Element with complex type found");
+
+ OSL_ENSURE(aNodeType == m_aTemplate->getInstanceType() ||
+ uno::TypeClass_ANY == m_aTemplate->getInstanceType().getTypeClass(),
+ "INTERNAL ERROR: Set Update: existing element does not match template type");
+#endif
+
+ return aElement->getExtendedRootName();
+}
+//-----------------------------------------------------------------------------
+static void checkEligibleChild(rtl::Reference< ElementTree > const& aElementTree, rtl::Reference< Tree > const& aParentTree)
+{
+ ElementTree const * const pElement = aElementTree.get(); OSL_ASSERT(pElement);
+
+ if (pElement->getContextTree() != NULL)
+ throw ConstraintViolation( "Set Update: cannot insert an element that already has a parent." );
+
+ Tree const* pAncestor = aParentTree.get();
+ while (pAncestor != NULL)
+ {
+ if (pElement == pAncestor)
+ throw ConstraintViolation( "Set Update: Circular insertion - trying to insert an element into self or descendant" );
+
+ pAncestor = pAncestor->getContextTree();
+ OSL_ENSURE(pAncestor != aParentTree.get(), "ERROR: Circular tree found");
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void TreeSetUpdater::implValidateTree(rtl::Reference< ElementTree > const& aElementTree)
+{
+ if (!aElementTree.is())
+ throw ConstraintViolation( "Set Update: cannot replace element of complex set with NULL node. Remove the element instead !" );
+
+ checkEligibleChild(aElementTree,m_aParentTree);
+
+ if (! aElementTree->isTemplateInstance())
+ {
+ throw TypeMismatch(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<Unnamed> (Template missing)")),
+ m_aTemplate->getName(), " - new element without template in Set Update");
+ }
+
+ if (!aElementTree->isInstanceOf(m_aTemplate))
+ {
+ throw TypeMismatch( aElementTree->getTemplate()->getPathString(),
+ m_aTemplate->getPathString(), " - new element without template in Set Update");
+ }
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any ValueSetUpdater::implValidateValue(com::sun::star::uno::Any const& aValue)
+{
+ com::sun::star::uno::Type const aThisType = m_aTemplate->getInstanceType();
+
+ OSL_ENSURE( aThisType.getTypeClass() == uno::TypeClass_ANY || isPossibleValueType(aThisType),
+ "Invalid element type for value set" );
+
+ com::sun::star::uno::Any aRet;
+ if (aValue.hasValue())
+ {
+ com::sun::star::uno::Type const aValType = aValue.getValueType();
+
+ if (aValType.getTypeClass() == uno::TypeClass_INTERFACE)
+ throw TypeMismatch(aValType.getTypeName(), aThisType.getTypeName(), " - cannot replace value by complex tree in Set update");
+
+ if (aValType == aThisType)
+ {
+ aRet = aValue;
+ }
+
+ else if ( uno::TypeClass_ANY == aThisType.getTypeClass() )
+ {
+ if ( ! isPossibleValueType(aValType) )
+ throw TypeMismatch(aValType.getTypeName(), aThisType.getTypeName(), " - new element has no legal configuration data type");
+
+ aRet = aValue;
+ }
+
+ else
+ {
+ if (!convertCompatibleValue(m_xTypeConverter, aRet, aValue, aThisType))
+ throw TypeMismatch(aValType.getTypeName(), aThisType.getTypeName(), " - new element does not match template type in SetUpdate");
+ }
+
+ OSL_ASSERT( isPossibleValueType(aRet.getValueType()) );
+ }
+ else
+ {
+ // cannot do anything about null values here
+ OSL_ASSERT(aValue.getValueTypeClass() == uno::TypeClass_VOID);
+
+ }
+ return aRet;
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any ValueSetUpdater::implValidateValue(rtl::Reference< Tree > const& aElementTree, com::sun::star::uno::Any const& aValue)
+{
+ node::Attributes aAttributes = aElementTree->getAttributes(aElementTree->getRootNode());
+ // Here we assume writable == removable/replaceable
+ if (aAttributes.isReadonly())
+ throw ConstraintViolation( "Set Update: Existing element is read-only !" );
+
+ // Here we assume nullable != removable
+ if (!aValue.hasValue())
+ {
+ if (!aAttributes.isNullable())
+ throw ConstraintViolation( "Set Update: Value is not nullable !" );
+ }
+ return implValidateValue( aValue);
+}
+//-----------------------------------------------------------------------------
+
+NodeChange TreeSetUpdater::validateInsertElement (rtl::OUString const& aName, rtl::Reference< ElementTree > const& aNewElement)
+{
+ view::ViewTreeAccess aParentView(m_aParentTree.get());
+
+ SetEntry anEntry = aParentView.findElement(aParentView.toSetNode(m_aSetNode),aName);
+ if (anEntry.isValid())
+ throw Exception("INTERNAL ERROR: Set Update: Element to be inserted already exists");
+
+ implValidateTree(aNewElement);
+
+ std::auto_ptr<SetElementChangeImpl> pChange( new SetInsertImpl(aNewElement->makeExtendedName(aName), aNewElement) );
+
+ pChange->setTarget(aParentView.makeNode(m_aSetNode));
+
+ return NodeChange(pChange.release());
+}
+//-----------------------------------------------------------------------------
+
+NodeChange ValueSetUpdater::validateInsertElement (rtl::OUString const& aName, com::sun::star::uno::Any const& aNewValue)
+{
+ view::ViewTreeAccess aParentView(m_aParentTree.get());
+
+ SetEntry anEntry = aParentView.findElement(aParentView.toSetNode(m_aSetNode),aName);
+ if (anEntry.isValid())
+ throw Exception("INTERNAL ERROR: Set Update: Element to be inserted already exists");
+
+ com::sun::star::uno::Any aValidValue = implValidateValue(aNewValue);
+
+ rtl::Reference<ElementTree> aNewElement = makeValueElement(aName, aValidValue,true);
+
+ std::auto_ptr<SetElementChangeImpl> pChange( new SetInsertImpl(aNewElement->makeExtendedName(aName), aNewElement) );
+
+ pChange->setTarget(aParentView.makeNode(m_aSetNode));
+
+ return NodeChange(pChange.release());
+}
+//-----------------------------------------------------------------------------
+
+NodeChange TreeSetUpdater::validateReplaceElement(rtl::Reference< ElementTree > const& aElement, rtl::Reference< ElementTree > const& aNewElement)
+{
+ Path::Component aName = implValidateElement(aElement,true);
+
+ implValidateTree(aNewElement);
+
+ std::auto_ptr<SetElementChangeImpl> pChange( new SetReplaceImpl(aName, aNewElement) );
+
+ pChange->setTarget(view::ViewTreeAccess(m_aParentTree.get()).makeNode(m_aSetNode));
+
+ return NodeChange(pChange.release());
+}
+//-----------------------------------------------------------------------------
+
+NodeChange ValueSetUpdater::validateReplaceElement(rtl::Reference< ElementTree > const& aElement, com::sun::star::uno::Any const& aNewValue)
+{
+ Path::Component aName = implValidateElement(aElement,false);
+
+ rtl::Reference< Tree > aElementNode = extractElementNode(aElement);
+
+ com::sun::star::uno::Any aValidValue = implValidateValue(aElementNode, aNewValue);
+
+ rtl::Reference< Tree > aElementTree = aElement.get();
+
+ rtl::Reference<ElementTree> aNewElement;
+ if(aElementTree->getAttributes(aElementTree->getRootNode()).isRemovable())
+ {
+ aNewElement = makeValueElement(aName.getName(), aElementNode, aValidValue,true);
+ }
+ else
+ {
+ aNewElement = makeValueElement(aName.getName(), aElementNode, aValidValue,false);
+ }
+
+ std::auto_ptr<SetElementChangeImpl> pChange( new SetReplaceImpl(aName, aNewElement) );
+
+ pChange->setTarget(view::ViewTreeAccess(m_aParentTree.get()).makeNode(m_aSetNode));
+
+ return NodeChange(pChange.release());
+}
+//-----------------------------------------------------------------------------
+
+NodeChange TreeSetUpdater::validateRemoveElement (rtl::Reference< ElementTree > const& aElement)
+{
+ Path::Component aName = implValidateElement(aElement,true);
+
+ std::auto_ptr<SetElementChangeImpl> pChange( new SetRemoveImpl(aName) );
+
+ pChange->setTarget(view::ViewTreeAccess(m_aParentTree.get()).makeNode(m_aSetNode));
+
+ return NodeChange(pChange.release());
+}
+
+//-----------------------------------------------------------------------------
+
+NodeChange ValueSetUpdater::validateRemoveElement (rtl::Reference< ElementTree > const& aElement)
+{
+ Path::Component aName = implValidateElement(aElement,true);
+
+ std::auto_ptr<SetElementChangeImpl> pChange( new SetRemoveImpl(aName) );
+
+ pChange->setTarget(view::ViewTreeAccess(m_aParentTree.get()).makeNode(m_aSetNode));
+
+ return NodeChange(pChange.release());
+}
+
+//-----------------------------------------------------------------------------
+
+NodeChange SetDefaulter::validateSetToDefaultState()
+{
+ std::auto_ptr< ISubtree > aDefault = m_aDefaultProvider.getDefaultTree(m_aParentTree,m_aSetNode);
+
+ // now build the specific change
+ std::auto_ptr<SetChangeImpl> pChange;
+
+ if (aDefault.get())
+ {
+ TemplateProvider aProvider = SetElementFactory::findTemplateProvider(m_aParentTree,m_aSetNode);
+
+ configmgr::configuration::SetElementFactory aTmp(aProvider);
+ pChange.reset( new SetResetImpl(aTmp, aDefault) );
+ pChange->setTarget(view::ViewTreeAccess(m_aParentTree.get()).makeNode(m_aSetNode));
+ }
+ return NodeChange(pChange.release());
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< Tree > ValueSetUpdater::extractElementNode (rtl::Reference< ElementTree > const& aElement)
+{
+ return aElement.get();
+}
+//-----------------------------------------------------------------------------
+
+#if OSL_DEBUG_LEVEL > 0
+com::sun::star::uno::Type ElementHelper::getUnoType(rtl::Reference< ElementTree > const& aElement)
+{
+ OSL_PRECOND( aElement.is(), "ERROR: Configuration: ElementTree operation requires valid node" );
+
+ rtl::Reference< Tree > aElementTree(aElement.get());
+
+ NodeRef aNode = aElementTree->getRootNode();
+ OSL_ASSERT( aNode.isValid() );
+
+ view::ViewTreeAccess aElementView(aElementTree.get());
+
+ if ( aElementView.isValueNode(aNode) )
+ {
+ return aElementView.getValueType(aElementView.toValueNode(aNode));
+ }
+ else
+ {
+ uno::Reference< uno::XInterface > const * const selectInterface=0;
+ return ::getCppuType(selectInterface);
+ }
+}
+#endif
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/defaultproviderproxy.cxx b/configmgr/source/treemgr/defaultproviderproxy.cxx
new file mode 100644
index 000000000000..75d82d8ff585
--- /dev/null
+++ b/configmgr/source/treemgr/defaultproviderproxy.cxx
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: defaultproviderproxy.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "defaultproviderproxy.hxx"
+#include "defaultprovider.hxx"
+#include "treemanager.hxx"
+#include "valuenode.hxx"
+#include "options.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+DefaultProviderProxy::DefaultProviderProxy(
+ rtl::Reference< TreeManager > const & _xDefaultTreeProvider,
+ IDefaultableTreeManager * _pDefaultTreeManager,
+ AbsolutePath const& _aBaseLocation,
+ RequestOptions const& _aOptions
+ )
+: m_aBaseLocation(_aBaseLocation)
+, m_aOptions(_aOptions)
+, m_xDefaultTreeProvider(_xDefaultTreeProvider)
+, m_pDefaultTreeManager(_pDefaultTreeManager)
+{
+}
+//-----------------------------------------------------------------------------
+
+DefaultProviderProxy::~DefaultProviderProxy()
+{
+}
+//-----------------------------------------------------------------------------
+
+/// tries to load a default instance of the specified node (which must be within the request range owned)
+std::auto_ptr<ISubtree> DefaultProviderProxy::getDefaultTree(
+ AbsolutePath const& _aLocation
+ ) const SAL_THROW((com::sun::star::uno::Exception))
+{
+ OSL_ENSURE( Path::hasPrefix(_aLocation,m_aBaseLocation),
+ "ERROR: DefaultProviderProxy called for out-of-scope location" );
+
+ std::auto_ptr<ISubtree> aRet;
+
+ if (m_xDefaultTreeProvider.is())
+ aRet = m_xDefaultTreeProvider->requestDefaultData(_aLocation, m_aOptions);
+
+ return aRet;
+}
+
+//-----------------------------------------------------------------------------
+/// tries to load default data into the specified tree
+bool DefaultProviderProxy::fetchDefaultData() SAL_THROW((com::sun::star::uno::Exception))
+{
+ OSL_PRECOND(m_pDefaultTreeManager, "No tree to fetch defaults into");
+ if (!m_pDefaultTreeManager) return false;
+
+ return !! m_pDefaultTreeManager->fetchDefaultData(m_aBaseLocation,m_aOptions);
+}
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/defaultproviderproxy.hxx b/configmgr/source/treemgr/defaultproviderproxy.hxx
new file mode 100644
index 000000000000..4bb43da11c8a
--- /dev/null
+++ b/configmgr/source/treemgr/defaultproviderproxy.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: defaultproviderproxy.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_DEFAULTPROVIDER_PROXY_HXX_
+#define CONFIGMGR_DEFAULTPROVIDER_PROXY_HXX_
+
+#include "configpath.hxx"
+#include "utility.hxx"
+#include "requestoptions.hxx"
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ class ISubtree;
+ class IDefaultableTreeManager;
+ class OOptions;
+ class TreeManager;
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+ /// provides access to the defaults for a given request
+ class DefaultProviderProxy
+ : public salhelper::SimpleReferenceObject
+ {
+ // the data defining a request
+ AbsolutePath m_aBaseLocation;
+ RequestOptions m_aOptions;
+
+ // the object(s) that provide the defaults
+ rtl::Reference< TreeManager > m_xDefaultTreeProvider;
+ IDefaultableTreeManager * m_pDefaultTreeManager;
+ public:
+ explicit
+ DefaultProviderProxy(
+ rtl::Reference< TreeManager > const & _xDefaultTreeProvider,
+ IDefaultableTreeManager * _pDefaultTreeManager,
+ AbsolutePath const& _aBaseLocation,
+ RequestOptions const& _aOptions
+ );
+
+ ~DefaultProviderProxy();
+
+ /// tries to load a default instance of the specified node (which must be within the request range owned)
+ std::auto_ptr<ISubtree> getDefaultTree(AbsolutePath const& _aLocation) const SAL_THROW((com::sun::star::uno::Exception));
+
+ /// tries to load default data into the owned tree - call only outside of any locks
+ bool fetchDefaultData() SAL_THROW((com::sun::star::uno::Exception));
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_DEFAULTPROVIDER_PROXY_HXX_
diff --git a/configmgr/source/treemgr/deferredview.cxx b/configmgr/source/treemgr/deferredview.cxx
new file mode 100644
index 000000000000..84ce4db3bbe0
--- /dev/null
+++ b/configmgr/source/treemgr/deferredview.cxx
@@ -0,0 +1,446 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: deferredview.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "deferredview.hxx"
+#include "viewfactory.hxx"
+#include "nodeimplobj.hxx"
+
+namespace configmgr
+{
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+static inline configuration::DeferredGroupNodeImpl* deferredGroupNode(Node const& _aNode)
+{
+ return static_cast<configuration::DeferredGroupNodeImpl*>(_aNode.get_impl());
+}
+//-----------------------------------------------------------------------------
+
+static inline configuration::DeferredGroupNodeImpl* deferredGroupNode(GroupNode const& _aNode)
+{
+ return static_cast<configuration::DeferredGroupNodeImpl*>(_aNode.get_impl());
+}
+//-----------------------------------------------------------------------------
+
+static inline configuration::DeferredSetNodeImpl* deferredSetNode(Node const& _aNode)
+{
+ return static_cast<configuration::DeferredSetNodeImpl*>(_aNode.get_impl());
+}
+//-----------------------------------------------------------------------------
+
+static inline configuration::DeferredSetNodeImpl* deferredSetNode(SetNode const& _aNode)
+{
+ return static_cast<configuration::DeferredSetNodeImpl*>(_aNode.get_impl());
+}
+//-----------------------------------------------------------------------------
+
+static inline void deferredValueNode(Node const& _aNode)
+{
+ { (void)_aNode; }
+ OSL_ENSURE( _aNode.isValueNode(),"Unknown Node type in deferred view");
+ OSL_ENSURE(_aNode.get_offset() == configuration::Tree::ROOT, "Tree: Unexpected node type - non-root value element");
+}
+//-----------------------------------------------------------------------------
+
+static void deferredValueNodeChanged(Node const& _aNode)
+{
+ { (void)_aNode; }
+ OSL_ENSURE( _aNode.isValueNode(),"Unknown Node type in deferred view");
+ OSL_ENSURE(_aNode.get_offset() == configuration::Tree::ROOT, "Tree: Unexpected node type - non-root value element");
+ OSL_ENSURE(!_aNode.isValueNode(),"Value node changes not supported in deferred view");
+ throw configuration::Exception("Internal Error: Invalid operation applied to element");
+}
+//-----------------------------------------------------------------------------
+
+bool DeferredViewStrategy::doHasChanges(Node const& _aNode) const
+{
+ if (_aNode.isGroupNode())
+ return deferredGroupNode(_aNode)->hasChanges();
+
+ else if (_aNode.isSetNode())
+ return deferredSetNode(_aNode)->hasChanges();
+
+ else
+ deferredValueNode(_aNode);
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+void DeferredViewStrategy::doMarkChanged(Node const& _aNode)
+{
+ if (_aNode.isGroupNode())
+ deferredGroupNode(_aNode)->markChanged();
+
+ else if (_aNode.isSetNode())
+ deferredSetNode(_aNode)->markChanged();
+
+ else
+ deferredValueNodeChanged(_aNode);
+}
+
+//-----------------------------------------------------------------------------
+void DeferredViewStrategy::doCollectChanges(Node const& _aNode, configuration::NodeChanges& _rChanges) const
+{
+ implCollectChangesIn(_aNode,_rChanges);
+}
+
+//-----------------------------------------------------------------------------
+void DeferredViewStrategy::implCollectChangesIn(Node const& _aNode, configuration::NodeChanges& _rChanges) const
+{
+ if ( hasChanges(_aNode) )
+ {
+ if (_aNode.isSetNode())
+ {
+ deferredSetNode(_aNode)->collectElementChanges( _rChanges);
+ }
+ else if (_aNode.isGroupNode())
+ {
+ GroupNode aGroup(_aNode);
+
+ deferredGroupNode(aGroup)->collectValueChanges( _rChanges, _aNode.tree(), _aNode.get_offset());
+
+ for( Node aChild = aGroup.getFirstChild();
+ aChild.is();
+ aChild = aGroup.getNextChild(aChild)
+ )
+ {
+ this->implCollectChangesIn( aChild, _rChanges );
+ }
+ }
+ else
+ OSL_ASSERT(!"Unreachable code");
+ }
+}
+
+//-----------------------------------------------------------------------------
+std::auto_ptr<SubtreeChange> DeferredViewStrategy::doPreCommitChanges(configuration::Tree * tree, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements)
+{
+ std::auto_ptr<SubtreeChange> pRet;
+ if (hasChanges(tree))
+ {
+ pRet = implPreCommitChanges(getRootNode(tree),_rRemovedElements);
+ if (pRet.get() != NULL)
+ {
+ pRet->setNodeName(getSimpleRootName(tree));
+ }
+ }
+ return pRet;
+}
+
+//-----------------------------------------------------------------------------
+void DeferredViewStrategy::doFailedCommit(configuration::Tree * tree, SubtreeChange& rChanges)
+{
+ implFailedCommit(getRootNode(tree),rChanges);
+}
+
+//-----------------------------------------------------------------------------
+void DeferredViewStrategy::doFinishCommit(configuration::Tree * tree, SubtreeChange& rChanges)
+{
+ implFinishCommit(getRootNode(tree),rChanges);
+}
+
+//-----------------------------------------------------------------------------
+void DeferredViewStrategy::doRevertCommit(configuration::Tree * tree, SubtreeChange& rChanges)
+{
+ implRevertCommit(getRootNode(tree),rChanges);
+}
+
+//-----------------------------------------------------------------------------
+configuration::ValueChangeImpl* DeferredViewStrategy::doAdjustToValueChange(GroupNode const& _aGroupNode, rtl::OUString const& _aName, ValueChange const& rExternalChange)
+{
+ rtl::Reference<configuration::ValueMemberNode::DeferredImpl> aChange = deferredGroupNode(_aGroupNode)->findValueChange(_aName);
+
+ if (aChange.is())
+ {
+ if (configuration::ValueChangeImpl* pValueChange = aChange->adjustToChange(rExternalChange))
+ {
+ OSL_ENSURE(aChange->isChange(), "Got an adjusted change from a non-changing value");
+
+ return pValueChange;
+ }
+ else // a non-change
+ {
+ OSL_ENSURE(!aChange->isChange(), "Got no adjusted change from a changing value") ;
+ OSL_ENSURE(false, "Got a non-change from a (deferred) group") ;
+ // then do as without deferred change
+ }
+ }
+
+ return ViewStrategy::doAdjustToValueChange(_aGroupNode, _aName, rExternalChange);
+
+}
+
+//-----------------------------------------------------------------------------
+node::Attributes DeferredViewStrategy::doAdjustAttributes(node::Attributes const& _aAttributes) const
+{
+ return _aAttributes;
+}
+
+//-----------------------------------------------------------------------------
+configuration::ValueMemberNode DeferredViewStrategy::doGetValueMember(GroupNode const& _aNode, rtl::OUString const& _aName, bool _bForUpdate) const
+{
+ return deferredGroupNode(_aNode)->makeValueMember(_aName,_bForUpdate);
+}
+
+//-----------------------------------------------------------------------------
+void DeferredViewStrategy::doInsertElement(SetNode const& _aNode, rtl::OUString const& aName, configuration::SetEntry const& _aNewEntry)
+{
+ // move to this memory segment
+ // should be direct (as any free-floating one)
+
+ //implMakeElement(aNewEntry)
+ configuration::ElementTreeData aNewElement = implMakeElement(_aNode, _aNewEntry );
+
+ deferredSetNode(_aNode)->insertNewElement(aName, aNewElement);
+}
+
+//-----------------------------------------------------------------------------
+void DeferredViewStrategy::doRemoveElement(SetNode const& _aNode, rtl::OUString const& aName)
+{
+ deferredSetNode(_aNode)->removeOldElement(aName);
+}
+
+//-----------------------------------------------------------------------------
+extern NodeFactory& getDeferredChangeFactory();
+
+NodeFactory& DeferredViewStrategy::doGetNodeFactory()
+{
+ return getDeferredChangeFactory();
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+rtl::Reference<ViewStrategy> createDeferredChangeStrategy()
+{
+ return new DeferredViewStrategy();
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<SubtreeChange> DeferredViewStrategy::implPreCommitChanges(Node const& _aNode, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements)
+{
+ std::auto_ptr<SubtreeChange> aRet;
+
+ OSL_ASSERT (this->hasChanges( _aNode) );
+
+ if (_aNode.isSetNode())
+ {
+ aRet = deferredSetNode(_aNode)->preCommitChanges(_rRemovedElements);
+ }
+ else if (_aNode.isGroupNode())
+ {
+ std::auto_ptr<SubtreeChange> aGroupChange(deferredGroupNode(_aNode)->preCommitValueChanges());
+
+ OSL_ASSERT(aGroupChange.get());
+ if (aGroupChange.get())
+ implPreCommitSubChanges( GroupNode(_aNode), _rRemovedElements, *aGroupChange);
+
+ aRet = aGroupChange;
+ }
+ else
+ deferredValueNode(_aNode);
+
+ return aRet;
+}
+//-----------------------------------------------------------------------------
+
+void DeferredViewStrategy::implFinishCommit(Node const& _aNode, SubtreeChange& rSubtreeChange)
+{
+ OSL_PRECOND( getSimpleNodeName(_aNode) == rSubtreeChange.getNodeName(), "ERROR: Change name does not match node");
+
+ if (_aNode.isSetNode())
+ {
+ OSL_ENSURE(rSubtreeChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
+
+ deferredSetNode(_aNode)->finishCommit(rSubtreeChange);
+ }
+ else if (_aNode.isGroupNode())
+ {
+ OSL_ENSURE(!rSubtreeChange.isSetNodeChange(),"ERROR: Change type SET does not match group");
+
+ deferredGroupNode(_aNode)->finishCommit(rSubtreeChange);
+ implFinishSubCommitted( GroupNode(_aNode), rSubtreeChange );
+ }
+ else
+ {
+ deferredValueNode(_aNode);
+ OSL_ENSURE(false, "Tree: Cannot finish commit: Unexpected node type");
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredViewStrategy::implRevertCommit(Node const& _aNode, SubtreeChange& rSubtreeChange)
+{
+ OSL_PRECOND( getSimpleNodeName(_aNode) == rSubtreeChange.getNodeName(), "ERROR: Change name does not match node");
+
+ if (_aNode.isSetNode())
+ {
+ OSL_ENSURE(rSubtreeChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
+
+ deferredSetNode(_aNode)->revertCommit(rSubtreeChange);
+ }
+ else if (_aNode.isGroupNode())
+ {
+ OSL_ENSURE(!rSubtreeChange.isSetNodeChange(),"ERROR: Change type SET does not match group");
+
+ deferredGroupNode(_aNode)->revertCommit(rSubtreeChange);
+ implRevertSubCommitted( GroupNode(_aNode), rSubtreeChange );
+ }
+ else
+ {
+ deferredValueNode(_aNode);
+ OSL_ENSURE(false, "Tree: Cannot revert commit: Unexpected node type");
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredViewStrategy::implFailedCommit(Node const& _aNode, SubtreeChange& rSubtreeChange)
+{
+ OSL_PRECOND( getSimpleNodeName(_aNode) == rSubtreeChange.getNodeName(), "ERROR: Change name does not match node");
+
+ if (_aNode.isSetNode())
+ {
+ OSL_ENSURE(rSubtreeChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
+
+ deferredSetNode(_aNode)->failedCommit(rSubtreeChange);
+ }
+ else if (_aNode.isGroupNode())
+ {
+ OSL_ENSURE(!rSubtreeChange.isSetNodeChange(),"ERROR: Change type SET does not match group");
+
+ deferredGroupNode(_aNode)->failedCommit(rSubtreeChange);
+ implFailedSubCommitted( GroupNode(_aNode), rSubtreeChange );
+ }
+ else
+ {
+ deferredValueNode(_aNode);
+ OSL_ENSURE(false, "Tree: Cannot handle commit failure: Unexpected node type");
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredViewStrategy::implPreCommitSubChanges(GroupNode const & _aGroup, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements, SubtreeChange& _rParentChange)
+{
+ for( Node aChild = _aGroup.getFirstChild(); aChild.is(); aChild = _aGroup.getNextChild(aChild) )
+ {
+ if (this->hasChanges(aChild))
+ {
+ std::auto_ptr<SubtreeChange> aSubChanges( this->implPreCommitChanges(aChild,_rRemovedElements) );
+ std::auto_ptr<Change> aSubChangesBase( aSubChanges.release() );
+ _rParentChange.addChange( aSubChangesBase );
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredViewStrategy::implFinishSubCommitted(GroupNode const & _aGroup, SubtreeChange& aChangesParent)
+{
+ for(SubtreeChange::MutatingChildIterator
+ it = aChangesParent.begin_changes(),
+ stop = aChangesParent.end_changes();
+ it != stop;
+ ++it)
+ {
+ if (dynamic_cast< SubtreeChange * >(&*it) != 0)
+ {
+ Node aChild = _aGroup.findChild( it->getNodeName() );
+ OSL_ENSURE( aChild.is(), "Changed sub-node not found in tree");
+
+ this->implFinishCommit(aChild, static_cast<SubtreeChange&>(*it));
+ }
+ else
+ {
+ OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) != 0, "Unexpected change type for inner node; change is ignored");
+ OSL_ENSURE(! _aGroup.findChild(it->getNodeName()).is() ,
+ "Found sub(tree) node where a value was changed");
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredViewStrategy::implRevertSubCommitted(GroupNode const & _aGroup, SubtreeChange& aChangesParent)
+{
+ for(SubtreeChange::MutatingChildIterator
+ it = aChangesParent.begin_changes(),
+ stop = aChangesParent.end_changes();
+ it != stop;
+ ++it)
+ {
+ if (dynamic_cast< SubtreeChange * >(&*it) != 0)
+ {
+ Node aChild = _aGroup.findChild( it->getNodeName() );
+ OSL_ENSURE( aChild.is(), "Changed sub-node not found in tree");
+
+ this->implRevertCommit(aChild, static_cast<SubtreeChange&>(*it));
+ }
+ else
+ {
+ OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) != 0, "Unexpected change type for inner node; change is ignored");
+ OSL_ENSURE(! _aGroup.findChild(it->getNodeName()).is() ,
+ "Found sub(tree) node where a value was changed");
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredViewStrategy::implFailedSubCommitted(GroupNode const & _aGroup, SubtreeChange& aChangesParent)
+{
+ for(SubtreeChange::MutatingChildIterator
+ it = aChangesParent.begin_changes(),
+ stop = aChangesParent.end_changes();
+ it != stop;
+ ++it)
+ {
+ if (dynamic_cast< SubtreeChange * >(&*it) != 0)
+ {
+ Node aChild = _aGroup.findChild( it->getNodeName() );
+ OSL_ENSURE( aChild.is(), "Changed sub-node not found in tree");
+
+ this->implFailedCommit(aChild, static_cast<SubtreeChange&>(*it));
+ }
+ else
+ {
+ OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) != 0, "Unexpected change type for inner node; change is ignored");
+ OSL_ENSURE(! _aGroup.findChild(it->getNodeName()).is() ,
+ "Found sub(tree) node where a value was changed");
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/treemgr/deferredview.hxx b/configmgr/source/treemgr/deferredview.hxx
new file mode 100644
index 000000000000..2d3c268d012f
--- /dev/null
+++ b/configmgr/source/treemgr/deferredview.hxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: deferredview.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_DEFERREDVIEW_HXX_
+#define CONFIGMGR_DEFERREDVIEW_HXX_
+
+#include "viewstrategy.hxx"
+
+
+namespace configmgr
+{
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+// View behavior for direct data access
+//-----------------------------------------------------------------------------
+
+ class DeferredViewStrategy : public ViewStrategy
+ {
+ public:
+ explicit
+ DeferredViewStrategy() {}
+
+ // ViewStrategy implementation
+ private:
+ // change handling -required
+ virtual bool doHasChanges(Node const& _aNode) const;
+ virtual void doMarkChanged(Node const& _aNode);
+
+
+ // change handling
+ virtual void doCollectChanges(Node const& _aNode, configuration::NodeChanges& rChanges) const;
+
+ // commit protocol
+ virtual std::auto_ptr<SubtreeChange> doPreCommitChanges(configuration::Tree * tree, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements);
+ virtual void doFailedCommit(configuration::Tree * tree, SubtreeChange& rChanges);
+ virtual void doFinishCommit(configuration::Tree * tree, SubtreeChange& rChanges);
+ virtual void doRevertCommit(configuration::Tree * tree, SubtreeChange& rChanges);
+
+ // notification protocol
+ virtual configuration::ValueChangeImpl* doAdjustToValueChange(GroupNode const& _aGroupNode, rtl::OUString const& aName, ValueChange const& rExternalChange);
+ // virtual void doAdjustToElementChanges(configuration::NodeChangesInformation& rLocalChanges, SetNode const& _aNode, SubtreeChange const& rExternalChanges, TreeDepth nDepth);
+
+ // common attributes
+ virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const;
+
+ // group member access
+ virtual configuration::ValueMemberNode doGetValueMember(GroupNode const& _aNode, rtl::OUString const& _aName, bool _bForUpdate) const;
+
+ // set element access
+ virtual void doInsertElement(SetNode const& _aNode, rtl::OUString const& aName, configuration::SetEntry const& aNewEntry);
+ virtual void doRemoveElement(SetNode const& _aNode, rtl::OUString const& aName);
+
+ virtual NodeFactory& doGetNodeFactory();
+ private:
+ void implCollectChangesIn(Node const& _aNode, configuration::NodeChanges& rChanges) const;
+ // commit protocol
+ std::auto_ptr<SubtreeChange> implPreCommitChanges(Node const& _aNode, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements);
+ void implFailedCommit(Node const& _aNode, SubtreeChange& rChanges);
+ void implFinishCommit(Node const& _aNode, SubtreeChange& rChanges);
+ void implRevertCommit(Node const& _aNode, SubtreeChange& rChanges);
+
+ void implPreCommitSubChanges(GroupNode const & _aGroup, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements, SubtreeChange& _rParentChange);
+ void implFailedSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);
+ void implFinishSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);
+ void implRevertSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges);
+
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_DEFERREDVIEW_HXX_
diff --git a/configmgr/source/treemgr/directview.cxx b/configmgr/source/treemgr/directview.cxx
new file mode 100644
index 000000000000..498ea66aca5d
--- /dev/null
+++ b/configmgr/source/treemgr/directview.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: directview.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "directview.hxx"
+#include "viewfactory.hxx"
+#include "setnodeimpl.hxx"
+
+namespace configmgr
+{
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+
+void DirectViewStrategy::implMarkNondefault(SetNode const& _aSetNode)
+{
+ sharable::SetNode * set = _aSetNode.getAccess();
+
+ OSL_ASSERT(set != 0);
+
+ sharable::SetNode* pNode = NULL;
+ if (m_aTreeSegment.is())
+ pNode = set;
+
+ OSL_ASSERT(pNode);
+
+ pNode->info.markAsDefault(false);
+}
+//-----------------------------------------------------------------------------
+
+bool DirectViewStrategy::doHasChanges(Node const& ) const
+{
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+void DirectViewStrategy::doMarkChanged(Node const& )
+{
+ // do nothing
+}
+//-----------------------------------------------------------------------------
+
+node::Attributes DirectViewStrategy::doAdjustAttributes(node::Attributes const& _aAttributes) const
+{
+ node::Attributes aAttributes = _aAttributes;
+
+ if (aAttributes.isReadonly())
+ aAttributes.setAccess(node::accessFinal);
+
+ return aAttributes;
+}
+//-----------------------------------------------------------------------------
+
+configuration::ValueMemberNode DirectViewStrategy::doGetValueMember(GroupNode const& _aNode, rtl::OUString const& _aName, bool _bForUpdate) const
+{
+ return ViewStrategy::doGetValueMember(_aNode,_aName,_bForUpdate);
+}
+//-----------------------------------------------------------------------------
+void DirectViewStrategy::doInsertElement(SetNode const& _aNode, rtl::OUString const& _aName, configuration::SetEntry const& _aNewEntry)
+{
+ // move to this memory segment
+ // should already be direct (as any free-floating one)
+
+ //implMakeElement(aNewEntry)
+ configuration::ElementTreeData aNewElement = implMakeElement(_aNode, _aNewEntry );
+ // _aNewEntry.tree()->rebuild(this, _aNode.accessor());
+
+ _aNode.get_impl()->insertElement(_aName, aNewElement);
+
+ aNewElement->attachTo( _aNode.getAccess(), _aName );
+
+ implMarkNondefault( _aNode );
+}
+//-----------------------------------------------------------------------------
+
+void DirectViewStrategy::doRemoveElement(SetNode const& _aNode, rtl::OUString const& _aName)
+{
+ configuration::ElementTreeData aOldElement = _aNode.get_impl()->removeElement(_aName);
+
+ aOldElement->detachFrom( _aNode.getAccess(), _aName);
+
+ implMarkNondefault( _aNode );
+}
+//-----------------------------------------------------------------------------
+
+extern NodeFactory& getDirectAccessFactory();
+
+NodeFactory& DirectViewStrategy::doGetNodeFactory()
+{
+ return getDirectAccessFactory();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference<ViewStrategy> createDirectAccessStrategy(rtl::Reference< data::TreeSegment > const & _aTreeSegment)
+{
+ return new DirectViewStrategy(_aTreeSegment);
+}
+
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/treemgr/directview.hxx b/configmgr/source/treemgr/directview.hxx
new file mode 100644
index 000000000000..8a047ecbdb7b
--- /dev/null
+++ b/configmgr/source/treemgr/directview.hxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: directview.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_DIRECTVIEW_HXX_
+#define CONFIGMGR_DIRECTVIEW_HXX_
+
+#include "viewstrategy.hxx"
+#include "treesegment.hxx"
+
+namespace configmgr
+{
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+// View behavior for direct data access
+//-----------------------------------------------------------------------------
+
+ class DirectViewStrategy : public ViewStrategy
+ {
+ rtl::Reference< data::TreeSegment > m_aTreeSegment;
+ public:
+ explicit
+ DirectViewStrategy(rtl::Reference< data::TreeSegment > const & _aTreeSegment)
+ : m_aTreeSegment(_aTreeSegment)
+ {}
+
+ protected:
+ // change handling -required
+ virtual bool doHasChanges(Node const& _aNode) const;
+ virtual void doMarkChanged(Node const& _aNode);
+
+ // common attributes
+ virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const;
+
+ // group member access
+ virtual configuration::ValueMemberNode doGetValueMember(GroupNode const& _aNode, rtl::OUString const& _aName, bool _bForUpdate) const;
+
+ // set element access
+ virtual void doInsertElement(SetNode const& _aNode, rtl::OUString const& aName, configuration::SetEntry const& aNewEntry);
+ virtual void doRemoveElement(SetNode const& _aNode, rtl::OUString const& aName);
+
+ virtual NodeFactory& doGetNodeFactory();
+
+ private:
+ void implMarkNondefault(SetNode const& _aNode);
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_DIRECTVIEW_HXX_
diff --git a/configmgr/source/treemgr/groupnodeimpl.hxx b/configmgr/source/treemgr/groupnodeimpl.hxx
new file mode 100644
index 000000000000..da7003c69939
--- /dev/null
+++ b/configmgr/source/treemgr/groupnodeimpl.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: groupnodeimpl.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_GROUPNODEBEHAVIOR_HXX_
+#define CONFIGMGR_GROUPNODEBEHAVIOR_HXX_
+
+#include "nodeimpl.hxx"
+#include "valuemembernode.hxx"
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ class SubtreeChange;
+ class ValueChange;
+
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ class ValueChangeImpl;
+//-----------------------------------------------------------------------------
+// a visitor
+//-----------------------------------------------------------------------------
+ struct GroupMemberVisitor
+ {
+ enum Result { DONE, CONTINUE };
+ virtual Result visit(ValueMemberNode const& aValue) = 0;
+ protected:
+ virtual ~GroupMemberVisitor() {}
+ };
+
+
+// Specific type of nodes
+//-----------------------------------------------------------------------------
+
+ class GroupNodeImpl : public NodeImpl
+ {
+ mutable sharable::Node *m_pCache;
+ public:
+ explicit GroupNodeImpl(sharable::GroupNode * _pNodeRef);
+
+ sharable::GroupNode * getDataAccess() const;
+
+ bool areValueDefaultsAvailable() const;
+
+ sharable::ValueNode * getOriginalValueNode(rtl::OUString const& aName) const;
+
+ ValueMemberNode makeValueMember(sharable::ValueNode * node);
+ };
+
+//-----------------------------------------------------------------------------
+
+ // domain-specific 'dynamic_cast' replacements
+ GroupNodeImpl& AsGroupNode(NodeImpl& rNode);
+
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_GROUPNODEBEHAVIOR_HXX_
diff --git a/configmgr/source/treemgr/makefile.mk b/configmgr/source/treemgr/makefile.mk
new file mode 100644
index 000000000000..ba98a6a161ef
--- /dev/null
+++ b/configmgr/source/treemgr/makefile.mk
@@ -0,0 +1,78 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.10 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source$/inc
+PRJNAME=configmgr
+TARGET=treemgr
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/collectchanges.obj \
+ $(SLO)$/configdefaultprovider.obj \
+ $(SLO)$/configexcept.obj \
+ $(SLO)$/configgroup.obj \
+ $(SLO)$/configpath.obj \
+ $(SLO)$/configset.obj \
+ $(SLO)$/defaultproviderproxy.obj \
+ $(SLO)$/valuemembernode.obj \
+ $(SLO)$/nodechange.obj \
+ $(SLO)$/nodechangeimpl.obj \
+ $(SLO)$/nodechangeinfo.obj \
+ $(SLO)$/nodefactory.obj \
+ $(SLO)$/nodeimpl.obj \
+ $(SLO)$/nodeimplobj.obj \
+ $(SLO)$/noderef.obj \
+ $(SLO)$/roottree.obj \
+ $(SLO)$/setnodeimpl.obj \
+ $(SLO)$/template.obj \
+ $(SLO)$/templateimpl.obj \
+ $(SLO)$/treeimpl.obj \
+ $(SLO)$/viewaccess.obj \
+ $(SLO)$/viewstrategy.obj \
+ $(SLO)$/viewnode.obj \
+ $(SLO)$/deferredview.obj \
+ $(SLO)$/directview.obj \
+ $(SLO)$/readonlyview.obj \
+
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/treemgr/nodechange.cxx b/configmgr/source/treemgr/nodechange.cxx
new file mode 100644
index 000000000000..9c581f19368d
--- /dev/null
+++ b/configmgr/source/treemgr/nodechange.cxx
@@ -0,0 +1,276 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodechange.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "nodechange.hxx"
+#include "nodechangeimpl.hxx"
+#include "nodechangeinfo.hxx"
+
+#include "noderef.hxx"
+#include "tree.hxx"
+
+#include <algorithm>
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+
+//-----------------------------------------------------------------------------
+// NodeChange handle class
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+inline void NodeChange::init()
+{
+ if (m_pImpl) m_pImpl->acquire();
+}
+inline void NodeChange::deinit()
+{
+ if (m_pImpl) m_pImpl->release();
+}
+
+//-----------------------------------------------------------------------------
+NodeChange::NodeChange()
+: m_pImpl(0)
+{
+}
+//-----------------------------------------------------------------------------
+
+NodeChange::NodeChange(NodeChangeImpl* pImpl)
+: m_pImpl(pImpl)
+{
+ init();
+}
+//-----------------------------------------------------------------------------
+
+NodeChange::NodeChange(NodeChange const& rOther)
+: m_pImpl(rOther.m_pImpl)
+{
+ init();
+}
+//-----------------------------------------------------------------------------
+
+NodeChange& NodeChange::operator=(NodeChange const& rOther)
+{
+ NodeChange(rOther).swap(*this);
+ return *this;
+}
+//-----------------------------------------------------------------------------
+
+void NodeChange::swap(NodeChange& rOther)
+{
+ std::swap(m_pImpl,rOther.m_pImpl);
+}
+//-----------------------------------------------------------------------------
+
+NodeChange::~NodeChange()
+{
+ deinit();
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChange::maybeChange() const
+{
+ return m_pImpl && m_pImpl->isChange(true);
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChange::isChange() const
+{
+ return m_pImpl && m_pImpl->isChange(false);
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt32 NodeChange::getChangeInfos(NodeChangesInformation& _rInfos) const
+{
+ sal_uInt32 nCount = 0;
+ if (m_pImpl)
+ {
+ sal_uInt32 nChanges = m_pImpl->getChangeDataCount();
+
+ for (sal_uInt32 ix = 0; ix < nChanges; ++ix)
+ {
+ NodeChangeInformation aSingleInfo;
+ aSingleInfo.change.type = NodeChangeData::eNoChange;
+
+ m_pImpl->fillChangeInfo(aSingleInfo,ix);
+
+ if ( !aSingleInfo.isEmptyChange() )
+ {
+ _rInfos.push_back(aSingleInfo);
+ ++nCount;
+ }
+ }
+ }
+
+ return nCount;
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChange::getChangeLocation(NodeChangeLocation& rLoc) const
+{
+ return m_pImpl && m_pImpl->fillChangeLocation(rLoc);
+}
+
+//-----------------------------------------------------------------------------
+
+// retrieve the tree where the change is actually taking place
+rtl::Reference< Tree > NodeChange::getAffectedTree() const
+{
+ if (this->maybeChange())
+ return m_pImpl->getTargetTree().get();
+ else
+ return NULL;
+}
+//-----------------------------------------------------------------------------
+
+// retrieve the tree where the change is actually taking place
+NodeRef NodeChange::getAffectedNode() const
+{
+ if (this->maybeChange())
+ {
+ rtl::Reference<Tree> aTree = m_pImpl->getTargetTree();
+ unsigned int nOffset = m_pImpl->getTargetNode();
+
+ OSL_ASSERT(aTree.is() && aTree->isValidNode(nOffset));
+
+ if (aTree.is() && nOffset)
+ return aTree->getNode(nOffset);
+ }
+ return NodeRef();
+}
+//-----------------------------------------------------------------------------
+
+NodeChange& NodeChange::test()
+{
+ if (m_pImpl) m_pImpl->test();
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+NodeChange const& NodeChange::test() const
+{
+ if (m_pImpl) m_pImpl->test();
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+NodeChange& NodeChange::apply()
+{
+ if (m_pImpl) m_pImpl->apply();
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+NodeChange const& NodeChange::apply() const
+{
+ if (m_pImpl) m_pImpl->apply();
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+// NodeChanges collection
+//-----------------------------------------------------------------------------
+
+NodeChanges::NodeChanges()
+: m_aChanges()
+{
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChanges::isEmpty() const
+{
+ return m_aChanges.empty();
+}
+//-----------------------------------------------------------------------------
+
+/// predicate for compact
+
+static bool isEmptyChange(NodeChange const& aChange)
+{
+ return !aChange.maybeChange();
+}
+//-----------------------------------------------------------------------------
+
+
+NodeChanges& NodeChanges::compact()
+{
+ m_aChanges.erase( std::remove_if(begin(),end(),isEmptyChange), end() );
+ return *this;
+}
+//-----------------------------------------------------------------------------
+
+void NodeChanges::implTest() const
+{
+ for(std::vector<NodeChange>::const_iterator it = begin(), stop = end(); it != stop; ++it)
+ {
+ it ->test();
+ }
+}
+//-----------------------------------------------------------------------------
+/** insert a change into this collection
+*/
+void NodeChanges::add(NodeChange const& aChange)
+{
+ m_aChanges.push_back(aChange);
+}
+
+//-----------------------------------------------------------------------------
+
+/** removes a change to <var>aNode</var> from this collection (if there is one)
+void NodeChanges::reset(Node const& aNode)
+{
+}
+*/
+
+sal_uInt32 NodeChanges::getChangesInfos(NodeChangesInformation& _rInfos) const
+{
+ if (isEmpty()) return 0;
+
+ _rInfos.reserve(_rInfos.size() + this->getCount());
+
+ sal_Int32 nResult = 0;
+ for (std::vector<NodeChange>::const_iterator it = begin(); it != end(); ++it)
+ {
+ nResult += it->getChangeInfos(_rInfos);
+ }
+
+ return nResult;
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+ }
+}
+
diff --git a/configmgr/source/treemgr/nodechangeimpl.cxx b/configmgr/source/treemgr/nodechangeimpl.cxx
new file mode 100644
index 000000000000..cb61a495958c
--- /dev/null
+++ b/configmgr/source/treemgr/nodechangeimpl.cxx
@@ -0,0 +1,788 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodechangeimpl.cxx,v $
+ * $Revision: 1.22 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "nodechangeimpl.hxx"
+#include "nodechangeinfo.hxx"
+#include "nodeimpl.hxx"
+#include "tree.hxx"
+#include "configset.hxx"
+#include "setnodeimpl.hxx"
+#include "groupnodeimpl.hxx"
+#include "valuenode.hxx"
+#include "change.hxx"
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// All Changes:NodeChangeImpl - common base
+//-----------------------------------------------------------------------------
+
+// life cycle states for a NodeChangeImpl
+enum { eTestedChange = 0x01, eAppliedChange = 0x02, eNoCheck = 0x07 };
+//-----------------------------------------------------------------------------
+
+NodeChangeImpl::NodeChangeImpl(bool bNoCheck)
+: m_aAffectedTree()
+, m_nAffectedNode(0)
+, m_nState(0)
+{
+ if (bNoCheck) m_nState = eNoCheck;
+}
+//-----------------------------------------------------------------------------
+
+view::ViewTreeAccess NodeChangeImpl::getTargetView()
+{
+ OSL_ENSURE( m_aAffectedTree.is(), "ERROR: Configuration Change: Target Tree Access has not been set up" );
+
+ return view::ViewTreeAccess(m_aAffectedTree.get());
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference<Tree> NodeChangeImpl::getTargetTree() const
+{
+ rtl::Reference<Tree> aRet = m_aAffectedTree;
+ OSL_ENSURE( aRet.is(), "ERROR: Configuration Change: Target Tree has not been set up" );
+
+ return aRet;
+}
+//-----------------------------------------------------------------------------
+
+unsigned int NodeChangeImpl::getTargetNode() const
+{
+ unsigned int nRet = m_nAffectedNode;
+ OSL_ENSURE( nRet != 0, "ERROR: Configuration Change: Target Node has not been set up" );
+ OSL_ENSURE( m_aAffectedTree.is() && m_aAffectedTree->isValidNode(nRet),
+ "ERROR: Configuration Change: Changing Node does not match tree" );
+
+ return nRet;
+}
+//-----------------------------------------------------------------------------
+
+void NodeChangeImpl::setTarget(view::Node _aAffectedNode)
+{
+ this->setTarget(_aAffectedNode.tree(), _aAffectedNode.get_offset());
+
+}
+void NodeChangeImpl::setTarget(rtl::Reference<Tree> const& _aAffectedTree, unsigned int _nAffectedNode)
+{
+ OSL_ENSURE(m_nState == 0 || (!m_aAffectedTree.is() && m_nState == eNoCheck), "WARNING: Configuration: Retargeting change that already was tested or applied");
+
+ OSL_ENSURE( _aAffectedTree.is(), "ERROR: Configuration Change: NULL Target Tree is not allowed" );
+ OSL_ENSURE( _nAffectedNode, "ERROR: Configuration Change: NULL Target Node is not allowed" );
+ OSL_ENSURE( _aAffectedTree->isValidNode(_nAffectedNode), "ERROR: Configuration Change: Target Node does not match Tree" );
+
+ if (m_nState != eNoCheck) m_nState = 0; // previous checks are invalidated
+
+ m_aAffectedTree = _aAffectedTree;
+ m_nAffectedNode = _nAffectedNode;
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChangeImpl::isChange(bool bAllowUntested) const
+{
+ OSL_ENSURE(bAllowUntested || (m_nState & eTestedChange), "WARNING: Configuration: Change was not tested - isChange is meaningless");
+
+ if (m_nState == eNoCheck)
+ return true;
+
+ if (!(m_nState & eTestedChange))
+ return bAllowUntested;
+
+ return doIsChange();
+}
+//-----------------------------------------------------------------------------
+
+sal_uInt32 NodeChangeImpl::getChangeDataCount() const
+{
+ OSL_PRECOND(m_nState & eTestedChange, "WARNING: Configuration: Change was not tested - change data count may be incorrect");
+
+ return doGetChangeCount();
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChangeImpl::fillChangeData(NodeChangeData& rChange, sal_uInt32 _ix) const
+{
+ OSL_PRECOND(_ix < doGetChangeCount(), "ERROR: Configuration: Change index out of range");
+ OSL_PRECOND(m_nState & eTestedChange, "WARNING: Configuration: Change was not tested - fillChange is partially meaningless");
+
+ return doFillChange(rChange, _ix) || rChange.isDataChange(); // force true if the data is signaling change
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChangeImpl::fillChangeLocation(NodeChangeLocation& rChange, sal_uInt32 _ix) const
+{
+ if (!m_aAffectedTree.is()) return false;
+
+ rChange.setBase( NodeID(this->getTargetTree().get(), this->getTargetNode()) );
+
+ rChange.setAccessor( this->doGetChangingNodePath(_ix) );
+
+ rChange.setAffected( NodeID(this->getTargetTree().get(), this->getTargetNode()) );
+
+ rChange.setChangingSubnode( this->doIsChangingSubnode() );
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChangeImpl::fillChangeInfo(NodeChangeInformation& rChange, sal_uInt32 _ix) const
+{
+ return fillChangeLocation(rChange.location, _ix) & fillChangeData(rChange.change, _ix);
+}
+//-----------------------------------------------------------------------------
+
+void NodeChangeImpl::test()
+{
+ if (!(m_nState & eTestedChange))
+ {
+ doTest(implGetTarget());
+ m_nState |= eTestedChange;
+ }
+}
+//-----------------------------------------------------------------------------
+
+void NodeChangeImpl::apply()
+{
+ if (!(m_nState & eAppliedChange))
+ {
+ implApply();
+
+ OSL_ENSURE(m_nState & eAppliedChange, "ERROR: Configuration: Change could not be applied");
+ OSL_ENSURE(m_nState & eTestedChange, "ERROR: Configuration: Change was not tested while applied");
+ }
+ else
+ OSL_ENSURE(m_nState & eTestedChange, "ERROR: Configuration: Change marked applied but not tested");
+}
+//-----------------------------------------------------------------------------
+
+// default count is 1
+sal_uInt32 NodeChangeImpl::doGetChangeCount() const
+{
+ return 1;
+}
+//-----------------------------------------------------------------------------
+
+/// apply this change to the given node - start state is nState (which is then updated)
+void NodeChangeImpl::implApply()
+{
+ OSL_ASSERT( !(m_nState & eAppliedChange)); // Caller must check
+
+ view::Node aTarget = implGetTarget();
+
+ if (!(m_nState & eTestedChange)) // Test checks the old value if there is realy a change
+ { // for eventlisteners to say "the old value is kept"
+ doTest(aTarget);
+ m_nState |= eTestedChange;
+ }
+
+ doApply(aTarget);
+ m_nState |= eAppliedChange;
+}
+//-----------------------------------------------------------------------------
+
+view::Node NodeChangeImpl::implGetTarget()
+{
+ OSL_ENSURE(m_aAffectedTree.is(), "ERROR: Configuration Change: no target tree set");
+
+ OSL_ENSURE(m_aAffectedTree->isValidNode(m_nAffectedNode), "ERROR: Configuration Change: target node not in target tree");
+
+ view::Node aTarget = getTargetView().makeNode(m_nAffectedNode);
+ OSL_ENSURE(aTarget.is(), "ERROR: Configuration: No target for change");
+ return aTarget;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Value operations: ValueChangeImpl = common base
+//-----------------------------------------------------------------------------
+
+ValueChangeImpl::ValueChangeImpl()
+: m_aNewValue()
+, m_aOldValue()
+{
+}
+//-----------------------------------------------------------------------------
+
+ValueChangeImpl::ValueChangeImpl(com::sun::star::uno::Any const& aNewValue)
+: m_aNewValue(aNewValue)
+, m_aOldValue()
+{
+}
+//-----------------------------------------------------------------------------
+
+ValueChangeImpl::ValueChangeImpl(com::sun::star::uno::Any const& aNewValue, com::sun::star::uno::Any const& aOldValue)
+: NodeChangeImpl(true)
+, m_aNewValue(aNewValue)
+, m_aOldValue(aOldValue)
+{
+}
+//-----------------------------------------------------------------------------
+
+ValueChangeImpl::~ValueChangeImpl()
+{
+}
+//-----------------------------------------------------------------------------
+
+void ValueChangeImpl::setTarget(view::GroupNode const& _aParentNode, rtl::OUString const& sNodeName)
+{
+ OSL_ENSURE(sNodeName.getLength() != 0, "ValueChangeTarget is being set without a name");
+
+ NodeChangeImpl::setTarget(_aParentNode.node());
+ m_aName = sNodeName;
+}
+//-----------------------------------------------------------------------------
+
+void ValueChangeImpl::setTarget(rtl::Reference<Tree> const& aAffectedTree, unsigned int nParentNode, rtl::OUString const& sNodeName)
+{
+ OSL_ENSURE(sNodeName.getLength() != 0, "ValueChangeTarget is being set without a name");
+
+ NodeChangeImpl::setTarget(aAffectedTree,nParentNode);
+ m_aName = sNodeName;
+}
+//-----------------------------------------------------------------------------
+
+RelativePath ValueChangeImpl::doGetChangingNodePath(sal_uInt32 ) const
+{
+ return RelativePath( Path::wrapSimpleName(m_aName) );
+}
+//-----------------------------------------------------------------------------
+
+bool ValueChangeImpl::doIsChangingSubnode() const
+{
+ return m_aName.getLength() != 0;
+}
+//-----------------------------------------------------------------------------
+
+bool ValueChangeImpl::doIsChange() const
+{
+ return !!(getNewValue() != getOldValue());
+}
+//-----------------------------------------------------------------------------
+
+bool ValueChangeImpl::doFillChange(NodeChangeData& rChange, sal_uInt32) const
+{
+ rChange.unoData.newValue = getNewValue();
+ rChange.unoData.oldValue = getOldValue();
+ return rChange.unoData.isDataChange();
+}
+//-----------------------------------------------------------------------------
+
+void ValueChangeImpl::doTest( view::Node const& rTarget)
+{
+ view::ViewTreeAccess aTargetView = getTargetView();
+
+ OSL_ENSURE(rTarget.isGroupNode(), "ERROR: Configuration: Target type mismatch: expected a group node holding the value");
+
+ ValueMemberNode aValueTarget = aTargetView.getValue( view::GroupNode(rTarget), m_aName );
+
+ OSL_ENSURE(aValueTarget.isValid(), "ERROR: Configuration: Target missing: could not find the changing value");
+
+ preCheckValue(aValueTarget, m_aOldValue, m_aNewValue);
+}
+//-----------------------------------------------------------------------------
+
+void ValueChangeImpl::doApply( view::Node const& rTarget)
+{
+ view::ViewTreeAccess aTargetView = getTargetView();
+
+ OSL_ENSURE(rTarget.isGroupNode(), "ERROR: Configuration: Target type mismatch: expected a group node holding the value");
+
+ ValueMemberUpdate aValueTarget = aTargetView.getValueForUpdate( view::GroupNode(rTarget), m_aName );
+
+ OSL_ENSURE(aValueTarget.isValid(), "ERROR: Configuration: Target missing: could not find the changing value");
+
+ doApplyChange(aValueTarget);
+ configmgr::configuration::ValueMemberNode aNode(aValueTarget.getNode());
+ postCheckValue(aNode, m_aNewValue); // Sideeffect: m_aNewValue will be changed
+}
+//-----------------------------------------------------------------------------
+
+void ValueChangeImpl::preCheckValue(ValueMemberNode& rNode, com::sun::star::uno::Any& rOld, com::sun::star::uno::Any& )
+{
+ com::sun::star::uno::Any aPrevValue = rNode.getValue();
+ OSL_ENSURE(!rOld.hasValue() || rOld == aPrevValue, "ERROR: Configuration: Stored old value of target does not match the actual value");
+ rOld = aPrevValue;
+}
+//-----------------------------------------------------------------------------
+
+void ValueChangeImpl::postCheckValue(ValueMemberNode& rNode, com::sun::star::uno::Any& rNew)
+{
+ com::sun::star::uno::Any aResultValue = rNode.getValue();
+ OSL_ENSURE(!rNew.hasValue() || rNew == aResultValue, "ERROR: Configuration: New value of target does not match the predicted result");
+ rNew = aResultValue;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Value operations: ValueReplaceImpl = set local value
+//-----------------------------------------------------------------------------
+
+ValueReplaceImpl::ValueReplaceImpl(com::sun::star::uno::Any const& aNewValue)
+:ValueChangeImpl(aNewValue)
+{
+}
+//-----------------------------------------------------------------------------
+
+ValueReplaceImpl::ValueReplaceImpl(com::sun::star::uno::Any const& aNewValue, com::sun::star::uno::Any const& aOldValue)
+:ValueChangeImpl(aNewValue, aOldValue)
+{
+}
+//-----------------------------------------------------------------------------
+
+void ValueReplaceImpl::doApplyChange( ValueMemberUpdate& rNode)
+{
+ rNode.setValue(getNewValue());
+}
+//-----------------------------------------------------------------------------
+
+bool ValueReplaceImpl::doFillChange( NodeChangeData& rChange, sal_uInt32 _ix) const
+{
+ rChange.type = NodeChangeData::eSetValue;
+ return ValueChangeImpl::doFillChange(rChange, _ix);
+}
+
+//-----------------------------------------------------------------------------
+// Value operations: ValueResetImpl = set to default
+//-----------------------------------------------------------------------------
+
+ValueResetImpl::ValueResetImpl()
+:ValueChangeImpl()
+, m_bTargetIsDefault(false)
+{
+}
+//-----------------------------------------------------------------------------
+
+ValueResetImpl::ValueResetImpl(com::sun::star::uno::Any const& aNewValue, com::sun::star::uno::Any const& aOldValue)
+:ValueChangeImpl(aNewValue, aOldValue)
+, m_bTargetIsDefault(false)
+{
+}
+//-----------------------------------------------------------------------------
+
+void ValueResetImpl::doApplyChange( ValueMemberUpdate& rNode)
+{
+ rNode.setDefault();
+}
+//-----------------------------------------------------------------------------
+
+bool ValueResetImpl::doIsChange() const
+{
+ return !m_bTargetIsDefault;
+}
+//-----------------------------------------------------------------------------
+
+bool ValueResetImpl::doFillChange( NodeChangeData& rChange, sal_uInt32 _ix) const
+{
+ rChange.type = NodeChangeData::eSetDefault;
+ ValueChangeImpl::doFillChange(rChange,_ix);
+ return !m_bTargetIsDefault && !rChange.isEmptyChange(); // do it defensively here - default (= 'new') may be unknown still
+}
+//-----------------------------------------------------------------------------
+
+void ValueResetImpl::preCheckValue(ValueMemberNode& rNode, com::sun::star::uno::Any& rOld, com::sun::star::uno::Any& rNew)
+{
+ ValueChangeImpl::preCheckValue(rNode,rOld,rNew);
+
+ com::sun::star::uno::Any aDefaultValue = rNode.getDefaultValue();
+ OSL_ENSURE(!rNew.hasValue() || rNew == aDefaultValue, "ERROR: Configuration: Stored new value of target does not match the actual default value");
+ rNew = aDefaultValue;
+ m_bTargetIsDefault = rNode.isDefault();
+}
+
+//-----------------------------------------------------------------------------
+// All Set Changes: SetChangeImpl - common base
+//-----------------------------------------------------------------------------
+
+SetChangeImpl::SetChangeImpl(bool bNoCheck)
+: NodeChangeImpl(bNoCheck)
+{
+}
+//-----------------------------------------------------------------------------
+
+bool SetChangeImpl::doIsChangingSubnode() const
+{
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Resetting a set to its default state
+//-----------------------------------------------------------------------------
+
+SetResetImpl::SetResetImpl(
+ SetElementFactory& _rElementFactory,
+ std::auto_ptr<ISubtree> _pDefaultData,
+ bool _bNoCheck
+)
+: SetChangeImpl(_bNoCheck)
+, m_aDefaultData(_pDefaultData)
+, m_rElementFactory(_rElementFactory)
+, m_aTreeChanges()
+{
+}
+//-----------------------------------------------------------------------------
+
+SetResetImpl::~SetResetImpl()
+{
+}
+//-----------------------------------------------------------------------------
+
+RelativePath SetResetImpl::doGetChangingNodePath(sal_uInt32 _ix) const
+{
+ OSL_ENSURE( _ix < m_aTreeChanges.size() || _ix == scCommonBase, "Illegal Change index" );
+ OSL_ASSERT( static_cast<size_t>(scCommonBase) > m_aTreeChanges.size() );
+
+ if ( _ix < m_aTreeChanges.size() )
+ return RelativePath( m_aTreeChanges[_ix].m_aElementName);
+
+ else
+ return RelativePath();
+}
+//-----------------------------------------------------------------------------
+
+static NodeChangeData::Type getChangeType(ElementTreeChange const& aChange)
+{
+ sal_Bool bHasNew = aChange.m_aAddedElement.is();
+ sal_Bool bHasOld = aChange.m_aRemovedElement.is();
+
+ NodeChangeData::Type aResult;
+ if (bHasNew)
+ aResult = bHasOld ? NodeChangeData::eReplaceElement : NodeChangeData::eInsertElement;
+ else
+ aResult = bHasOld ? NodeChangeData::eRemoveElement : NodeChangeData::eSetDefault;
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+bool SetResetImpl::doIsChange() const
+{
+ return !m_aTreeChanges.empty() || m_aDefaultData.get();
+}
+//-----------------------------------------------------------------------------
+
+bool SetResetImpl::doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const
+{
+ OSL_ENSURE( _ix < m_aTreeChanges.size() || _ix == scCommonBase, "Illegal Change index" );
+ if (_ix >= m_aTreeChanges.size())
+ {
+ rChange.type = NodeChangeData::eResetSetDefault;
+ return m_aDefaultData.get() != NULL;
+ }
+ ElementTreeChange const& aChange = m_aTreeChanges[_ix];
+
+ rChange.type = getChangeType(aChange);
+
+ rChange.element.newValue = aChange.m_aAddedElement;
+ rChange.element.oldValue = aChange.m_aRemovedElement;
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+void SetResetImpl::doTest( view::Node const& rTarget)
+{
+ if ( m_aDefaultData.get() )
+ {
+ view::ViewTreeAccess accessor = this->getTargetView();
+
+ view::SetNode aTargetSet(rTarget);
+
+ std::auto_ptr<SubtreeChange> pChanges = accessor.differenceToDefaultState(aTargetSet, *m_aDefaultData);
+
+ if (pChanges.get())
+ {
+ for (SubtreeChange::MutatingChildIterator it = pChanges->begin_changes(),
+ stop = pChanges->end_changes();
+ it != stop;
+ ++it)
+ {
+ rtl::OUString aName(it->getNodeName());
+
+ SetEntry anExistingEntry = accessor.findElement(aTargetSet,aName);
+
+ rtl::Reference<ElementTree> aOldTree = anExistingEntry.tree();
+ rtl::Reference<ElementTree> aNewTree;
+
+ if (AddNode * addNode = dynamic_cast< AddNode * >(&*it))
+ {
+ rtl::Reference< data::TreeSegment > pAddedNode = addNode->getNewTree();
+
+ OSL_ENSURE(pAddedNode.is(), "Processing an addNode to default - no node to add");
+
+ aNewTree = m_rElementFactory.instantiateOnDefault(pAddedNode,accessor.getElementTemplate(aTargetSet)).get();
+ }
+
+
+ Path::Component aFullName =
+ aNewTree.is() ? aNewTree->getExtendedRootName() :
+ aOldTree.is() ? aOldTree->getExtendedRootName() :
+ Path::makeCompositeName(aName,accessor.getElementTemplate(aTargetSet)->getName());
+
+ OSL_ENSURE(aOldTree.is() || aNewTree.is(), "No data for change to default");
+
+ m_aTreeChanges.push_back(ElementTreeChange(aFullName,aNewTree,aOldTree));
+ }
+ }
+
+ m_aDefaultData.reset();
+ }
+}
+//-----------------------------------------------------------------------------
+
+void SetResetImpl::doApply( view::Node const& rTarget)
+{
+ view::ViewTreeAccess accessor = this->getTargetView();
+
+ view::SetNode aTargetSet(rTarget);
+
+ for (std::vector< ElementTreeChange >::iterator it = m_aTreeChanges.begin(); it != m_aTreeChanges.end(); ++it)
+ {
+ rtl::OUString aElementName = it->m_aElementName.getName();
+
+ if (it->m_aRemovedElement.is())
+ accessor.removeElement(aTargetSet, aElementName);
+
+ if (it->m_aAddedElement.is())
+ {
+ SetEntry aNewEntry( it->m_aAddedElement.get() );
+ accessor.insertElement(aTargetSet, aElementName, aNewEntry);
+ }
+
+ OSL_ENSURE(getChangeType(*it) != NodeChangeData::eSetDefault,
+ "Cannot apply change without data");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// All Set Changes affecting a single element: SetElementChangeImpl - common base
+//-----------------------------------------------------------------------------
+
+SetElementChangeImpl::SetElementChangeImpl(Path::Component const& aName, bool bNoCheck)
+: SetChangeImpl(bNoCheck)
+, m_aName(aName)
+{
+}
+//-----------------------------------------------------------------------------
+
+RelativePath SetElementChangeImpl::doGetChangingNodePath(sal_uInt32 ) const
+{
+ return RelativePath(getFullElementName());
+}
+//-----------------------------------------------------------------------------
+
+void SetElementChangeImpl::doTest( view::Node const& rTarget)
+{
+ doTestElement(view::SetNode(rTarget), getElementName() );
+}
+//-----------------------------------------------------------------------------
+
+void SetElementChangeImpl::doApply( view::Node const& rTarget)
+{
+ doApplyToElement(view::SetNode(rTarget), getElementName() );
+}
+
+//-----------------------------------------------------------------------------
+// Full Sets: SetInsertTreeImpl
+//-----------------------------------------------------------------------------
+
+SetInsertImpl::SetInsertImpl(Path::Component const& aName, rtl::Reference<ElementTree> const& aNewTree, bool bNoCheck)
+: SetElementChangeImpl(aName,bNoCheck)
+, m_aNewTree(aNewTree)
+{
+}
+//-----------------------------------------------------------------------------
+
+bool SetInsertImpl::doIsChange() const
+{
+ return !!m_aNewTree.is();
+}
+//-----------------------------------------------------------------------------
+
+bool SetInsertImpl::doFillChange(NodeChangeData& rChange, sal_uInt32) const
+{
+ rChange.type = NodeChangeData::eInsertElement;
+ if (m_aNewTree.is())
+ rChange.element.newValue = m_aNewTree;
+
+ return isChange(true);
+}
+//-----------------------------------------------------------------------------
+
+void SetInsertImpl::doTestElement( view::SetNode const& _aNode, rtl::OUString const& aName)
+{
+ SetEntry anEntry = getTargetView().findElement(_aNode,aName); // require loaded children
+ OSL_ENSURE(!anEntry.isValid(), "ERROR: Configuration: Adding a node that already exists");
+}
+//-----------------------------------------------------------------------------
+
+void SetInsertImpl::doApplyToElement( view::SetNode const& _aNode, rtl::OUString const& aName)
+{
+ if (m_aNewTree.is())
+ {
+ SetEntry aNewEntry( m_aNewTree.get() );
+ getTargetView().insertElement( _aNode, aName, aNewEntry);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Full Sets: SetReplaceTreeImpl
+//-----------------------------------------------------------------------------
+
+SetReplaceImpl::SetReplaceImpl(Path::Component const& aName, rtl::Reference<ElementTree> const& aNewTree)
+: SetElementChangeImpl(aName)
+, m_aNewTree(aNewTree)
+, m_aOldTree()
+{
+}
+//-----------------------------------------------------------------------------
+
+SetReplaceImpl::SetReplaceImpl(Path::Component const& aName, rtl::Reference<ElementTree> const& aNewTree, rtl::Reference<ElementTree> const& aOldTree)
+: SetElementChangeImpl(aName,true)
+, m_aNewTree(aNewTree)
+, m_aOldTree(aOldTree)
+{
+}
+//-----------------------------------------------------------------------------
+
+/// checks, if this represents an actual change
+bool SetReplaceImpl::doIsChange() const
+{
+ return !(m_aOldTree == m_aNewTree);
+}
+//-----------------------------------------------------------------------------
+
+/// fills in pre- and post-change values, returns wether they differ
+bool SetReplaceImpl::doFillChange(NodeChangeData& rChange, sal_uInt32) const
+{
+ rChange.type = NodeChangeData::eReplaceElement;
+ if (m_aNewTree.is())
+ rChange.element.newValue = m_aNewTree;
+
+ if (m_aOldTree.is())
+ rChange.element.oldValue = m_aOldTree;
+
+ return isChange(true);
+}
+//-----------------------------------------------------------------------------
+
+void SetReplaceImpl::doTestElement( view::SetNode const& _aNode, rtl::OUString const& aName)
+{
+ OSL_ASSERT(!m_aOldTree.is()); // already tested ?
+
+ // remove the old node
+ SetEntry anEntry = getTargetView().findElement(_aNode,aName); // require loaded children
+ OSL_ENSURE(anEntry.isValid(), "ERROR: Configuration: Replacing a node that doesn't exist");
+
+ m_aOldTree = anEntry.tree();
+}
+//-----------------------------------------------------------------------------
+
+void SetReplaceImpl::doApplyToElement( view::SetNode const& _aNode, rtl::OUString const& aName)
+{
+ if (m_aOldTree != m_aNewTree)
+ {
+ view::ViewTreeAccess aTargetView = this->getTargetView();
+
+ OSL_ENSURE(m_aOldTree.is(), "ERROR: Configuration: Replacing a node that doesn't exist");
+ aTargetView.removeElement(_aNode, aName);
+
+ // add the new one
+ OSL_ENSURE(m_aNewTree.is(), "ERROR: Configuration: Replacing a node with nothing");
+ if (m_aNewTree.is())
+ {
+ SetEntry aNewEntry( m_aNewTree.get() );
+ aTargetView.insertElement( _aNode, aName, aNewEntry);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Full Sets: SetRemoveTreeImpl
+//-----------------------------------------------------------------------------
+
+SetRemoveImpl::SetRemoveImpl(Path::Component const& aName)
+: SetElementChangeImpl(aName)
+, m_aOldTree()
+{
+}
+//-----------------------------------------------------------------------------
+
+SetRemoveImpl::SetRemoveImpl(Path::Component const& aName, rtl::Reference<ElementTree> const& aOldTree)
+: SetElementChangeImpl(aName,true)
+, m_aOldTree(aOldTree)
+{
+}
+//-----------------------------------------------------------------------------
+
+/// checks, if this represents an actual change
+bool SetRemoveImpl::doIsChange() const
+{
+ return !!m_aOldTree.is();
+}
+//-----------------------------------------------------------------------------
+
+/// fills in pre- and post-change values, returns wether they differ
+bool SetRemoveImpl::doFillChange(NodeChangeData& rChange, sal_uInt32) const
+{
+ rChange.type = NodeChangeData::eRemoveElement;
+ if (m_aOldTree.is())
+ rChange.element.oldValue = m_aOldTree;
+
+ return isChange(true);
+}
+//-----------------------------------------------------------------------------
+
+void SetRemoveImpl::doTestElement( view::SetNode const& _aNode, rtl::OUString const& aName)
+{
+ OSL_ASSERT(!m_aOldTree.is()); // already tested ?
+
+ // remove the old node
+ SetEntry anEntry = getTargetView().findElement(_aNode,aName); // require loaded children
+ OSL_ENSURE(anEntry.isValid(), "ERROR: Configuration: Removing a node that doesn't exist");
+
+ m_aOldTree = anEntry.tree();
+}
+//-----------------------------------------------------------------------------
+
+void SetRemoveImpl::doApplyToElement( view::SetNode const& _aNode, rtl::OUString const& aName)
+{
+ getTargetView().removeElement(_aNode, aName);
+}
+
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/treemgr/nodechangeimpl.hxx b/configmgr/source/treemgr/nodechangeimpl.hxx
new file mode 100644
index 000000000000..ca456e3a1d22
--- /dev/null
+++ b/configmgr/source/treemgr/nodechangeimpl.hxx
@@ -0,0 +1,432 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodechangeimpl.hxx,v $
+ * $Revision: 1.14 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGCHANGEIMPL_HXX_
+#define CONFIGMGR_CONFIGCHANGEIMPL_HXX_
+
+#include "configexcept.hxx"
+#include "configpath.hxx"
+#include "viewaccess.hxx"
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include "utility.hxx"
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+ class ISubtree;
+
+ namespace view { class ViewTreeAccess; struct Node; struct GroupNode; struct SetNode; }
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+ class ValueMemberNode;
+ class ValueMemberUpdate;
+//-----------------------------------------------------------------------------
+ class NodeChangeData;
+ class NodeChangeLocation;
+ class NodeChangeInformation;
+//-----------------------------------------------------------------------------
+ struct ElementTreeChange
+ {
+ Path::Component m_aElementName;
+ rtl::Reference<ElementTree> m_aAddedElement;
+ rtl::Reference<ElementTree> m_aRemovedElement;
+
+ ElementTreeChange(
+ Path::Component const& _aElementName,
+ rtl::Reference<ElementTree> const& _aAddedElement,
+ rtl::Reference<ElementTree> const& _aRemovedElement
+ )
+ : m_aElementName(_aElementName)
+ , m_aAddedElement(_aAddedElement)
+ , m_aRemovedElement(_aRemovedElement)
+ {}
+
+ bool isChange() const
+ {
+ return !!(m_aAddedElement != m_aRemovedElement);
+ }
+ };
+//-----------------------------------------------------------------------------
+
+
+ /// represents a node position in some tree
+ class NodeChangeImpl
+ : public salhelper::SimpleReferenceObject
+ {
+ public:
+ explicit
+ NodeChangeImpl(bool bNoCheck = false);
+
+ public:
+ // related/affected nodes and trees
+ /// the tree within which the change occurs
+ rtl::Reference<Tree> getTargetTree() const;
+
+ /// the node that is affected by the change
+ unsigned int getTargetNode() const;
+
+ protected:
+ /// setup the 'target' node that is to be affected or changed
+ void setTarget(rtl::Reference<Tree> const& _aAffectedTree, unsigned int _nAffectedNode);
+ void setTarget(view::Node _aAffectedNode);
+
+ view::ViewTreeAccess getTargetView();
+ public:
+ // getting information
+ /*static const sal_uInt32*/ enum { scCommonBase = ~0u };
+
+ /// checks, if this represents an actual change - with or without requiring a preceding test
+ bool isChange(bool bAllowUntested) const;
+
+ /// return the number of distict changes in this object
+ sal_uInt32 getChangeDataCount() const;
+
+ /// fills in base change location, returns whether it is set
+ bool fillChangeLocation(NodeChangeLocation& rChange, sal_uInt32 _ix = scCommonBase) const;
+
+ /// fills in pre- and post-change values, returns whether they may differ
+ bool fillChangeData(NodeChangeData& rChange, sal_uInt32 _ix) const;
+
+ /// fills in change location and values, returns whether data may be changed
+ bool fillChangeInfo(NodeChangeInformation& rChange, sal_uInt32 _ix) const;
+
+ /// test whether this really is a change to the stored 'changing' node
+ void test();
+
+ /// apply this change to the stored 'changing' node
+ void apply();
+
+ private:
+ /// virtual hooks for some of the public methods
+ /// return the number of distict changes in this object
+ sal_uInt32 doGetChangeCount() const;
+
+ /// the path from base to 'changing' node
+ virtual RelativePath doGetChangingNodePath(sal_uInt32 _ix) const = 0;
+
+ /// is the change really affecting a child (or children) of the affected node (true for values)
+ virtual bool doIsChangingSubnode() const = 0;
+
+ /// checks, if this represents an actual change (given whether the change has been applied or not)
+ virtual bool doIsChange() const = 0;
+
+ /// fills in pre- and post-change values, returns wether they differ
+ virtual bool doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const = 0;
+
+ /// dry-check whether this is a change
+ virtual void doTest( view::Node const& rTarget) = 0;
+ /// do apply the actual change
+ virtual void doApply( view::Node const& rTarget) = 0;
+
+ private:
+ rtl::Reference<Tree> m_aAffectedTree;
+ unsigned int m_nAffectedNode;
+ sal_uInt16 m_nState;
+
+ void implApply();
+ view::Node implGetTarget();
+ };
+//-----------------------------------------------------------------------------
+
+ /// represents a node position in some tree
+ class ValueChangeImpl
+ : public NodeChangeImpl
+ {
+ rtl::OUString m_aName;
+ com::sun::star::uno::Any m_aNewValue;
+ com::sun::star::uno::Any m_aOldValue;
+ public:
+ explicit ValueChangeImpl();
+ explicit ValueChangeImpl(com::sun::star::uno::Any const& aNewValue);
+ explicit ValueChangeImpl(com::sun::star::uno::Any const& aNewValue, com::sun::star::uno::Any const& aOldValue);
+ ~ValueChangeImpl();
+
+ public:
+ /// setup the 'target' node that is to be affected or changed
+ void setTarget(view::GroupNode const& _aParentNode, rtl::OUString const& sNodeName);
+ void setTarget(rtl::Reference<Tree> const& aAffectedTree, unsigned int nParentNode, rtl::OUString const& sNodeName);
+
+ public:
+ /// get the name of the value
+ rtl::OUString getValueName() const { return m_aName; }
+
+ /// get the pre-change value (if known)
+ com::sun::star::uno::Any getOldValue() const { return m_aOldValue; }
+ /// get the post-change value (if known)
+ com::sun::star::uno::Any getNewValue() const { return m_aNewValue; }
+
+ protected:
+ using NodeChangeImpl::setTarget;
+ // override information items
+ /// the path from base to 'affected' node - here is the name of the changing node
+ virtual RelativePath doGetChangingNodePath(sal_uInt32 _ix) const;
+
+ /// is the change really affecting a child of the affected node (true here)
+ virtual bool doIsChangingSubnode() const;
+
+ protected:
+ // override change information items
+ /// checks, if this represents an actual change (given whether the change has been applied or not)
+ virtual bool doIsChange() const;
+
+ /// fills in pre- and post-change values, returns wether they differ
+ virtual bool doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const = 0;
+
+ protected:
+ // override apply functionality
+ /// retrieve the old value from the given node
+ virtual void doTest( view::Node const& rTarget);
+ /// do apply the actual change
+ virtual void doApply( view::Node const& rTarget);
+
+ protected:
+ // new overrideables
+ /// extract the pre-change value from the target context
+ virtual void preCheckValue(ValueMemberNode& rNode, com::sun::star::uno::Any& rOld, com::sun::star::uno::Any& rNew);
+ /// extract the post-change value from the target context
+ virtual void postCheckValue(ValueMemberNode& rNode, com::sun::star::uno::Any& rNew);
+ /// apply the new value to the target context
+ virtual void doApplyChange(ValueMemberUpdate& rNode) = 0;
+ };
+//-----------------------------------------------------------------------------
+
+ /// represents setting a value node to a given value
+ class ValueReplaceImpl
+ : public ValueChangeImpl
+ {
+ public:
+ explicit ValueReplaceImpl(com::sun::star::uno::Any const& aNewValue);
+ explicit ValueReplaceImpl(com::sun::star::uno::Any const& aNewValue, com::sun::star::uno::Any const& aOldValue);
+
+ protected:
+ // implement: set the target to the new value
+ virtual void doApplyChange( ValueMemberUpdate& rNode);
+
+ /// fills in pre- and post-change values, returns wether they differ
+ virtual bool doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const;
+
+// friend class SetReplaceValueImpl;
+ };
+//-----------------------------------------------------------------------------
+
+ /// represents resetting a value node to its default value
+ class ValueResetImpl
+ : public ValueChangeImpl
+ {
+ bool m_bTargetIsDefault;
+ public:
+ explicit ValueResetImpl();
+ explicit ValueResetImpl(com::sun::star::uno::Any const& aNewValue, com::sun::star::uno::Any const& aOldValue);
+
+ protected:
+ // override: set the new value as well and check the default state
+ virtual void preCheckValue(ValueMemberNode& rNode, com::sun::star::uno::Any& rOld, com::sun::star::uno::Any& rNew);
+
+ /// checks, if this represents an actual change (given whether the change has been applied or not)
+ virtual bool doIsChange() const;
+
+ // implement: set the target to default
+ virtual void doApplyChange( ValueMemberUpdate& rNode);
+
+ /// fills in pre- and post-change values, returns wether they differ
+ virtual bool doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const;
+ };
+//-----------------------------------------------------------------------------
+
+
+ /// represents a change to a set (as a container)
+ class SetChangeImpl
+ : public NodeChangeImpl
+ {
+ public:
+ explicit SetChangeImpl(bool bNoCheck = false);
+
+ using NodeChangeImpl::setTarget;
+
+ protected:
+ /// virtual hooks for some of the public methods
+ /// is the change really affecting a child of the affected node (false here)
+ virtual bool doIsChangingSubnode() const;
+ };
+//-----------------------------------------------------------------------------
+ class SetElementFactory;
+
+ /// represents setting to its default state a set (as a container)
+ class SetResetImpl
+ : public SetChangeImpl
+ {
+ std::auto_ptr<ISubtree> m_aDefaultData;
+ SetElementFactory& m_rElementFactory;
+ std::vector< ElementTreeChange > m_aTreeChanges;
+ public:
+ explicit SetResetImpl(
+ SetElementFactory& _rElementFactory,
+ std::auto_ptr<ISubtree> _pDefaultData,
+ bool _bNoCheck = false);
+
+ ~SetResetImpl();
+
+ protected:
+ /// virtual hooks for some of the public methods
+ /// retrieve the count of elements affected
+ sal_uInt32 doGetChangeCount() const;
+
+ /// the path from base to 'affected' node
+ virtual RelativePath doGetChangingNodePath(sal_uInt32 _ix) const;
+
+ /// checks, if this represents an actual change (given whether the change has been applied or not)
+ virtual bool doIsChange() const;
+ /// fills in pre- and post-change values, returns wether they differ
+ virtual bool doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const;
+
+
+ /// retrieve the old value from the given node
+ virtual void doTest( view::Node const& rTarget);
+ /// do apply the actual change
+ virtual void doApply( view::Node const& rTarget);
+ };
+//-----------------------------------------------------------------------------
+
+ /// represents a change to an element of a set (as a container)
+ class SetElementChangeImpl
+ : public SetChangeImpl
+ {
+ Path::Component m_aName;
+ public:
+ explicit SetElementChangeImpl(Path::Component const& aName, bool bNoCheck = false);
+
+ /// the name of the element being changed
+ Path::Component getFullElementName() const { return m_aName; }
+
+ /// the name of the element being changed
+ rtl::OUString getElementName() const { return m_aName.getName(); }
+
+ protected:
+ /// virtual hooks for some of the public methods
+ /// the path from base to 'affected' node - use element name
+ virtual RelativePath doGetChangingNodePath(sal_uInt32 _ix) const;
+
+ /// retrieve the old value from the given node
+ virtual void doTest( view::Node const& rTarget);
+ /// do apply the actual change
+ virtual void doApply( view::Node const& rTarget);
+
+ private:
+ /// new overridable: retrieve the old value from a properly typed node
+ virtual void doTestElement(view::SetNode const& _aNode, rtl::OUString const& aName) = 0;
+ /// new overridable: apply the change to a properly typed node
+ virtual void doApplyToElement(view::SetNode const& _aNode, rtl::OUString const& aName) = 0;
+ };
+//-----------------------------------------------------------------------------
+
+ /// represents an insertion into a set of trees
+ class SetInsertImpl
+ : public SetElementChangeImpl
+ {
+ rtl::Reference<ElementTree> m_aNewTree;
+ public:
+ explicit SetInsertImpl(Path::Component const& aName, rtl::Reference<ElementTree> const& aNewTree, bool bNoCheck = false);
+
+ protected:
+ /// checks, if this represents an actual change (given whether the change has been applied or not)
+ virtual bool doIsChange() const;
+ /// fills in pre- and post-change values, returns wether they differ
+ virtual bool doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const;
+
+ /// new overridable: retrieve the old value from a properly typed node
+ virtual void doTestElement(view::SetNode const& _aNode, rtl::OUString const& aName);
+ /// new overridable: apply the change to a properly typed node
+ virtual void doApplyToElement(view::SetNode const& _aNode, rtl::OUString const& aName);
+ };
+//-----------------------------------------------------------------------------
+
+ /// represents a substitution within a set of trees
+ class SetReplaceImpl
+ : public SetElementChangeImpl
+ {
+ rtl::Reference<ElementTree> m_aNewTree;
+ rtl::Reference<ElementTree> m_aOldTree;
+ public:
+ explicit SetReplaceImpl(Path::Component const& aName, rtl::Reference<ElementTree> const& aNewTree);
+ explicit SetReplaceImpl(Path::Component const& aName, rtl::Reference<ElementTree> const& aNewTree, rtl::Reference<ElementTree> const& aOldTree);
+
+ protected:
+ /// checks, if this represents an actual change (given whether the change has been applied or not)
+ virtual bool doIsChange() const;
+ /// fills in pre- and post-change values, returns wether they differ
+ virtual bool doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const;
+
+ /// new overridable: retrieve the old value from a properly typed node
+ virtual void doTestElement(view::SetNode const& _aNode, rtl::OUString const& aName);
+ /// new overridable: apply the change to a properly typed node
+ virtual void doApplyToElement(view::SetNode const& _aNode, rtl::OUString const& aName);
+ };
+//-----------------------------------------------------------------------------
+
+ /// represents a removal from of a set of trees
+ class SetRemoveImpl
+ : public SetElementChangeImpl
+ {
+ rtl::Reference<ElementTree> m_aOldTree;
+ public:
+ explicit SetRemoveImpl(Path::Component const& aName);
+ explicit SetRemoveImpl(Path::Component const& aName, rtl::Reference<ElementTree> const& aOldTree);
+
+ protected:
+ /// checks, if this represents an actual change (given whether the change has been applied or not)
+ virtual bool doIsChange() const;
+ /// fills in pre- and post-change values, returns wether they differ
+ virtual bool doFillChange(NodeChangeData& rChange, sal_uInt32 _ix) const;
+
+ /// new overridable: retrieve the old value from a properly typed node
+ virtual void doTestElement(view::SetNode const& _aNode, rtl::OUString const& aName);
+ /// new overridable: apply the change to a properly typed node
+ virtual void doApplyToElement(view::SetNode const& _aNode, rtl::OUString const& aName);
+ };
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGCHANGEIMPL_HXX_
diff --git a/configmgr/source/treemgr/nodechangeinfo.cxx b/configmgr/source/treemgr/nodechangeinfo.cxx
new file mode 100644
index 000000000000..57abeeed78a4
--- /dev/null
+++ b/configmgr/source/treemgr/nodechangeinfo.cxx
@@ -0,0 +1,224 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodechangeinfo.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "nodechangeinfo.hxx"
+
+#include "noderef.hxx"
+#include "tree.hxx"
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+NodeChangeData::NodeChangeData()
+: type(eNoChange)
+, unoData()
+, element()
+{
+}
+//-----------------------------------------------------------------------------
+
+NodeChangeData::NodeChangeData(NodeChangeData const& aOther)
+: type(aOther.type)
+, unoData(aOther.unoData)
+, element(aOther.element)
+{
+}
+//-----------------------------------------------------------------------------
+
+NodeChangeData& NodeChangeData::operator=(NodeChangeData const& aOther)
+{
+ type = aOther.type;
+ unoData = aOther.unoData;
+ element = aOther.element;
+ return *this;
+}
+//-----------------------------------------------------------------------------
+
+NodeChangeData::~NodeChangeData()
+{
+}
+//-----------------------------------------------------------------------------
+
+bool NodeChangeData::isDataChange() const
+{
+ if (isSetChange() && element.isDataChange())
+ return true;
+
+ return unoData.isDataChange();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< Tree > NodeChangeData::getNewElementTree() const
+{
+ return element.newValue.get();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< Tree > NodeChangeData::getOldElementTree() const
+{
+ return element.oldValue.get();
+}
+//-----------------------------------------------------------------------------
+
+NodeID NodeChangeData::getNewElementNodeID() const
+{
+ rtl::Reference<ElementTree> newElement = this->element.newValue;
+ if ( newElement.is() && newElement->nodeCount() > 0)
+ {
+ return NodeID( newElement.get(), Tree::ROOT );
+ }
+ else
+ return NodeID(0,0);
+}
+//-----------------------------------------------------------------------------
+
+NodeID NodeChangeData::getOldElementNodeID() const
+{
+ rtl::Reference<ElementTree> oldElement = this->element.oldValue;
+ if ( oldElement.is() && oldElement->nodeCount() > 0)
+ {
+ return NodeID( oldElement.get(), Tree::ROOT );
+ }
+ else
+ return NodeID(0,0);
+}
+//-----------------------------------------------------------------------------
+
+NodeChangeLocation::NodeChangeLocation()
+: m_path()
+, m_base(0,0)
+, m_affected(0,0)
+, m_bSubNodeChanging(false)
+{
+}
+//-----------------------------------------------------------------------------
+bool NodeChangeLocation::isValidLocation() const
+{
+ return m_base.isValidNode() &&
+ (m_affected.isEmpty()
+ ? ! m_bSubNodeChanging
+ : ( m_affected.isValidNode() &&
+ (! m_bSubNodeChanging ||
+ (!m_path.isEmpty() &&
+ SubNodeID(m_affected,m_path.getLocalName().getName()).isValidNode()
+ ) ) ) );
+}
+#if OSL_DEBUG_LEVEL > 0
+//-----------------------------------------------------------------------------
+bool NodeChangeLocation::isValidData() const
+{
+ return m_base.isValidNode() &&
+ (m_affected.isEmpty()
+ ? ! m_bSubNodeChanging
+ : ( m_affected.isValidNode() &&
+ (! m_bSubNodeChanging || !m_path.isEmpty() )
+ ) );
+}
+#endif
+//-----------------------------------------------------------------------------
+
+void NodeChangeLocation::setAccessor(RelativePath const& aAccessor)
+{
+ m_path = aAccessor;
+}
+//-----------------------------------------------------------------------------
+
+void NodeChangeLocation::setBase(NodeID const& aBaseNode)
+{
+ m_base = aBaseNode;
+}
+//-----------------------------------------------------------------------------
+
+void NodeChangeLocation::setAffected(NodeID const& aTargetNode)
+{
+ m_affected = aTargetNode;
+
+ if (m_base.isEmpty())
+ setBase(aTargetNode);
+}
+//-----------------------------------------------------------------------------
+
+void NodeChangeLocation::setChangingSubnode( bool bSubnode )
+{
+ OSL_ENSURE(!m_affected.isEmpty() || !bSubnode, "Change without target cannot affect subnode");
+
+ m_bSubNodeChanging = bSubnode;
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< Tree > NodeChangeLocation::getBaseTree() const
+{
+ OSL_ENSURE(m_base.isValidNode(), "Invalid base location set in NodeChangeLocation");
+ return m_base.getTree();
+}
+//-----------------------------------------------------------------------------
+
+NodeRef NodeChangeLocation::getBaseNode() const
+{
+ OSL_ENSURE(m_base.isValidNode(), "Invalid base location set in NodeChangeLocation");
+ return m_base.getNode();
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< Tree > NodeChangeLocation::getAffectedTreeRef() const
+{
+ NodeID aAffected = this->getAffectedNodeID();
+ return aAffected.getTree();
+}
+//-----------------------------------------------------------------------------
+
+NodeID NodeChangeLocation::getAffectedNodeID() const
+{
+ OSL_ENSURE(m_affected.isEmpty() || m_affected.isValidNode(), "Invalid target location set in NodeChangeLocation");
+ return m_affected;
+}
+//-----------------------------------------------------------------------------
+
+SubNodeID NodeChangeLocation::getChangingValueID() const
+{
+ if (!m_bSubNodeChanging) return SubNodeID::createEmpty();
+
+ OSL_ENSURE(!m_affected.isEmpty() && m_affected.isValidNode(), "Invalid target location set in NodeChangeLocation with subnode");
+ OSL_ENSURE(!m_path.isEmpty(), "No target accessor set in NodeChangeLocation with subnode");
+
+ SubNodeID aResult( m_affected, m_path.getLocalName().getName() );
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/nodefactory.cxx b/configmgr/source/treemgr/nodefactory.cxx
new file mode 100644
index 000000000000..1453413f3a1c
--- /dev/null
+++ b/configmgr/source/treemgr/nodefactory.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodefactory.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "nodefactory.hxx"
+#include "nodeimplobj.hxx"
+#include "configpath.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+namespace view
+{
+
+// Creating Specific types of nodes
+//-----------------------------------------------------------------------------
+namespace
+{
+//---------------------------------------------------------------------
+ struct BasicNodeFactory : NodeFactory
+ {
+ rtl::Reference<configuration::NodeImpl> makeValueNode(sharable::ValueNode * node);
+ rtl::Reference<configuration::NodeImpl> makeGroupNode(sharable::GroupNode * node);
+ rtl::Reference<configuration::NodeImpl> makeSetNode(sharable::SetNode * node, configuration::Template* pTemplate);
+ };
+ //-------------------------------------------------------------------------
+
+ rtl::Reference<configuration::NodeImpl> BasicNodeFactory::makeValueNode(sharable::ValueNode * node)
+ {
+ return new configuration::ValueElementNodeImpl(node);
+ }
+ //-------------------------------------------------------------------------
+
+ rtl::Reference<configuration::NodeImpl> BasicNodeFactory::makeGroupNode(sharable::GroupNode * node)
+ {
+ return new configuration::GroupNodeImpl(node);
+ }
+ //-------------------------------------------------------------------------
+
+ rtl::Reference<configuration::NodeImpl> BasicNodeFactory::makeSetNode(sharable::SetNode * node, configuration::Template* pTemplate)
+ {
+ return new configuration::SetNodeImpl(node, pTemplate);
+ }
+ //-------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+
+ struct DeferredNodeFactory : NodeFactory
+ {
+ rtl::Reference<configuration::NodeImpl> makeValueNode(sharable::ValueNode * node);
+ rtl::Reference<configuration::NodeImpl> makeGroupNode(sharable::GroupNode * node);
+ rtl::Reference<configuration::NodeImpl> makeSetNode(sharable::SetNode * node, configuration::Template* pTemplate);
+ };
+ //-------------------------------------------------------------------------
+
+ rtl::Reference<configuration::NodeImpl> DeferredNodeFactory::makeValueNode(sharable::ValueNode * node)
+ {
+ // OSL_ENSURE(false, "Wrong factory for value elements - should be immutable (=read-only)");
+ return new configuration::ValueElementNodeImpl(node);
+ }
+ //-------------------------------------------------------------------------
+
+ rtl::Reference<configuration::NodeImpl> DeferredNodeFactory::makeGroupNode(sharable::GroupNode * node)
+ {
+ return new configuration::DeferredGroupNodeImpl(node);
+ }
+ //-------------------------------------------------------------------------
+
+ rtl::Reference<configuration::NodeImpl> DeferredNodeFactory::makeSetNode(sharable::SetNode * node, configuration::Template* pTemplate)
+ {
+ return new configuration::DeferredSetNodeImpl(node, pTemplate);
+ }
+ //-------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+} // anonymous
+//-----------------------------------------------------------------------------
+
+// Different standard (static) factories
+//---------------------------------------------------------------------
+
+ /// provides a factory for immediately commiting node implementations
+ NodeFactory& getDirectAccessFactory()
+ {
+ static BasicNodeFactory aFactory;
+ return aFactory;
+ }
+ /// provides a factory for read-only node implementations
+ NodeFactory& getReadAccessFactory()
+ {
+ static BasicNodeFactory aFactory;
+ return aFactory;
+ }
+ /// provides a factory for nodes that cache changes temporarily
+ NodeFactory& getDeferredChangeFactory()
+ {
+ static DeferredNodeFactory aFactory;
+ return aFactory;
+ }
+
+//---------------------------------------------------------------------
+} // view
+
+//-----------------------------------------------------------------------------
+} // configmgr
+
diff --git a/configmgr/source/treemgr/nodefactory.hxx b/configmgr/source/treemgr/nodefactory.hxx
new file mode 100644
index 000000000000..1f96839cd998
--- /dev/null
+++ b/configmgr/source/treemgr/nodefactory.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodefactory.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGNODEFACTORY_HXX_
+#define CONFIGMGR_CONFIGNODEFACTORY_HXX_
+
+#include <rtl/ref.hxx>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+ class NodeImpl;
+ class Template;
+ }
+ namespace sharable {
+ struct GroupNode;
+ struct SetNode;
+ struct ValueNode;
+ }
+//-----------------------------------------------------------------------------
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+
+// Creating Specific types of nodes
+//-----------------------------------------------------------------------------
+
+ struct NodeFactory
+ {
+ virtual rtl::Reference<configuration::NodeImpl> makeValueNode(sharable::ValueNode * node) = 0;
+ virtual rtl::Reference<configuration::NodeImpl> makeGroupNode(sharable::GroupNode * node) = 0;
+ virtual rtl::Reference<configuration::NodeImpl> makeSetNode(sharable::SetNode * node, configuration::Template* pTemplate) = 0;
+ };
+ }
+//-----------------------------------------------------------------------------
+
+}
+
+#endif // CONFIGMGR_CONFIGNODEFACTORY_HXX_
diff --git a/configmgr/source/treemgr/nodeimpl.cxx b/configmgr/source/treemgr/nodeimpl.cxx
new file mode 100644
index 000000000000..fc56655c3b61
--- /dev/null
+++ b/configmgr/source/treemgr/nodeimpl.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodeimpl.cxx,v $
+ * $Revision: 1.26 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "nodeimpl.hxx"
+#include "valuenodeimpl.hxx"
+#include "groupnodeimpl.hxx"
+#include "nodevisitor.hxx"
+#include "tree.hxx"
+#include "nodechange.hxx"
+#include "nodechangeimpl.hxx"
+#include "nodechangeinfo.hxx"
+#include "change.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+
+// Specific types of nodes
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class GroupNodeImpl
+//-----------------------------------------------------------------------------
+
+sharable::GroupNode * GroupNodeImpl::getDataAccess() const
+{
+ sharable::Node * node = getOriginalNodeAccess();
+ OSL_ASSERT(node != 0 && node->isGroup());
+ return &node->group;
+}
+//-----------------------------------------------------------------------------
+
+GroupNodeImpl::GroupNodeImpl(sharable::GroupNode * _pNodeRef)
+ : NodeImpl(reinterpret_cast<sharable::Node *>(_pNodeRef))
+ , m_pCache( NULL )
+{
+}
+//-----------------------------------------------------------------------------
+
+bool GroupNodeImpl::areValueDefaultsAvailable() const
+{
+ return getDataAccess()->hasDefaultsAvailable();
+}
+//-----------------------------------------------------------------------------
+
+ValueMemberNode GroupNodeImpl::makeValueMember(sharable::ValueNode * node)
+{
+ return ValueMemberNode(node);
+}
+//-----------------------------------------------------------------------------
+
+sharable::ValueNode * GroupNodeImpl::getOriginalValueNode(rtl::OUString const& _aName) const
+{
+ OSL_ENSURE( _aName.getLength() != 0, "Cannot get nameless child value");
+
+ sharable::GroupNode * group = getDataAccess();
+
+ if (m_pCache)
+ {
+ if (m_pCache->isNamed(_aName))
+ return m_pCache->valueData();
+
+ m_pCache = group->getNextChild(m_pCache);
+
+ if (m_pCache && m_pCache->isNamed(_aName))
+ return m_pCache->valueData();
+ m_pCache = NULL;
+ }
+
+ sharable::Node * child = group->getChild(_aName);
+ m_pCache = child;
+
+ // to do: investigate cache lifecycle more deeply.
+
+ return child == 0 ? 0 : child->valueData();
+}
+
+//-----------------------------------------------------------------------------
+// class ValueElementNodeImpl
+//-----------------------------------------------------------------------------
+
+sharable::ValueNode * ValueElementNodeImpl::getDataAccess() const
+{
+ sharable::Node * node = getOriginalNodeAccess();
+ OSL_ASSERT(node != 0 && node->isValue());
+ return &node->value;
+}
+//-----------------------------------------------------------------------------
+
+ValueElementNodeImpl::ValueElementNodeImpl(sharable::ValueNode * const& _aNodeRef)
+ : NodeImpl(reinterpret_cast<sharable::Node *>(_aNodeRef))
+{
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any ValueElementNodeImpl::getValue() const
+{
+ return getDataAccess()->getValue();
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Type ValueElementNodeImpl::getValueType() const
+{
+ return getDataAccess()->getValueType();
+}
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/treemgr/nodeimpl.hxx b/configmgr/source/treemgr/nodeimpl.hxx
new file mode 100644
index 000000000000..31b5f99b6c79
--- /dev/null
+++ b/configmgr/source/treemgr/nodeimpl.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodeimpl.hxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_CONFIGNODEBEHAVIOR_HXX_
+#define CONFIGMGR_CONFIGNODEBEHAVIOR_HXX_
+
+#include "attributes.hxx"
+#include "node.hxx"
+#include "utility.hxx"
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace view { class ViewStrategy; }
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+ //-----------------------------------------------------------------------------
+ class Tree;
+ class NodeChange;
+ class NodeChanges;
+ class NodeChangesInformation;
+
+//-----------------------------------------------------------------------------
+// Specific types of nodes
+//-----------------------------------------------------------------------------
+
+ class NodeImpl;
+ struct INodeHandler;
+
+ // Almost an interface, but derives from concrete OReference
+ class NodeImpl : public salhelper::SimpleReferenceObject
+ {
+ friend class view::ViewStrategy;
+ sharable::Node * m_pNodeRef;
+ public:
+ NodeImpl(sharable::Node * _pNodeRef)
+ : m_pNodeRef(_pNodeRef) {}
+
+ public:
+ /// provide access to the data of the underlying node
+ sharable::Node * getOriginalNodeAccess() const
+ { return m_pNodeRef; }
+ };
+
+//-----------------------------------------------------------------------------
+ class ValueElementNodeImpl;
+ class GroupNodeImpl;
+ class SetNodeImpl;
+//-----------------------------------------------------------------------------
+
+ struct INodeHandler
+ {
+ virtual void handle( ValueElementNodeImpl& rNode) = 0;
+ virtual void handle( GroupNodeImpl& rNode) = 0;
+ virtual void handle( SetNodeImpl& rNode) = 0;
+ };
+
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_CONFIGNODEBEHAVIOR_HXX_
diff --git a/configmgr/source/treemgr/nodeimplobj.cxx b/configmgr/source/treemgr/nodeimplobj.cxx
new file mode 100644
index 000000000000..57958c82771b
--- /dev/null
+++ b/configmgr/source/treemgr/nodeimplobj.cxx
@@ -0,0 +1,1165 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodeimplobj.cxx,v $
+ * $Revision: 1.26 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "nodeimplobj.hxx"
+
+
+#include "nodechange.hxx"
+#include "nodechangeinfo.hxx"
+#include "nodechangeimpl.hxx"
+#include "valuenode.hxx"
+#include "change.hxx"
+#include "viewaccess.hxx"
+#include "viewfactory.hxx"
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+// Value Nodes
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class DeferredValueElementNodeImpl
+//-----------------------------------------------------------------------------
+
+// Group Nodes
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class DeferredGroupNodeImpl
+//-----------------------------------------------------------------------------
+
+DeferredGroupNodeImpl::DeferredGroupNodeImpl(sharable::GroupNode * const& _aNodeRef)
+: GroupNodeImpl(_aNodeRef)
+, m_aChanges()
+{
+}
+//-----------------------------------------------------------------------------
+
+DeferredGroupNodeImpl::~DeferredGroupNodeImpl()
+{
+}
+//-----------------------------------------------------------------------------
+
+ValueMemberNode DeferredGroupNodeImpl::makeValueMember(rtl::OUString const& _aName, bool _bForUpdate)
+{
+ MemberChanges::iterator it = m_aChanges.find(_aName);
+
+ if (it != m_aChanges.end())
+ {
+ if (!it->second.is())
+ OSL_ENSURE(_aName.getLength() == 0, "ERROR: Found empty change reference");
+
+ else if (_bForUpdate || it->second->isChange()) // found one
+ return ValueMemberNode(it->second);
+
+ else // leftover non-change
+ m_aChanges.erase(it);
+
+ // if not found continue with default
+ }
+
+ sharable::ValueNode * original = getOriginalValueNode(_aName);
+
+ if (_bForUpdate) // create a new change
+ {
+ if (original != 0)
+ {
+ rtl::Reference<ValueMemberNode::DeferredImpl> aNewChange(new ValueMemberNode::DeferredImpl(original));
+ m_aChanges[_aName] = aNewChange;
+
+ return ValueMemberNode(aNewChange);
+ }
+ }
+
+ return GroupNodeImpl::makeValueMember(original);
+}
+//-----------------------------------------------------------------------------
+
+bool DeferredGroupNodeImpl::hasChanges() const
+{
+ for (MemberChanges::const_iterator it = m_aChanges.begin(); it != m_aChanges.end(); ++it)
+ {
+ if (!it->second.is())
+ {
+ // empty element is present -> marked as changed
+ OSL_ASSERT(it->first.getLength() == 0);
+ return true;
+ }
+
+ if (it->second->isChange())
+ return true;
+ }
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+void DeferredGroupNodeImpl::collectValueChanges(NodeChanges& rChanges, Tree* pParentTree, unsigned int nNode) const
+{
+ for (MemberChanges::const_iterator it = m_aChanges.begin(); it != m_aChanges.end(); ++it)
+ {
+ if (it->second.is())
+ {
+ OSL_ASSERT(it->first.getLength() != 0);
+ if (ValueChangeImpl* pValueChange = it->second->collectChange())
+ {
+ pValueChange->setTarget(pParentTree,nNode,it->first);
+
+ rChanges.add( NodeChange(pValueChange) );
+ }
+ else // leftover non-change
+ OSL_ENSURE(!it->second->isChange(), "Got no change from a changing value") ;
+ }
+ else
+ OSL_ASSERT(it->first.getLength() == 0);
+ }
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference<ValueMemberNode::DeferredImpl> DeferredGroupNodeImpl::findValueChange(rtl::OUString const& aName)
+{
+ rtl::Reference<ValueMemberNode::DeferredImpl> aResult;
+
+ MemberChanges::iterator it = m_aChanges.find(aName);
+
+ if (it != m_aChanges.end())
+ {
+ if (it->second.is() )
+ {
+ if (it->second->isChange())
+ {
+ aResult = it->second;
+ }
+
+ else // leftover non-change -> drop
+ {
+ m_aChanges.erase(it);
+ }
+ }
+ else
+ OSL_ENSURE(aName.getLength() == 0, "ERROR: Found empty change reference");
+ }
+
+ return aResult;
+}
+
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<SubtreeChange> DeferredGroupNodeImpl::preCommitValueChanges()
+{
+ std::auto_ptr<SubtreeChange> aRet;
+
+ if (!m_aChanges.empty())
+ {
+ sharable::Node * originalData = this->getOriginalNodeAccess();
+ aRet.reset( new SubtreeChange( originalData->getName(),
+ originalData->getAttributes() ) );
+
+ for (MemberChanges::iterator pos = m_aChanges.begin(); pos != m_aChanges.end(); )
+ {
+ MemberChanges::iterator it = pos++; // this is used to allow erasing below
+
+ if (!it->second.is())
+ {
+ OSL_ASSERT(it->first.getLength() == 0);
+ }
+ else if (it->second->isChange())
+ {
+ std::auto_ptr<ValueChange> aValueChange = it->second->preCommitChange();
+ if (aValueChange.get())
+ {
+ std::auto_ptr<Change> aBaseChange(aValueChange.release());
+ aRet->addChange( aBaseChange );
+ }
+ else
+ OSL_ENSURE(false, "Got no change from a changed member");
+ }
+ else // found left-over non-change
+ m_aChanges.erase(it);
+ }
+ if (m_aChanges.empty()) aRet.reset();
+ }
+
+ return aRet;
+}
+//-----------------------------------------------------------------------------
+
+void DeferredGroupNodeImpl::finishCommit(SubtreeChange& rChanges)
+{
+ OSL_ENSURE(!rChanges.isSetNodeChange(),"ERROR: Change type SET does not match group");
+
+ for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
+ it != stop;
+ ++it)
+ {
+ rtl::OUString aValueName(it->getNodeName());
+
+ MemberChanges::iterator itStoredChange = m_aChanges.find(aValueName);
+
+ if (itStoredChange != m_aChanges.end())
+ {
+ ValueChange * valueChange = dynamic_cast< ValueChange * >(&*it);
+ OSL_ENSURE(valueChange != 0, "Unexpected type of element change");
+ if (valueChange == 0) throw Exception("Unexpected type of element change");
+
+ rtl::Reference<ValueMemberNode::DeferredImpl> aStoredChange = itStoredChange->second;
+ OSL_ENSURE( aStoredChange.is(), "Found empty change object for Member value change");
+
+ if (aStoredChange.is())
+ {
+ aStoredChange->finishCommit(*valueChange);
+ OSL_ENSURE(!aStoredChange->isChange(),"ValueChange is not moot after finishCommit");
+ }
+
+ m_aChanges.erase( itStoredChange ); // remove finished change
+ }
+ else
+ OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) == 0, "Value member change has no change data representation");
+
+ }
+
+ OSL_DEBUG_ONLY( m_aChanges.erase( rtl::OUString() ) ); // remove change marker (if present)
+ OSL_ENSURE(m_aChanges.empty(), "Found unprocessed changes to values in group");
+
+ m_aChanges.clear(); // remove all pending stuff and marker
+}
+//-----------------------------------------------------------------------------
+
+void DeferredGroupNodeImpl::revertCommit(SubtreeChange& rChanges)
+{
+ OSL_ENSURE(!rChanges.isSetNodeChange(),"ERROR: Change type SET does not match group");
+
+ for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
+ it != stop;
+ ++it)
+ {
+ rtl::OUString aValueName(it->getNodeName());
+
+ MemberChanges::iterator itStoredChange = m_aChanges.find(aValueName);
+
+ if (itStoredChange != m_aChanges.end())
+ {
+ ValueChange * valueChange = dynamic_cast< ValueChange * >(&*it);
+ OSL_ENSURE(valueChange != 0, "Unexpected type of element change");
+ if (valueChange == 0) continue;
+
+ rtl::Reference<ValueMemberNode::DeferredImpl> aStoredChange = itStoredChange->second;
+ OSL_ENSURE( aStoredChange.is(), "Cannot restore change: found empty change object for Member value change");
+
+ if (aStoredChange.is())
+ {
+ aStoredChange->revertCommit(*valueChange);
+ OSL_ENSURE(!aStoredChange->isChange(),"ValueChange is not moot after reverting - will be discarded nevertheless");
+ }
+ m_aChanges.erase( itStoredChange ); // remove change if it is moot
+ }
+ else
+ OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) == 0, "Value member change has no change data representation");
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredGroupNodeImpl::failedCommit(SubtreeChange& rChanges)
+{
+ OSL_ENSURE(!rChanges.isSetNodeChange(),"ERROR: Change type SET does not match group");
+
+ for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
+ it != stop;
+ ++it)
+ {
+ rtl::OUString aValueName(it->getNodeName());
+
+ MemberChanges::iterator itStoredChange = m_aChanges.find(aValueName);
+
+ if (itStoredChange != m_aChanges.end())
+ {
+ ValueChange * valueChange = dynamic_cast< ValueChange * >(&*it);
+ OSL_ENSURE(valueChange != 0, "Unexpected type of element change");
+ if (valueChange == 0) continue;
+
+ rtl::Reference<ValueMemberNode::DeferredImpl> aStoredChange = itStoredChange->second;
+ OSL_ENSURE( aStoredChange.is(), "Cannot recover from failed change: found empty change object for Member value change");
+
+ if (aStoredChange.is())
+ aStoredChange->failedCommit(*valueChange);
+ {
+ if (!aStoredChange->isChange())
+ m_aChanges.erase( itStoredChange ); // remove change if it is moot
+ }
+ }
+ else
+ OSL_ENSURE(dynamic_cast< ValueChange * >(&*it) == 0, "Value member change has no change data representation");
+ }
+
+ OSL_DEBUG_ONLY( m_aChanges.erase( rtl::OUString() ) ); // remove change marker (if present)
+ OSL_ENSURE(m_aChanges.empty(), "RevertCommit: Found unprocessed changes to values in group");
+
+ m_aChanges.clear(); // discard all pending stuff and marker
+}
+//-----------------------------------------------------------------------------
+
+
+void DeferredGroupNodeImpl::markChanged()
+{
+ // special mark: a NULL rtl::Reference<ValueMemberNode::DeferredImpl> at empty name
+ m_aChanges.insert( MemberChanges::value_type() );
+}
+//-----------------------------------------------------------------------------
+
+// Set nodes
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// class DeferredTreeSetNodeImpl
+//-----------------------------------------------------------------------------
+
+DeferredSetNodeImpl::DeferredSetNodeImpl(sharable::SetNode * const& _aNodeRef, Template* pTemplate)
+: SetNodeImpl(_aNodeRef,pTemplate)
+, m_aChangedData()
+, m_bChanged(false)
+, m_bDefault(false)
+{
+}
+//-----------------------------------------------------------------------------
+
+bool DeferredSetNodeImpl::doIsEmpty() const
+{
+ if (m_aChangedData.isEmpty())
+ return SetNodeImpl::doIsEmpty();
+
+ // look for added elements
+ {for(ElementSet::ConstIterator it = m_aChangedData.begin(), stop = m_aChangedData.end();
+ it != stop;
+ ++it)
+ {
+ if (it->isValid()) return false;
+ }}
+
+
+ // look for elements in the base set that are not 'deleted' (the changes are all deletions here)
+ {for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
+ it != stop;
+ ++it)
+ {
+ if (!m_aChangedData.hasElement(it->first)) return false;
+ }}
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+ElementTree* DeferredSetNodeImpl::doFindElement(rtl::OUString const& aName)
+{
+ ElementTreeData* pElement = m_aChangedData.getElement(aName);
+ if (!pElement)
+ pElement = SetNodeImpl::getStoredElement(aName);
+
+ return pElement ? pElement->get() : 0;
+}
+//-----------------------------------------------------------------------------
+
+SetNodeVisitor::Result DeferredSetNodeImpl::doDispatchToElements(SetNodeVisitor& aVisitor)
+{
+ SetNodeVisitor::Result eRet = SetNodeVisitor::CONTINUE;
+ // look for elements in the base set that are not hidden by changes
+ {for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
+ it != stop && eRet != SetNodeVisitor::DONE;
+ ++it)
+ {
+ if (m_aChangedData.getElement(it->first) == 0)
+ {
+ OSL_ASSERT(it->second.isValid());
+ eRet = aVisitor.visit(SetEntry(it->second.get()));
+ }
+ }}
+
+ // look for added elements
+ {for(ElementSet::ConstIterator it = m_aChangedData.begin(), stop = m_aChangedData.end();
+ it != stop && eRet != SetNodeVisitor::DONE;
+ ++it)
+ {
+ if (it->isValid())
+ {
+ eRet = aVisitor.visit(SetEntry(it->get()));
+ }
+ }}
+ return eRet;
+}
+//-----------------------------------------------------------------------------
+
+bool DeferredSetNodeImpl::hasChanges() const
+{
+ return m_bChanged || !m_aChangedData.isEmpty();
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::collectElementChanges(NodeChanges& rChanges) const
+{
+ // collect added and deleted nodes
+ {for(ElementSet::Data::const_iterator it = m_aChangedData.beginNative(), stop = m_aChangedData.endNative();
+ it != stop;
+ ++it)
+ {
+ ElementTreeData const* pOriginal = SetNodeImpl::getStoredElement(it->first);
+
+ if (it->second.isValid()) // added one
+ {
+ if (pOriginal)
+ {
+ rChanges.add(NodeChange(implCreateReplace(it->first,it->second,*pOriginal)));
+ }
+ else
+ {
+ rChanges.add(NodeChange(implCreateInsert(it->first,it->second)));
+ }
+ }
+ else
+ {
+ if (pOriginal)
+ {
+ rChanges.add(NodeChange(implCreateRemove(it->first,*pOriginal)));
+ }
+
+ //else nothing to do
+ }
+ }}
+
+ // collect preexisting nodes
+ // if (!containsValues()) // value elements ar immutable !
+ {for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
+ it != stop;
+ ++it)
+ {
+ if (m_aChangedData.getElement(it->first) == 0)
+ {
+ OSL_ASSERT(it->second.isValid());
+ view::ViewTreeAccess aElementView(it->second.get());
+
+ if (aElementView.hasChanges())
+ aElementView.collectChanges(rChanges);
+ }
+ }}
+
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::markChanged()
+{
+ m_bChanged = true;
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::doTransferElements(ElementSet& rReplacement)
+{
+ // transfer preexisting nodes (unless replaced/deleted)
+ {for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
+ it != stop;
+ ++it)
+ {
+ if (m_aChangedData.getElement(it->first) == 0)
+ {
+ OSL_ASSERT(it->second.isValid());
+
+ rReplacement.insertElement(it->first,it->second);
+ }
+ }}
+
+ // commit added and deleted nodes
+ {
+ ElementSet::Data::const_iterator it = m_aChangedData.beginNative();
+ ElementSet::Data::const_iterator const stop = m_aChangedData.endNative();
+
+ while(it != stop)
+ {
+ if (it->second.isValid())
+ rReplacement.insertElement(it->first,it->second);
+
+ ++it;
+ m_aChangedData.removeElement(it->first);
+ }
+ }
+
+ m_bChanged = false;
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::rebuildElement(rtl::OUString const& _aName, ElementTreeData const& _aElement)
+{
+ Tree* pContext = this->getParentTree();
+ OSL_ENSURE(pContext, "Context tree must be set before rebuilding");
+
+ rtl::Reference<view::ViewStrategy> xContextBehavior = pContext->getViewBehavior();
+
+ sharable::TreeFragment * elementAccessor = this->getDataAccess()->getElement(_aName);
+ OSL_ENSURE(elementAccessor != 0, "Element Tree not found in data");
+
+ OSL_ENSURE(_aElement.isValid(), "Element not found in view");
+ _aElement->rebuild(xContextBehavior, elementAccessor);
+}
+
+//-----------------------------------------------------------------------------
+std::auto_ptr<SubtreeChange> DeferredSetNodeImpl::preCommitChanges(std::vector< rtl::Reference<ElementTree> >& _rRemovedElements)
+{
+ sharable::Node * originalData = this->getOriginalNodeAccess();
+ // now first get the name of this node
+ rtl::OUString sSetName = originalData->getName();
+
+ // and make a SubtreeChange
+ std::auto_ptr<SubtreeChange> pSetChange( new SubtreeChange(sSetName,
+ getElementTemplate()->getName(),
+ getElementTemplate()->getModule(),
+ originalData->getAttributes() ) );
+
+ // commit preexisting nodes
+ {
+ for(ElementSet::Data::const_iterator it = SetNodeImpl::beginElementSet(), stop = SetNodeImpl::endElementSet();
+ it != stop;
+ ++it)
+ {
+ if (m_aChangedData.getElement(it->first) == 0)
+ {
+ OSL_ASSERT(it->second.isValid());
+ OSL_ENSURE( !m_bDefault || it->second.inDefault, "m_bDefault is inconsistent");
+
+ view::ViewTreeAccess aElementView(it->second.get());
+ std::auto_ptr<SubtreeChange> pNewChange = aElementView.preCommitChanges(_rRemovedElements);
+ if (pNewChange.get() != 0)
+ {
+ //OSL_ENSURE( !containsValues(), "Unexpected change generated by value set element");
+ std::auto_ptr<Change> pNewChangeBase( pNewChange.release() );
+ pSetChange->addChange(pNewChangeBase);
+ }
+ }
+ }
+ }
+
+ // commit added and deleted nodes
+ {
+ ElementSet::Data::const_iterator it = m_aChangedData.beginNative();
+ ElementSet::Data::const_iterator const stop = m_aChangedData.endNative();
+
+ while(it != stop)
+ {
+ rtl::OUString aName = it->first;
+ ElementTreeData aNewElement = it->second;
+
+ ElementTreeData* pOriginal = SetNodeImpl::getStoredElement(aName);
+
+ if (aNewElement.isValid())
+ {
+ rtl::Reference< data::TreeSegment > aAddedTree = aNewElement->releaseOwnedTree();
+ if (!aAddedTree.is())
+ {
+ throw Exception("INTERNAL ERROR: Could not find data for the added ElementTree");
+ }
+
+ OSL_ENSURE( !m_bDefault || aNewElement.inDefault, "m_bDefault is inconsistent");
+
+ AddNode* pAddNode = new AddNode(aAddedTree, aName, aNewElement.inDefault );
+
+ std::auto_ptr<Change> pNewChange( pAddNode );
+
+ if (pOriginal)
+ pAddNode->setReplacing();
+
+ pSetChange->addChange(pNewChange);
+ }
+ else
+ {
+ if (pOriginal)
+ {
+ OSL_ENSURE( !m_bDefault || aNewElement.inDefault, "m_bDefault is inconsistent");
+
+ std::auto_ptr<Change> pNewChange( new RemoveNode(aName,aNewElement.inDefault) );
+
+ pSetChange->addChange(pNewChange);
+ }
+ //else nothing to do
+ }
+
+ // collect removed or replaced element
+ if (pOriginal)
+ _rRemovedElements.push_back( pOriginal->tree );
+
+ ++it;
+ }
+ }
+ return pSetChange;
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::finishCommit(SubtreeChange& rChanges)
+{
+ OSL_ENSURE(rChanges.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
+ OSL_ENSURE( rChanges.getElementTemplateName() == getElementTemplate()->getName(),
+ "ERROR: Element template of change does not match the template of the set");
+ OSL_ENSURE( rChanges.getElementTemplateModule() == getElementTemplate()->getModule(),
+ "ERROR: Element template module of change does not match the template of the set");
+
+ for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
+ it != stop;
+ ++it)
+ {
+ rtl::OUString aElementName(it->getNodeName());
+
+ ElementTreeData* pOriginal = getStoredElement(aElementName);
+
+ if (ElementTreeData* pNewElement = m_aChangedData.getElement(aElementName))
+ {
+ ElementTreeData aOriginal;
+ if (pOriginal)
+ {
+ aOriginal = *pOriginal;
+ OSL_ASSERT(aOriginal.isValid());
+ }
+ else
+ OSL_ASSERT(!aOriginal.isValid());
+
+ // handle a added, replaced or deleted node
+ rtl::Reference< data::TreeSegment > aRemovedTree;
+
+ if (pNewElement->isValid())
+ {
+ AddNode * addNode = dynamic_cast< AddNode * >(&*it);
+ OSL_ENSURE(addNode != 0, "Unexpected type of element change");
+ if (addNode == 0) throw Exception("Unexpected type of element change");
+
+ aRemovedTree = addNode->getReplacedTree();
+ OSL_ASSERT( addNode->isReplacing() == (0!=pOriginal) );
+ OSL_ASSERT( addNode->isReplacing() == (bool) aRemovedTree.is() );
+
+ if (aOriginal.isValid())
+ SetNodeImpl::replaceElement(aElementName,*pNewElement);
+
+ else
+ SetNodeImpl::insertElement(aElementName,*pNewElement);
+
+ this->rebuildElement(aElementName,*pNewElement);
+ }
+ else
+ {
+ RemoveNode * removeNode = dynamic_cast< RemoveNode * >(&*it);
+ OSL_ENSURE(removeNode != 0, "Unexpected type of element change");
+ if (removeNode == 0) throw Exception("Unexpected type of element change");
+
+ aRemovedTree = removeNode->getRemovedTree();
+
+ OSL_ASSERT(aOriginal.isValid());
+ if (aOriginal.isValid())
+ SetNodeImpl::removeElement(aElementName);
+ }
+ // handle a added or deleted node
+ if (aOriginal.isValid())
+ {
+ OSL_ENSURE(aRemovedTree.is(), "Cannot take over the removed node");
+
+ aOriginal->takeTreeAndRebuild(aRemovedTree);
+ }
+ m_aChangedData.removeElement(aElementName);
+ }
+ else
+ {
+ // handle preexisting nodes
+ //OSL_ENSURE(!containsValues(), "Unexpected change to value set element");
+ OSL_ENSURE(pOriginal && pOriginal->isValid(), "Changed Element is missing");
+ SubtreeChange * subtreeChange = dynamic_cast< SubtreeChange * >(&*it);
+ OSL_ENSURE(subtreeChange != 0, "Unexpected type of element change");
+
+ if (subtreeChange == 0) throw Exception("Unexpected set element change");
+
+ if (pOriginal && pOriginal->isValid())
+ view::ViewTreeAccess(pOriginal->get()).finishCommit(*subtreeChange);
+ }
+ }
+ m_bChanged = false;
+
+ OSL_ENSURE(m_aChangedData.isEmpty(), "ERROR: Uncommitted changes left in set node");
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::revertCommit(SubtreeChange& rChanges)
+{
+ OSL_ENSURE(rChanges.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
+ OSL_ENSURE( rChanges.getElementTemplateName() == getElementTemplate()->getName(),
+ "ERROR: Element template of change does not match the template of the set");
+ OSL_ENSURE( rChanges.getElementTemplateModule() == getElementTemplate()->getModule(),
+ "ERROR: Element template module of change does not match the template of the set");
+
+
+ for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
+ it != stop;
+ ++it)
+ {
+ rtl::OUString aElementName(it->getNodeName());
+
+ ElementTreeData* pOriginal = getStoredElement(aElementName);
+
+ if (ElementTreeData* pNewElement = m_aChangedData.getElement(aElementName))
+ {
+ // handle a added, replaced or deleted node
+ rtl::Reference< data::TreeSegment > pRemovedTree;
+
+ if (pNewElement->isValid())
+ {
+ AddNode * addNode = dynamic_cast< AddNode * >(&*it);
+ OSL_ENSURE(addNode != 0, "Unexpected type of element change");
+ if (addNode == 0) throw Exception("Unexpected type of element change");
+
+ pRemovedTree = addNode->getReplacedTree();
+ OSL_ASSERT( addNode->isReplacing() == (0!=pOriginal) );
+ OSL_ASSERT( addNode->isReplacing() == (0!=pRemovedTree.is()) );
+
+ OSL_ENSURE(!addNode->wasInserted(), "Cannot retract new node: Change was integrated");
+
+ rtl::Reference< data::TreeSegment > aAddedTree = addNode->getNewTree();
+ OSL_ENSURE(aAddedTree.is(), "Cannot restore new node: Change lost ownership");
+
+ // restore the tree
+ (*pNewElement)->takeTreeBack(aAddedTree);
+ }
+ else
+ {
+ RemoveNode * removeNode = dynamic_cast< RemoveNode * >(&*it);
+ OSL_ENSURE(removeNode != 0, "Unexpected type of element change");
+ if (removeNode == 0) throw Exception("Unexpected type of element change");
+
+ pRemovedTree = removeNode->getRemovedTree();
+
+ OSL_ASSERT(pOriginal);
+ OSL_ASSERT((0 != pOriginal) == (0!=pRemovedTree.is()) );
+ }
+ OSL_ENSURE(pRemovedTree.is(), "Possible problems reverting removed node: Change took ownership");
+ // try handle a added or deleted node
+ if (pOriginal)
+ {
+ OSL_ASSERT(pOriginal->isValid());
+ (*pOriginal)->takeTreeAndRebuild(pRemovedTree);
+ OSL_DEBUG_ONLY(pRemovedTree.clear());
+ }
+ OSL_ENSURE(!pRemovedTree.is(), "Could not revert removed node: Nowhere to put ownership");
+ }
+ else
+ {
+ // handle preexisting nodes
+ //OSL_ENSURE(!containsValues(), "Unexpected change to value set element");
+ OSL_ENSURE(pOriginal && pOriginal->isValid(), "Changed Element is missing");
+ SubtreeChange * subtreeChange = dynamic_cast< SubtreeChange * >(&*it);
+ OSL_ENSURE(subtreeChange != 0, "Unexpected set element change");
+
+ if (subtreeChange == 0) throw Exception("Unexpected set element change");
+
+ if (pOriginal && pOriginal->isValid())
+ view::ViewTreeAccess(pOriginal->get()).revertCommit(*subtreeChange);
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::failedCommit(SubtreeChange& rChanges)
+{
+ OSL_ENSURE(rChanges.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
+ OSL_ENSURE( rChanges.getElementTemplateName() == getElementTemplate()->getName(),
+ "ERROR: Element template of change does not match the template of the set");
+ OSL_ENSURE( rChanges.getElementTemplateModule() == getElementTemplate()->getModule(),
+ "ERROR: Element template module of change does not match the template of the set");
+
+ for(SubtreeChange::MutatingChildIterator it = rChanges.begin_changes(), stop = rChanges.end_changes();
+ it != stop;
+ ++it)
+ {
+ rtl::OUString aElementName(it->getNodeName());
+
+ ElementTreeData* pOriginal = getStoredElement(aElementName);
+
+ if (ElementTreeData* pNewElement = m_aChangedData.getElement(aElementName))
+ {
+ ElementTreeData aOriginal;
+ if (pOriginal)
+ {
+ aOriginal = *pOriginal;
+ OSL_ASSERT(aOriginal.isValid());
+ }
+ else
+ OSL_ASSERT(!aOriginal.isValid());
+
+ // handle a added, replaced or deleted node
+ rtl::Reference< data::TreeSegment > aRemovedTree;
+
+ if (pNewElement->isValid())
+ {
+ AddNode * addNode = dynamic_cast< AddNode * >(&*it);
+ OSL_ENSURE(addNode != 0, "Unexpected type of element change");
+ if (addNode == 0) throw Exception("Unexpected type of element change");
+
+ aRemovedTree = addNode->getReplacedTree();
+ OSL_ASSERT( addNode->isReplacing() == (0!=pOriginal) );
+ OSL_ASSERT( addNode->isReplacing() == (bool) aRemovedTree.is() );
+
+ if (addNode->wasInserted())
+ { // it has been integrated into the master tree
+ OSL_ENSURE(getDataAccess()->getElement(aElementName) == addNode->getInsertedTree(),
+ "Internal Error: Inserted tree address does not match actual data");
+
+ // so add it
+ if (aOriginal.isValid())
+ SetNodeImpl::replaceElement(aElementName,*pNewElement);
+
+ else
+ SetNodeImpl::insertElement(aElementName,*pNewElement);
+
+ this->rebuildElement(aElementName,*pNewElement);
+ }
+ else // Change not done; need to restore new node (element will be released into the wild then)
+ {
+ rtl::Reference< data::TreeSegment > aAddedTree = addNode->getNewTree();
+
+ OSL_ENSURE(aAddedTree.is(), "Unexpected: added node is gone, but where ? May cause invalid references");
+ (*pNewElement)->takeTreeBack(aAddedTree);
+ detach(*pNewElement);
+ }
+ }
+ else
+ {
+ RemoveNode * removeNode = dynamic_cast< RemoveNode * >(&*it);
+ OSL_ENSURE(removeNode != 0, "Unexpected type of element change");
+ if (removeNode == 0) throw Exception("Unexpected type of element change");
+
+ aRemovedTree = removeNode->getRemovedTree();
+
+ OSL_ASSERT(aOriginal.isValid());
+ if (aRemovedTree.is() && getDataAccess()->getElement(aElementName) == 0)
+ {
+ // really removed - then remove the originel
+ if (aOriginal.isValid())
+ SetNodeImpl::removeElement(aElementName);
+ }
+ }
+
+ // handle a added or deleted node
+ if (aOriginal.isValid() && aRemovedTree.is())
+ {
+ aOriginal->takeTreeAndRebuild(aRemovedTree);
+ //aOriginal->getAccess().makeDirect();
+ OSL_DEBUG_ONLY(aRemovedTree.clear());
+ }
+ OSL_ENSURE(!aRemovedTree.is(), "Could not revert removed node: Nowhere to put ownership");
+
+ m_aChangedData.removeElement(aElementName);
+ }
+ else
+ {
+ // handle preexisting nodes
+ //OSL_ENSURE(!containsValues(), "Unexpected change to value set element");
+ OSL_ENSURE(pOriginal && pOriginal->isValid(), "Changed Element is missing");
+ SubtreeChange * subtreeChange = dynamic_cast< SubtreeChange * >(&*it);
+ OSL_ENSURE(subtreeChange != 0, "Unexpected set element change");
+
+ if (subtreeChange == 0) throw Exception("Unexpected set element change");
+
+ if (pOriginal && pOriginal->isValid())
+ view::ViewTreeAccess(pOriginal->get()).recoverFailedCommit(*subtreeChange);
+ }
+ }
+ m_bChanged = false;
+ m_bDefault = false;
+
+ OSL_ENSURE(m_aChangedData.isEmpty(), "ERROR: Uncommitted changes left in set node");
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::insertNewElement(rtl::OUString const& aName, ElementTreeData const& aNewElement)
+{
+ attach(aNewElement,aName);
+ try
+ {
+ // put the new element into the changed set
+ ElementTreeData* pAddedElement = m_aChangedData.getElement(aName);
+ if (pAddedElement)
+ {
+ OSL_ENSURE(!pAddedElement->isValid(),"WARNING: Element being inserted was already there - replacing");
+ detach(m_aChangedData.replaceElement(aName,aNewElement));
+ }
+ else
+ {
+ m_aChangedData.insertElement(aName, aNewElement);
+ }
+ m_bChanged = true;
+ m_bDefault = false;
+ }
+ catch (std::exception&)
+ {
+ detach(aNewElement);
+ throw;
+ }
+}
+//-------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::removeOldElement(rtl::OUString const& aName)
+{
+ // put an empty (dummy) element into the changed set
+ ElementTreeData* pAddedElement = m_aChangedData.getElement(aName);
+ if (pAddedElement)
+ {
+ OSL_ENSURE(pAddedElement->isValid(),"WARNING: Element being removed was already removed");
+ detach(m_aChangedData.replaceElement(aName, ElementTreeData()));
+ m_bChanged = true;
+ m_bDefault = false;
+ }
+ else
+ {
+ m_aChangedData.insertElement(aName, ElementTreeData());
+ }
+
+ // now check the original one
+ ElementTreeData* pOldElement = getStoredElement(aName);
+ if (pOldElement)
+ {
+ OSL_ASSERT(pOldElement->isValid());
+ detach(*pOldElement);
+ m_bChanged = true;
+ m_bDefault = false;
+ }
+ else // just clear things out
+ {
+ m_aChangedData.removeElement(aName);
+ }
+
+ OSL_ENSURE(pOldElement || pAddedElement,"WARNING: Element being removed was not found in set");
+}
+//-----------------------------------------------------------------------------
+
+SetElementChangeImpl* DeferredSetNodeImpl::doAdjustChangedElement(NodeChangesInformation& rLocalChanges, rtl::OUString const& aName, Change const& aChange)
+{
+ if (ElementTreeData* pLocalElement = m_aChangedData.getElement(aName))
+ {
+ if (ElementTreeData* pElement = getStoredElement(aName))
+ {
+ OSL_ASSERT(pElement->isValid());
+
+ if (SubtreeChange const * subtreeChange = dynamic_cast< SubtreeChange const * >(&aChange))
+ {
+ // recurse to element tree - but do not notify those changes (?)
+ Tree * elementTree = pElement->get();
+
+ NodeChangesInformation aIgnoredChanges;
+ view::getViewBehavior(elementTree)->adjustToChanges(aIgnoredChanges, view::getRootNode(elementTree), *subtreeChange);
+ }
+ else
+ {
+ OSL_ENSURE(dynamic_cast<ValueChange const * >(&aChange) != 0, "Unexpected kind of change to value set element" );
+ //OSL_ENSURE( containsValues(), "Unexpected kind of change: Value change applied to tree set element" );
+ }
+
+ }
+ else
+ {
+ // could be changed to do an insert instead (?)
+ OSL_ENSURE( false, "Changed Element didn't exist before it was removed/replaced" );
+ }
+
+ if (pLocalElement->isValid())
+ {
+ // we have a complete replacement for the changed node
+ ElementTreeData aLocalElement = *pLocalElement;
+
+ // also signal something happened
+ return implCreateReplace(aName,aLocalElement,aLocalElement);
+ }
+ else
+ {
+ // already removed locally - should be notified by different route (if applicable)
+ return NULL;
+ }
+ }
+ else
+ {
+ return SetNodeImpl::doAdjustChangedElement( rLocalChanges,aName,aChange);
+ }
+}
+//-----------------------------------------------------------------------------
+
+SetElementChangeImpl* DeferredSetNodeImpl::doAdjustToAddedElement(rtl::OUString const& aName, AddNode const& aAddNodeChange, ElementTreeData const& aNewElement)
+{
+ m_bDefault = false;
+ if (ElementTreeData* pLocalElement = m_aChangedData.getElement(aName))
+ {
+ // We have another element replacing ours - what do we do ?
+ if (hasStoredElement(aName))
+ {
+ OSL_ENSURE( aAddNodeChange.isReplacing(), "Added Element already exists - replacing" );
+
+ this->replaceElement(aName,aNewElement);
+ }
+ else
+ {
+ OSL_ENSURE( !aAddNodeChange.isReplacing(), "Replaced Element doesn't exist - simply adding" );
+ this->insertElement(aName,aNewElement);
+ }
+
+
+ if (pLocalElement->isValid()) // ours remains a valid replacement
+ {
+ ElementTreeData aLocalElement = *pLocalElement;
+
+ // just signal something happened
+ return implCreateReplace(aName,aLocalElement,aLocalElement);
+ }
+ else // had been removed locally
+ {
+ // signal what happened
+ return implCreateInsert(aName,aNewElement);
+ }
+ }
+ else
+ {
+ return SetNodeImpl::implAdjustToAddedElement(aName,aNewElement,aAddNodeChange.isReplacing());
+ }
+}
+//-----------------------------------------------------------------------------
+
+SetElementChangeImpl* DeferredSetNodeImpl::doAdjustToRemovedElement(rtl::OUString const& aName, RemoveNode const& /*aRemoveNodeChange*/)
+{
+ m_bDefault = false;
+ if (ElementTreeData* pLocalElement = m_aChangedData.getElement(aName))
+ {
+ if (hasStoredElement(aName))
+ {
+ // take away the original
+ this->removeElement(aName);
+ }
+
+ if (pLocalElement->isValid()) // remains a valid replacement
+ {
+ ElementTreeData aLocalElement = *pLocalElement;
+
+ // signal something happened
+ return implCreateReplace(aName,aLocalElement,aLocalElement);
+ }
+ else // already was removed locally
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return SetNodeImpl::implAdjustToRemovedElement(aName);
+ }
+}
+//-----------------------------------------------------------------------------
+
+void DeferredSetNodeImpl::doDifferenceToDefaultState(SubtreeChange& _rChangeToDefault, ISubtree& _rDefaultTree)
+{
+ if (!m_bDefault)
+ {
+ implDifferenceToDefaultState(_rChangeToDefault,_rDefaultTree);
+
+ ElementSet::Data::const_iterator it = m_aChangedData.beginNative();
+ ElementSet::Data::const_iterator const stop = m_aChangedData.endNative();
+
+ while(it != stop)
+ {
+ rtl::OUString aName = it->first;
+ ElementTreeData aElement = it->second;
+
+ Change* pChange = _rChangeToDefault.getChange( aName );
+ OSL_ENSURE(pChange == NULL || dynamic_cast< AddNode * >(pChange) != 0 || dynamic_cast< RemoveNode * >(pChange) != 0,
+ "Unexpected change type found in difference to default tree");
+
+ if (pChange == NULL)
+ {
+ std::auto_ptr<INode> aDefaultNode = _rDefaultTree.removeChild(aName);
+ OSL_ENSURE( aDefaultNode.get(), "Error: unused Default tree not found after SetNodeImpl::implDifferenceToDefaultState");
+
+ rtl::OUString aElementTypeName = _rDefaultTree.getElementTemplateName();
+ OSL_ENSURE( _rDefaultTree.isSetNode(), "Error: missing set template information in default data");
+
+ rtl::Reference< data::TreeSegment > aDefaultTree = data::TreeSegment::create(aDefaultNode,aElementTypeName);
+ OSL_ENSURE(aDefaultTree.is(), "Error: unused Default tree not accessible after SetNodeImpl::implDifferenceToDefaultState");
+
+ AddNode* pAddIt = new AddNode(aDefaultTree, aName, true );
+
+ std::auto_ptr<Change> pNewChange( pAddIt );
+
+ if (aElement.isValid())
+ {
+ OSL_ENSURE(!aElement.inDefault, "Default element replaced by default");
+ pAddIt->setReplacing();
+ }
+
+ _rChangeToDefault.addChange(pNewChange);
+
+ }
+ else if (AddNode * addNode = dynamic_cast< AddNode * >(pChange))
+ {
+ // adjust the AddNode - remove the original expected node
+ addNode->clearReplacedTree();
+
+ if (aElement.isValid())
+ {
+ if (aElement.inDefault)
+ {
+ // change already done locally
+ _rChangeToDefault.removeChange(aName);
+ }
+ else // adjust here
+ addNode->setReplacing();
+ }
+
+ else
+ OSL_ENSURE(!addNode->isReplacing(),"Could not unmark the 'replacing' state of an AddNode");
+ }
+ else if (RemoveNode * removeNode = dynamic_cast< RemoveNode * >(pChange))
+ {
+ if (aElement.isValid())
+ {
+ OSL_ENSURE(!aElement.inDefault, "Default element replaced by default");
+ // adjust the RemoveNode - remove the original expected node
+ removeNode->clearRemovedTree();
+ }
+ else
+ {
+ // change already done locally
+ _rChangeToDefault.removeChange(aName);
+ }
+ // TODO: mark local removal as to-default
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/treemgr/nodeimplobj.hxx b/configmgr/source/treemgr/nodeimplobj.hxx
new file mode 100644
index 000000000000..bf488be9b56e
--- /dev/null
+++ b/configmgr/source/treemgr/nodeimplobj.hxx
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: nodeimplobj.hxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_NODEIMPLOBJECTS_HXX_
+#define CONFIGMGR_NODEIMPLOBJECTS_HXX_
+
+#include "sal/config.h"
+
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "node.hxx"
+#include "nodeimpl.hxx"
+#include "groupnodeimpl.hxx"
+#include "setnodeimpl.hxx"
+#include "valuenodeimpl.hxx"
+#include "utility.hxx"
+
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+// Specific types of nodes for direct or read only access
+//-----------------------------------------------------------------------------
+
+// Value Nodes
+//-----------------------------------------------------------------------------
+
+ class ValueMemberNode::DeferredImpl : public salhelper::SimpleReferenceObject
+ {
+ sharable::ValueNode * m_valueNode;
+
+ com::sun::star::uno::Any m_aNewValue;
+ bool m_bToDefault;
+ bool m_bChange;
+ public:
+ explicit DeferredImpl(sharable::ValueNode * valueNode);
+
+ /// does this wrap a change
+ bool isChange() const { return m_bChange; }
+
+ /// retrieve the underlying (original) node
+ sharable::ValueNode * getOriginalNode() const
+ { return m_valueNode; }
+
+ /// Does this node change to default
+ bool isToDefault() const { return m_bToDefault; }
+
+ /// retrieve the current value of this node
+ com::sun::star::uno::Any getNewValue() const { return m_aNewValue; }
+
+ /// Set this node to a new value
+ void setValue(com::sun::star::uno::Any const& aNewValue, sharable::ValueNode * originalNode);
+
+ /// Set this node to assume its default value
+ void setValueToDefault(sharable::ValueNode * originalNode);
+
+ public:
+ // commit protocol
+ std::auto_ptr<ValueChange> preCommitChange();
+ void finishCommit(ValueChange& rChange);
+ void revertCommit(ValueChange& rChange);
+ void failedCommit(ValueChange& rChange);
+
+ ValueChangeImpl* collectChange();
+ ValueChangeImpl* adjustToChange(ValueChange const& rExternalChange);
+
+ // notification protocol
+ void adjustToChange(NodeChangesInformation& rLocalChange, ValueChange const& rExternalChange, Tree& rParentTree, unsigned int nParentPos, rtl::OUString const& aName);
+ };
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+
+// Group Nodes
+//-----------------------------------------------------------------------------
+
+ class DeferredGroupNodeImpl : public GroupNodeImpl
+ {
+ public:
+ explicit
+ DeferredGroupNodeImpl(sharable::GroupNode * const& _aNodeRef);
+ explicit
+ DeferredGroupNodeImpl(sharable::GroupNode * const& _aNewAddress, GroupNodeImpl& rOriginal);
+
+ ~DeferredGroupNodeImpl();
+
+ public:
+ // commit protocol
+ std::auto_ptr<SubtreeChange> preCommitValueChanges();
+ void finishCommit(SubtreeChange& rChange);
+ void revertCommit(SubtreeChange& rChange);
+ void failedCommit(SubtreeChange& rChange);
+
+ void collectValueChanges(NodeChanges& rChanges, Tree* pParent, unsigned int nNode) const;
+
+ public:
+ // data access
+ bool hasChanges() const;
+ void markChanged();
+
+ rtl::Reference<ValueMemberNode::DeferredImpl> findValueChange(rtl::OUString const& aName);
+
+ using GroupNodeImpl::makeValueMember;
+ ValueMemberNode makeValueMember(rtl::OUString const& _aName, bool _bForUpdate);
+
+ private:
+ typedef std::map< rtl::OUString, rtl::Reference<ValueMemberNode::DeferredImpl> > MemberChanges;
+
+ MemberChanges m_aChanges;
+ };
+//-----------------------------------------------------------------------------
+
+// Set nodes
+//-----------------------------------------------------------------------------
+
+ class DeferredSetNodeImpl : public SetNodeImpl
+ {
+ public:
+ explicit
+ DeferredSetNodeImpl(sharable::SetNode * const& _aNodeRef, Template* pTemplate);
+
+ public:
+ bool hasChanges() const;
+ void markChanged();
+ void collectElementChanges(NodeChanges& rChanges) const;
+
+ public:
+ std::auto_ptr<SubtreeChange> preCommitChanges(std::vector< rtl::Reference<ElementTree> >& _rRemovedElements);
+ void failedCommit(SubtreeChange& rChanges);
+ void finishCommit(SubtreeChange& rChanges);
+ void revertCommit(SubtreeChange& rChanges);
+
+ void insertNewElement(rtl::OUString const& aName, ElementTreeData const& aNewElement);
+ void removeOldElement(rtl::OUString const& aName);
+ // Base Overrideables
+ private:
+ // NodeImpl implementation
+ virtual bool doIsEmpty() const;
+ virtual ElementTree* doFindElement(rtl::OUString const& aName) ;
+ virtual SetNodeVisitor::Result doDispatchToElements(SetNodeVisitor& aVisitor);
+
+ virtual void doDifferenceToDefaultState(SubtreeChange& _rChangeToDefault, ISubtree& _rDefaultTree);
+
+ virtual SetElementChangeImpl* doAdjustToAddedElement(rtl::OUString const& aName, AddNode const& aAddNodeChange, ElementTreeData const & aNewElement);
+ virtual SetElementChangeImpl* doAdjustToRemovedElement(rtl::OUString const& aName, RemoveNode const& aRemoveNodeChange);
+
+ virtual SetElementChangeImpl* doAdjustChangedElement(NodeChangesInformation& rLocalChanges, rtl::OUString const& aName, Change const& aChange);
+
+ virtual void doTransferElements(ElementSet& rReplacement);
+
+ // Implementation
+ private:
+ void rebuildElement(rtl::OUString const& aName, ElementTreeData const& _aElement);
+
+ private:
+ ElementSet m_aChangedData;
+ bool m_bChanged;
+ bool m_bDefault;
+ };
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_NODEIMPLOBJECTS_HXX_
diff --git a/configmgr/source/treemgr/noderef.cxx b/configmgr/source/treemgr/noderef.cxx
new file mode 100644
index 000000000000..330eab07aea5
--- /dev/null
+++ b/configmgr/source/treemgr/noderef.cxx
@@ -0,0 +1,920 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: noderef.cxx,v $
+ * $Revision: 1.34 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "anynoderef.hxx"
+#include "valueref.hxx"
+#include "noderef.hxx"
+#include "tree.hxx"
+#include "viewaccess.hxx"
+#include "configpath.hxx"
+#include "nodechange.hxx"
+#include "configexcept.hxx"
+#include "configset.hxx"
+#include "tracer.hxx"
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm> // for swap
+#define INCLUDED_ALGORITHM
+#endif
+#ifndef INCLUDED_FUNCTIONAL
+#include <functional> // for less
+#define INCLUDED_FUNCTIONAL
+#endif
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+// local helpers
+//-----------------------------------------------------------------------------
+
+namespace
+{
+//-----------------------------------------------------------------------------
+ struct CollectValueIDs : GroupMemberVisitor
+ {
+ CollectValueIDs(NodeID const& aParentID, std::vector<SubNodeID>& rValueList)
+ : m_aParentID(aParentID)
+ , m_rValueList(rValueList)
+ {
+ }
+
+ Result visit(ValueMemberNode const& anEntry);
+
+ NodeID m_aParentID;
+ std::vector<SubNodeID>& m_rValueList;
+ };
+
+ GroupMemberVisitor::Result CollectValueIDs::visit(ValueMemberNode const& aValue)
+ {
+ OSL_ASSERT(aValue.isValid());
+
+ rtl::OUString aValueName = aValue.getNodeName();
+
+ m_rValueList.push_back(SubNodeID( m_aParentID, aValueName));
+
+ return CONTINUE;
+ }
+//-----------------------------------------------------------------------------
+}
+
+//-----------------------------------------------------------------------------
+// class NodeRef
+//-----------------------------------------------------------------------------
+
+NodeRef::NodeRef()
+: m_nPos(0)
+, m_nDepth(0)
+{
+}
+//-----------------------------------------------------------------------------
+
+NodeRef::NodeRef(unsigned int nPos, unsigned int nDepth)
+: m_nPos(nPos)
+, m_nDepth(nDepth)
+{}
+//-----------------------------------------------------------------------------
+
+NodeRef::NodeRef(NodeRef const& rOther)
+: m_nPos(rOther.m_nPos)
+, m_nDepth(rOther.m_nDepth)
+{
+}
+//-----------------------------------------------------------------------------
+
+NodeRef& NodeRef::operator=(NodeRef const& rOther)
+{
+ NodeRef(rOther).swap(*this);
+ return *this;
+}
+//-----------------------------------------------------------------------------
+
+void NodeRef::swap(NodeRef& rOther)
+{
+ std::swap(m_nPos, rOther.m_nPos);
+ std::swap(m_nDepth, rOther.m_nDepth);
+}
+//-----------------------------------------------------------------------------
+
+NodeRef::~NodeRef()
+{
+}
+
+//-----------------------------------------------------------------------------
+// class ValueRef
+//-----------------------------------------------------------------------------
+
+bool ValueRef::checkValidState() const
+{
+ if (m_nParentPos == 0) return false;
+
+ // old node semantics for now
+ if ( m_sNodeName.getLength() == 0 ) return false;
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+ValueRef::ValueRef()
+: m_sNodeName()
+, m_nParentPos(0)
+{
+}
+//-----------------------------------------------------------------------------
+
+ValueRef::ValueRef(rtl::OUString const& aName, unsigned int nParentPos)
+: m_sNodeName(aName)
+, m_nParentPos(nParentPos)
+{
+ OSL_ENSURE( nParentPos == 0 || checkValidState(), "Constructing invalid ValueRef");
+}
+//-----------------------------------------------------------------------------
+
+ValueRef::ValueRef(ValueRef const& rOther)
+: m_sNodeName(rOther.m_sNodeName)
+, m_nParentPos(rOther.m_nParentPos)
+{
+}
+//-----------------------------------------------------------------------------
+
+ValueRef& ValueRef::operator=(ValueRef const& rOther)
+{
+ ValueRef(rOther).swap(*this);
+ return *this;
+}
+//-----------------------------------------------------------------------------
+
+void ValueRef::swap(ValueRef& rOther)
+{
+ std::swap(m_sNodeName, rOther.m_sNodeName);
+ std::swap(m_nParentPos, rOther.m_nParentPos);
+}
+//-----------------------------------------------------------------------------
+
+ValueRef::~ValueRef()
+{
+}
+
+//-----------------------------------------------------------------------------
+// class AnyNodeRef
+//-----------------------------------------------------------------------------
+#if OSL_DEBUG_LEVEL > 0
+bool AnyNodeRef::checkValidState() const
+{
+ if (m_nUsedPos == 0) return false;
+
+ if ( m_sNodeName.getLength() != 0 ) // it's a local value
+ {
+ // not used as runtime check as it should not be dangerous
+ OSL_ENSURE(m_nDepth ==0, "AnyNodeRef that wraps a ValueRef should have no depth"); // value has no depth
+ }
+
+ return true;
+}
+#endif
+//-----------------------------------------------------------------------------
+
+AnyNodeRef::AnyNodeRef()
+: m_sNodeName()
+, m_nUsedPos(0)
+, m_nDepth(0)
+{
+}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef::AnyNodeRef(unsigned int nPos, unsigned int nDepth)
+: m_sNodeName()
+, m_nUsedPos(nPos)
+, m_nDepth(nDepth)
+{}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef::AnyNodeRef(rtl::OUString const& aName, unsigned int nParentPos)
+: m_sNodeName(aName)
+, m_nUsedPos(nParentPos)
+, m_nDepth(0)
+{}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef::AnyNodeRef(AnyNodeRef const& rOther)
+: m_sNodeName(rOther.m_sNodeName)
+, m_nUsedPos(rOther.m_nUsedPos)
+, m_nDepth(rOther.m_nDepth)
+{
+}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef::AnyNodeRef(NodeRef const& aNodeRef)
+: m_sNodeName()
+, m_nUsedPos( aNodeRef.m_nPos )
+, m_nDepth( aNodeRef.m_nDepth )
+{}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef::AnyNodeRef(ValueRef const& aValueRef)
+: m_sNodeName( aValueRef.m_sNodeName )
+, m_nUsedPos( aValueRef.m_nParentPos )
+, m_nDepth( 0 )
+{}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef& AnyNodeRef::operator=(AnyNodeRef const& rOther)
+{
+ AnyNodeRef(rOther).swap(*this);
+ return *this;
+}
+//-----------------------------------------------------------------------------
+
+void AnyNodeRef::swap(AnyNodeRef& rOther)
+{
+ std::swap(m_sNodeName, rOther.m_sNodeName);
+ std::swap(m_nUsedPos, rOther.m_nUsedPos);
+ std::swap(m_nDepth, rOther.m_nDepth);
+}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef::~AnyNodeRef()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+bool AnyNodeRef::isNode() const
+{
+ OSL_PRECOND( isValid(), "ERROR: Configuration: AnyNodeRef operation requires valid node" );
+ if (!isValid()) return false;
+
+ return m_sNodeName.getLength() == 0;
+}
+//-----------------------------------------------------------------------------
+
+NodeRef AnyNodeRef::toNode() const
+{
+ OSL_PRECOND( isValid(), "ERROR: Configuration: AnyNodeRef operation requires valid node" );
+ if (!isValid() || !isNode()) return NodeRef();
+
+ return NodeRef(m_nUsedPos,m_nDepth);
+}
+//-----------------------------------------------------------------------------
+
+ValueRef AnyNodeRef::toValue() const
+{
+ OSL_PRECOND( isValid(), "ERROR: Configuration: AnyNodeRef operation requires valid node" );
+ if (!isValid() || isNode()) return ValueRef();
+
+ return ValueRef(m_sNodeName, m_nUsedPos);
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// hashing any pointer
+//-----------------------------------------------------------------------------
+static // for now
+// should move this to a more public place sometime
+// need this, as STLPORT does not hash sal_(u)Int64 (at least on MSVC)
+inline
+size_t hash64(sal_uInt64 n)
+{
+ // simple solution (but the same that STLPORT uses for unsigned long long (if enabled))
+ return static_cast<size_t>(n);
+}
+//-----------------------------------------------------------------------------
+
+static // for now
+// should move this to a more public place sometime
+inline
+size_t hashAnyPointer(void* p)
+{
+ // most portable quick solution IMHO (we need this cast for UNO tunnels anyway)
+ sal_uInt64 n = reinterpret_cast<sal_uInt64>(p);
+
+ return hash64(n);
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class NodeID
+//-----------------------------------------------------------------------------
+
+NodeID::NodeID(rtl::Reference< Tree > const& rTree, NodeRef const& rNode)
+: m_pTree( rTree.get() )
+, m_nNode( rNode.getOffset() )
+{
+}
+//-----------------------------------------------------------------------------
+
+NodeID::NodeID(Tree* pImpl, unsigned int nNode)
+: m_pTree( pImpl )
+, m_nNode( nNode )
+{
+}
+//-----------------------------------------------------------------------------
+
+bool NodeID::isEmpty() const
+{
+ OSL_ENSURE( m_pTree == NULL || m_pTree->isValidNode(m_nNode), "Node does not match tree in NodeID");
+ return m_pTree == NULL;
+}
+//-----------------------------------------------------------------------------
+
+bool NodeID::isValidNode() const
+{
+ return m_pTree != NULL && m_pTree->isValidNode(m_nNode);
+}
+//-----------------------------------------------------------------------------
+
+// hashing
+size_t NodeID::hashCode() const
+{
+ return hashAnyPointer(m_pTree) + 5*m_nNode;
+}
+//-----------------------------------------------------------------------------
+
+unsigned int NodeID::toIndex() const
+{
+ unsigned int n = m_nNode;
+ if (m_pTree)
+ {
+ OSL_ENSURE(m_pTree->isValidNode(n),"Cannot produce valid Index for NodeID");
+
+ n -= Tree::ROOT;
+ }
+ return n;
+}
+
+NodeRef NodeID::getNode() const {
+ return m_pTree == 0 ? NodeRef() : m_pTree->getNode(m_nNode);
+}
+
+//-----------------------------------------------------------------------------
+bool operator < (NodeID const& lhs, NodeID const& rhs)
+{
+ if (lhs.m_pTree == rhs.m_pTree)
+ return lhs.m_nNode < rhs.m_nNode;
+ else
+ return std::less<Tree*>()(lhs.m_pTree,rhs.m_pTree);
+}
+
+//-----------------------------------------------------------------------------
+// class SubNodeID
+//-----------------------------------------------------------------------------
+
+SubNodeID::SubNodeID()
+: m_sNodeName()
+, m_aParentID(0,0)
+{
+}
+//-----------------------------------------------------------------------------
+
+SubNodeID::SubNodeID(rtl::Reference< Tree > const& rTree, NodeRef const& rParentNode, rtl::OUString const& aName)
+: m_sNodeName(aName)
+, m_aParentID(rTree,rParentNode)
+{
+}
+//-----------------------------------------------------------------------------
+
+SubNodeID::SubNodeID(NodeID const& rParentNodeID, rtl::OUString const& aName)
+: m_sNodeName(aName)
+, m_aParentID(rParentNodeID)
+{
+}
+//-----------------------------------------------------------------------------
+
+bool SubNodeID::isValidNode() const
+{
+ if (!m_aParentID.isValidNode()) return false;
+
+ OSL_ENSURE(m_sNodeName.getLength() != 0,"Invalid subnode ID: Missing name");
+
+ rtl::Reference< Tree > aCheck( m_aParentID.getTree() );
+ return aCheck->hasChild( m_aParentID.getNode(), m_sNodeName );
+}
+//-----------------------------------------------------------------------------
+
+bool operator < (SubNodeID const& lhs, SubNodeID const& rhs)
+{
+ if (lhs.m_aParentID == rhs.m_aParentID)
+ return !!(lhs.m_sNodeName < rhs.m_sNodeName);
+ else
+ return lhs.m_aParentID < rhs.m_aParentID;
+}
+
+//-----------------------------------------------------------------------------
+// Free functions
+//-----------------------------------------------------------------------------
+
+rtl::OUString validateElementName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode )
+{
+ { (void)aTree; (void)aNode; }
+ OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
+ OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
+
+ OSL_PRECOND( view::ViewTreeAccess(aTree.get()).isSetNode(aNode), "ERROR: Configuration: Set node expected.");
+
+ return validateElementName(sName);
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString validateChildName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode )
+{
+ { (void)aTree; (void)aNode; }
+ OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
+ OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
+
+ OSL_PRECOND( view::ViewTreeAccess(aTree.get()).isGroupNode(aNode), "ERROR: Configuration: Group node expected.");
+
+ return validateNodeName(sName);
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString validateChildOrElementName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode )
+{
+ OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
+ OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
+
+ OSL_PRECOND( isStructuralNode(aTree,aNode), "ERROR: Configuration: Inner node expected.");
+
+ if (view::ViewTreeAccess(aTree.get()).isSetNode(aNode))
+ return validateElementName(sName);
+
+ else
+ return validateNodeName(sName);
+}
+//-----------------------------------------------------------------------------
+
+Path::Component validateElementPathComponent(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode )
+{
+ rtl::OUString aElementName = validateElementName(sName,aTree,aNode);
+
+ rtl::Reference<Template> aTemplate = aTree->extractElementInfo(aNode);
+ if (aTemplate.is())
+ {
+ return Path::makeCompositeName( aElementName, aTemplate->getName() );
+ }
+ else
+ {
+ OSL_ENSURE(false, "WARNING: Cannot find element type information for building an element name");
+ return Path::wrapElementName(aElementName);
+ }
+}
+//-----------------------------------------------------------------------------
+
+static void implValidateLocalPath(RelativePath& _rPath, rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ if (_rPath.isEmpty())
+ throw InvalidName(_rPath.toString(), "is an empty path.");
+
+ // FOR NOW: validate only the first component
+ if (!view::ViewTreeAccess(aTree.get()).isSetNode(aNode))
+ if (!_rPath.getFirstName().isSimpleName())
+ throw InvalidName(_rPath.toString(), "is not valid in this context. Predicate expression used to select group member.");
+}
+//-----------------------------------------------------------------------------
+
+RelativePath validateRelativePath(rtl::OUString const& _sPath, rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
+ OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
+
+ OSL_PRECOND( isStructuralNode(aTree,aNode), "ERROR: Configuration: Inner node expected.");
+
+ if ( Path::isAbsolutePath(_sPath) )
+ {
+ OSL_ENSURE(false, "Absolute pathes are not allowed here (compatibility support enabled");
+ return validateAndReducePath(_sPath,aTree,aNode);
+ }
+
+ RelativePath aResult = RelativePath::parse(_sPath);
+
+ implValidateLocalPath(aResult,aTree,aNode);
+
+ return aResult;
+}
+//-----------------------------------------------------------------------------
+
+RelativePath validateAndReducePath(rtl::OUString const& _sPath, rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
+ OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
+
+ OSL_PRECOND( isStructuralNode(aTree,aNode), "ERROR: Configuration: Inner node expected.");
+
+ if ( !Path::isAbsolutePath(_sPath) )
+ return validateRelativePath(_sPath,aTree,aNode);
+
+ AbsolutePath aInputPath = AbsolutePath::parse(_sPath);
+
+ RelativePath aStrippedPath = Path::stripPrefix( aInputPath, aTree->getAbsolutePath(aNode) );
+
+ implValidateLocalPath(aStrippedPath,aTree,aNode);
+
+ return aStrippedPath;
+}
+//-----------------------------------------------------------------------------
+
+bool hasChildOrElement(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, rtl::OUString const& aName)
+{
+ return view::ViewTreeAccess(aTree.get()).isSetNode(aNode) ? aTree->hasElement(aNode,aName) : aTree->hasChild(aNode,aName);
+}
+//-----------------------------------------------------------------------------
+
+bool hasChildOrElement(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, Path::Component const& aName)
+{
+ return view::ViewTreeAccess(aTree.get()).isSetNode(aNode) ? aTree->hasElement(aNode,aName) : aTree->hasChild(aNode,aName.getName());
+}
+//-----------------------------------------------------------------------------
+
+bool findInnerChildOrAvailableElement(rtl::Reference< Tree > & aTree, NodeRef& aNode, rtl::OUString const& aName)
+{
+ if ( view::ViewTreeAccess(aTree.get()).isSetNode(aNode) )
+ {
+ rtl::Reference< ElementTree > aElement = aTree->getAvailableElement(aNode,aName);
+ if (aElement.is())
+ {
+ aTree = aElement.get();
+ aNode = aTree->getRootNode();
+ return true;
+ }
+ }
+ else
+ {
+ NodeRef aChild = aTree->getChildNode(aNode,aName);
+
+ if ( aChild.isValid() )
+ {
+ aNode = aChild;
+ return true;
+ }
+ }
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef getChildOrElement(rtl::Reference< Tree > & aTree, NodeRef const& aParentNode, rtl::OUString const& aName)
+{
+ if (aTree->hasChildValue(aParentNode,aName))
+ {
+ return AnyNodeRef(aTree->getChildValue(aParentNode,aName));
+ }
+
+ else if ( view::ViewTreeAccess(aTree.get()).isSetNode(aParentNode) )
+ {
+ rtl::Reference< ElementTree > aElement = aTree->getElement(aParentNode,aName);
+ if (aElement.is())
+ {
+ aTree = aElement.get();
+ return AnyNodeRef(aTree->getRootNode());
+ }
+ }
+
+ else
+ {
+ NodeRef aChild = aTree->getChildNode(aParentNode,aName);
+
+ if ( aChild.isValid() )
+ {
+ return AnyNodeRef(aChild);
+ }
+ }
+
+ return AnyNodeRef();
+}
+//-----------------------------------------------------------------------------
+
+static
+inline
+bool findLocalInnerChild(rtl::Reference< Tree > const& aTree, NodeRef& aNode, Path::Component const& aName)
+{
+ NodeRef aChild = aTree->getChildNode(aNode,aName.getName());
+
+ if ( !aChild.isValid() ) return false;
+
+ OSL_ENSURE( aName.isSimpleName(), "Child of group was found by request using element name format -failing");
+ if ( !aName.isSimpleName()) return false;
+
+ aNode = aChild;
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+static
+inline
+bool findElement(rtl::Reference< Tree > & aTree, NodeRef& aNode, Path::Component const& aName)
+{
+ rtl::Reference< ElementTree > aElement = aTree->getElement(aNode,aName.getName());
+
+ if (!aElement.is()) return false;
+
+ rtl::Reference< Tree > aFoundTree = aElement.get();
+
+ OSL_ENSURE(matches(aFoundTree->getExtendedRootName(),aName), "Element found, but type prefix does not match - failing");
+ if ( !matches(aFoundTree->getExtendedRootName(),aName) ) return false;
+
+ aTree = aFoundTree;
+ aNode = aTree->getRootNode();
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+static
+bool findLocalInnerDescendant(rtl::Reference< Tree > const& aTree, NodeRef& aNode, RelativePath& rPath)
+{
+ while ( !rPath.isEmpty() )
+ {
+ if ( view::ViewTreeAccess(aTree.get()).isSetNode(aNode) ) return false;
+
+ if ( ! findLocalInnerChild(aTree,aNode,rPath.getFirstName()) ) return false;
+
+ rPath.dropFirstName();
+ }
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+static
+bool findDeepInnerDescendant(rtl::Reference< Tree > & aTree, NodeRef& aNode, RelativePath& rPath)
+{
+ while ( !rPath.isEmpty() )
+ {
+ if ( view::ViewTreeAccess(aTree.get()).isSetNode(aNode) )
+ {
+ if ( ! findElement(aTree,aNode,rPath.getFirstName()) ) return false;
+ }
+ else
+ {
+ if ( ! findLocalInnerChild(aTree,aNode,rPath.getFirstName()) ) return false;
+ }
+
+ rPath.dropFirstName();
+ }
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+static
+inline
+bool identifiesLocalValue(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, RelativePath const& aPath)
+{
+ if ( aPath.getDepth() == 1 )
+ {
+ Path::Component const & aLocalName = aPath.getLocalName();
+ rtl::OUString aName = aLocalName.getName();
+
+ if (aTree->hasChildValue(aNode,aName))
+ {
+ OSL_ENSURE( aLocalName.isSimpleName(), "Value in group was found by request using element name format");
+ if ( aLocalName.isSimpleName())
+ return true;
+ }
+ }
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef getLocalDescendant(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, RelativePath const& rPath)
+{
+ NodeRef aNestedNode( aNode );
+ RelativePath aRemainingPath(rPath);
+
+ if ( findLocalInnerDescendant(aTree,aNestedNode,aRemainingPath) )
+ {
+ OSL_ASSERT(
+ aNestedNode.isValid() &&
+ aTree->isValidNode(aNestedNode.getOffset()));
+ return AnyNodeRef(aNestedNode);
+ }
+
+ if ( identifiesLocalValue(aTree,aNestedNode,aRemainingPath) )
+ {
+ ValueRef aValue = aTree->getChildValue(aNestedNode,rPath.getLocalName().getName());
+ OSL_ASSERT(aTree->isValidValueNode(aValue));
+ return AnyNodeRef(aValue);
+ }
+
+ return AnyNodeRef();
+}
+//-----------------------------------------------------------------------------
+
+AnyNodeRef getDeepDescendant(rtl::Reference< Tree > & aTree, NodeRef& aNode, RelativePath& rPath)
+{
+ if ( findDeepInnerDescendant(aTree,aNode,rPath) )
+ {
+ OSL_ASSERT(
+ aNode.isValid() && aTree->isValidNode(aNode.getOffset()));
+ return AnyNodeRef(aNode);
+ }
+
+ if ( identifiesLocalValue(aTree,aNode,rPath) )
+ {
+ ValueRef aValue = aTree->getChildValue(aNode,rPath.getLocalName().getName());
+ OSL_ASSERT(aTree->isValidValueNode(aValue));
+ return AnyNodeRef(aValue);
+ }
+
+ return AnyNodeRef();
+}
+//-----------------------------------------------------------------------------
+
+void getAllContainedNodes(rtl::Reference< Tree > const& aTree, std::vector<NodeID>& aList)
+{
+ aList.clear();
+
+ if (Tree* pImpl = aTree.get())
+ {
+ unsigned int nCount = pImpl->nodeCount();
+ aList.reserve(nCount);
+
+ unsigned int const nEnd = Tree::ROOT + nCount;
+
+ for(unsigned int nOffset = Tree::ROOT;
+ nOffset < nEnd;
+ ++nOffset)
+ {
+ OSL_ASSERT( pImpl->isValidNode(nOffset) );
+ aList.push_back( NodeID(pImpl,nOffset) );
+ }
+
+ OSL_ASSERT( aList.size()==nCount );
+ }
+}
+//-----------------------------------------------------------------------------
+
+void getAllChildrenHelper(NodeID const& aNode, std::vector<SubNodeID>& aList)
+{
+ aList.clear();
+
+ if (Tree* pTreeImpl = aNode.getTree())
+ {
+ view::ViewTreeAccess aView(pTreeImpl);
+
+ if (unsigned int const nParent = aNode.getOffset())
+ {
+ OSL_ASSERT( pTreeImpl->isValidNode(nParent) );
+
+ if (aView.isGroupNodeAt(nParent))
+ {
+ view::GroupNode aParent = aView.getGroupNodeAt(nParent);
+
+ {
+ CollectValueIDs aCollector(aNode, aList);
+ aView.dispatchToValues(aView.getGroupNodeAt(nParent),aCollector);
+ }
+
+ for(view::Node aChild = aParent.getFirstChild();
+ aChild.is();
+ aChild = aParent.getNextChild(aChild))
+ {
+ OSL_ASSERT( pTreeImpl->isValidNode(aChild.get_offset()) );
+ aList.push_back( SubNodeID( aNode, pTreeImpl->getSimpleNodeName(aChild.get_offset())) );
+ }
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+NodeID findNodeFromIndex(rtl::Reference< Tree > const& aTree, unsigned int nIndex)
+{
+ if (Tree* pImpl = aTree.get())
+ {
+ unsigned int nNode = nIndex + Tree::ROOT;
+ if (pImpl->isValidNode(nNode))
+ {
+ return NodeID(pImpl,nNode);
+ }
+ }
+ return NodeID(0,0);
+}
+
+//-----------------------------------------------------------------------------
+
+static inline bool isRootNode(NodeRef const& aNode)
+{
+ return aNode.getOffset() == Tree::ROOT;
+}
+//-----------------------------------------------------------------------------
+#if OSL_DEBUG_LEVEL > 0
+bool isSimpleValueElement(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ OSL_PRECOND( !aNode.isValid() || !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
+
+ view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
+
+ OSL_ASSERT( !aNode.isValid() ||
+ aView.isGroupNode(aNode) ||
+ aView.isSetNode(aNode) ||
+ (aView.isValueNode(aNode) && isRootNode(aNode)) );
+
+ return aNode.isValid() && isRootNode(aNode) && aView.isValueNode(aNode);
+}
+#endif
+//-----------------------------------------------------------------------------
+
+bool isStructuralNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ OSL_PRECOND( !aNode.isValid() || !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
+
+ view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
+
+ OSL_ASSERT( !aNode.isValid() ||
+ aView.isGroupNode(aNode) ||
+ aView.isSetNode(aNode) ||
+ (aView.isValueNode(aNode) && isRootNode(aNode)) );
+
+ return aNode.isValid() && ! aView.isValueNode(aNode);
+}
+//-----------------------------------------------------------------------------
+
+bool isGroupNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ OSL_PRECOND( !aNode.isValid() || !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
+
+ view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
+
+ OSL_ASSERT( !aNode.isValid() ||
+ aView.isGroupNode(aNode) ||
+ aView.isSetNode(aNode) ||
+ (aView.isValueNode(aNode) && isRootNode(aNode)) );
+
+ return aNode.isValid() && aView.isGroupNode(aNode);
+}
+//-----------------------------------------------------------------------------
+
+bool isSetNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ OSL_PRECOND( !aNode.isValid() || !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
+
+ view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
+
+ OSL_ASSERT( !aNode.isValid() ||
+ aView.isGroupNode(aNode) ||
+ aView.isSetNode(aNode) ||
+ (aView.isValueNode(aNode) && isRootNode(aNode)) );
+
+ return aNode.isValid() && aView.isSetNode(aNode);
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any getSimpleElementValue(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
+{
+ OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid Node");
+ OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
+
+ if (!aNode.isValid()) return com::sun::star::uno::Any();
+
+ OSL_PRECOND( isSimpleValueElement(aTree, aNode), "ERROR: Configuration: Getting value is supported only for value nodes");
+
+ view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
+
+ return aView.getValue(aView.toValueNode(aNode));
+}
+
+//-----------------------------------------------------------------------------
+ } // namespace configuration
+} // namespace configmgr
diff --git a/configmgr/source/treemgr/readonlyview.cxx b/configmgr/source/treemgr/readonlyview.cxx
new file mode 100644
index 000000000000..11060ff80009
--- /dev/null
+++ b/configmgr/source/treemgr/readonlyview.cxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: readonlyview.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "readonlyview.hxx"
+#include "viewfactory.hxx"
+#include "configexcept.hxx"
+
+namespace configmgr
+{
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+void ReadOnlyViewStrategy::failReadOnly() const
+{
+ OSL_ENSURE(false, "Changing operation attempted on read-only node data");
+ throw configuration::ConstraintViolation("INTERNAL ERROR: Trying to update a read-only node");
+}
+
+//-----------------------------------------------------------------------------
+
+bool ReadOnlyViewStrategy::doHasChanges(Node const& ) const
+{
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+void ReadOnlyViewStrategy::doMarkChanged(Node const& )
+{
+ failReadOnly();
+}
+//-----------------------------------------------------------------------------
+
+node::Attributes ReadOnlyViewStrategy::doAdjustAttributes(node::Attributes const& _aAttributes) const
+{
+ node::Attributes aAttributes = _aAttributes;
+ aAttributes.markReadonly();
+ return aAttributes;
+}
+//-----------------------------------------------------------------------------
+
+configuration::ValueMemberNode ReadOnlyViewStrategy::doGetValueMember(GroupNode const& _aNode, rtl::OUString const& _aName, bool _bForUpdate) const
+{
+ if (_bForUpdate) failReadOnly();
+
+ return ViewStrategy::doGetValueMember(_aNode,_aName,_bForUpdate);
+}
+//-----------------------------------------------------------------------------
+
+void ReadOnlyViewStrategy::doInsertElement(SetNode const& , rtl::OUString const& , configuration::SetEntry const& )
+{
+ failReadOnly();
+}
+//-----------------------------------------------------------------------------
+
+void ReadOnlyViewStrategy::doRemoveElement(SetNode const& /*_aNode*/, rtl::OUString const& /*_aName*/)
+{
+ failReadOnly();
+}
+//-----------------------------------------------------------------------------
+
+extern NodeFactory& getReadAccessFactory();
+
+NodeFactory& ReadOnlyViewStrategy::doGetNodeFactory()
+{
+ return getReadAccessFactory();
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+rtl::Reference<ViewStrategy> createReadOnlyStrategy()
+{
+ return new ReadOnlyViewStrategy();
+}
+
+//-----------------------------------------------------------------------------
+
+ }
+}
diff --git a/configmgr/source/treemgr/readonlyview.hxx b/configmgr/source/treemgr/readonlyview.hxx
new file mode 100644
index 000000000000..38a25de00653
--- /dev/null
+++ b/configmgr/source/treemgr/readonlyview.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: readonlyview.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_READONLYVIEW_HXX_
+#define CONFIGMGR_READONLYVIEW_HXX_
+
+#include "viewstrategy.hxx"
+
+
+namespace configmgr
+{
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+// View behavior for direct read-only access
+//-----------------------------------------------------------------------------
+
+ class ReadOnlyViewStrategy : public ViewStrategy
+ {
+ public:
+ explicit
+ ReadOnlyViewStrategy() {}
+
+ protected:
+ // change handling -required
+ virtual bool doHasChanges(Node const& _aNode) const;
+ virtual void doMarkChanged(Node const& _aNode);
+
+ // common attributes
+ virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const;
+
+ // group member access
+ virtual configuration::ValueMemberNode doGetValueMember(GroupNode const& _aNode, rtl::OUString const& _aName, bool _bForUpdate) const;
+
+ // set element access
+ virtual void doInsertElement(SetNode const& _aNode, rtl::OUString const& aName, configuration::SetEntry const& aNewEntry);
+ virtual void doRemoveElement(SetNode const& _aNode, rtl::OUString const& aName);
+
+ virtual NodeFactory& doGetNodeFactory();
+ private:
+ void failReadOnly() const;
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_READONLYVIEW_HXX_
diff --git a/configmgr/source/treemgr/roottree.cxx b/configmgr/source/treemgr/roottree.cxx
new file mode 100644
index 000000000000..c839bc0cdfae
--- /dev/null
+++ b/configmgr/source/treemgr/roottree.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: roottree.cxx,v $
+ * $Revision: 1.21 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+
+#include "roottree.hxx"
+#include "roottreeimpl.hxx"
+#include "viewaccess.hxx"
+#include "viewfactory.hxx"
+#include "noderef.hxx"
+#include "nodechangeinfo.hxx"
+#include "treechangelist.hxx"
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+// factory methods
+//-----------------------------------------------------------------------------
+
+rtl::Reference< Tree > createReadOnlyTree( AbsolutePath const& aRootPath,
+ sharable::Node * cacheNode,
+ unsigned int nDepth,
+ TemplateProvider const& aTemplateProvider)
+{
+ return new RootTree(view::createReadOnlyStrategy(),
+ aRootPath, cacheNode, nDepth,
+ aTemplateProvider
+ );
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< Tree > createUpdatableTree( AbsolutePath const& aRootPath,
+ sharable::Node * cacheNode,
+ unsigned int nDepth,
+ TemplateProvider const& aTemplateProvider)
+{
+ return new RootTree(view::createDeferredChangeStrategy(),
+ aRootPath, cacheNode, nDepth,
+ aTemplateProvider
+ );
+}
+
+//-----------------------------------------------------------------------------
+// update on notify method
+//-----------------------------------------------------------------------------
+bool adjustToChanges( NodeChangesInformation& rLocalChanges,
+ rtl::Reference< Tree > const& aBaseTree, NodeRef const& aBaseNode,
+ SubtreeChange const& aExternalChange)
+{
+ OSL_PRECOND( !isEmpty(aBaseTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
+ OSL_PRECOND( aBaseNode.isValid() && aBaseTree->isValidNode(aBaseNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
+
+ if (!isEmpty(aBaseTree.get()))
+ {
+ OSL_ENSURE(rLocalChanges.empty(), "Should pass empty container to adjustToChanges(...)");
+
+ view::ViewTreeAccess(aBaseTree.get()).adjustToChanges(rLocalChanges, aBaseNode, aExternalChange);
+
+ return !rLocalChanges.empty();
+ }
+ else
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class CommitHelper
+//-----------------------------------------------------------------------------
+struct CommitHelper::Data
+{
+ std::vector< rtl::Reference<ElementTree> > m_aRemovedElements; // filled to keep the elements alive 'till after notification
+};
+
+//-----------------------------------------------------------------------------
+CommitHelper::CommitHelper(rtl::Reference< Tree > const& aTree)
+: m_pData( )
+, m_pTree( aTree.get() )
+{
+ OSL_ENSURE(m_pTree, "INTERNAL ERROR: Unexpected NULL tree in commit helper");
+}
+//-----------------------------------------------------------------------------
+CommitHelper::~CommitHelper()
+{
+}
+
+//-----------------------------------------------------------------------------
+bool CommitHelper::prepareCommit(TreeChangeList& rChangeList)
+{
+ OSL_ENSURE(m_pTree,"ERROR: CommitHelper: Cannot commit without a tree");
+ if (m_pTree == NULL)
+ return false;
+
+ OSL_ENSURE(m_pData.get() == NULL,"ERROR: CommitHelper: Need to reset before reusing");
+ m_pData.reset( new Data() );
+
+ // get and check the changes
+ std::auto_ptr<SubtreeChange> pTreeChange(view::ViewTreeAccess(m_pTree).preCommitChanges(m_pData->m_aRemovedElements));
+ if (pTreeChange.get() == NULL)
+ return false;
+
+ // find the name and path of the change
+ OSL_ENSURE(m_pTree->getSimpleRootName() == pTreeChange->getNodeName(), "ERROR in Commit: Change name mismatch");
+
+ // now fill the TreeChangeList
+ rChangeList.setRootPath( m_pTree->getRootPath() );
+ rChangeList.root.swap( *pTreeChange );
+
+ return true;
+}
+//-----------------------------------------------------------------------------
+
+void CommitHelper::finishCommit(TreeChangeList& rChangeList)
+{
+ OSL_ENSURE(m_pTree,"INTERNAL ERROR: Nothing to finish without a tree");
+
+ // find the name and path of the change
+ AbsolutePath aPath = m_pTree->getRootPath();
+
+ OSL_ENSURE( rChangeList.getRootNodePath().toString() == aPath.toString(), "ERROR: FinishCommit cannot handle rebased changes trees");
+ if ( !matches(rChangeList.getRootNodePath(), aPath) )
+ throw configuration::Exception("INTERNAL ERROR: FinishCommit cannot handle rebased changes trees");
+
+ view::ViewTreeAccess(m_pTree).finishCommit(rChangeList.root);
+}
+//-----------------------------------------------------------------------------
+
+void CommitHelper::failedCommit(TreeChangeList& rChangeList)
+{
+ OSL_ENSURE(m_pTree,"INTERNAL ERROR: Nothing to finish without a tree");
+
+ AbsolutePath aPath = m_pTree->getRootPath();
+
+ OSL_ENSURE( rChangeList.getRootNodePath().toString() == aPath.toString(), "ERROR: FinishCommit cannot handle rebased changes trees");
+ if ( !matches(rChangeList.getRootNodePath(), aPath) )
+ throw configuration::Exception("INTERNAL ERROR: FinishCommit cannot handle rebased changes trees");
+
+ view::ViewTreeAccess(m_pTree).recoverFailedCommit(rChangeList.root);
+}
+//-----------------------------------------------------------------------------
+
+ }
+}
+
diff --git a/configmgr/source/treemgr/roottreeimpl.hxx b/configmgr/source/treemgr/roottreeimpl.hxx
new file mode 100644
index 000000000000..2607da9432af
--- /dev/null
+++ b/configmgr/source/treemgr/roottreeimpl.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: roottreeimpl.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_ROOTTREEIMPL_HXX_
+#define CONFIGMGR_ROOTTREEIMPL_HXX_
+
+#include "tree.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ /** is the Implementation class for class <type>Tree</type>.
+ <p> Holds a list of <type>Node</type> which it allows to access by
+ <type>unsigned int</type> (which is basically a one-based index).
+ </p>
+ <p> Also provides for navigation to the context this tree is located in
+ </p>
+ */
+ class RootTree : public Tree
+ {
+ public:
+ // Construction
+ /// creates a Tree without a parent tree
+ RootTree( rtl::Reference<view::ViewStrategy> const& _xStrategy,
+ AbsolutePath const& aRootPath,
+ sharable::Node * cacheNode, unsigned int nDepth,
+ TemplateProvider const& aTemplateProvider);
+
+ // make it public
+ private:
+ virtual Path::Component doGetRootName() const;
+ virtual void doFinishRootPath(Path::Rep& rPath) const;
+
+ AbsolutePath m_aRootPath;
+ };
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_ROOTTREEIMPL_HXX_
diff --git a/configmgr/source/treemgr/setnodeimpl.cxx b/configmgr/source/treemgr/setnodeimpl.cxx
new file mode 100644
index 000000000000..b8297c271beb
--- /dev/null
+++ b/configmgr/source/treemgr/setnodeimpl.cxx
@@ -0,0 +1,997 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: setnodeimpl.cxx,v $
+ * $Revision: 1.26 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+
+#include "builddata.hxx"
+#include "setnodeimpl.hxx"
+#include "treefragment.hxx"
+#include "viewfactory.hxx"
+#include "configpath.hxx"
+#include "tree.hxx"
+#include "valuenodeimpl.hxx"
+#include "nodechange.hxx"
+#include "nodechangeimpl.hxx"
+#include "nodevisitor.hxx"
+#include "change.hxx"
+#include "viewaccess.hxx"
+#include "nodeconverter.hxx"
+#include "treeactions.hxx"
+#include "treechangefactory.hxx"
+#include "collectchanges.hxx"
+#include <osl/diagnose.h>
+
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-------------------------------------------------------------------------
+// initialization helpers
+//-------------------------------------------------------------------------
+namespace
+{
+ class CollectElementTrees : data::SetVisitor
+ {
+ public:
+ CollectElementTrees(rtl::Reference<view::ViewStrategy> const& _xStrategy,
+ Tree* pParentTree, unsigned int nPos,
+ unsigned int nDepth,
+ rtl::Reference<Template> const& aTemplate,
+ TemplateProvider const& aTemplateProvider)
+ : m_aTemplate(aTemplate)
+ , m_aTemplateProvider(aTemplateProvider)
+ , m_xStrategy(_xStrategy)
+ , m_pParentTree(pParentTree)
+ , m_nPos(nPos)
+ , m_nDepth(nDepth)
+ {
+ OSL_ENSURE(m_aTemplate.is(),"WARNING: Collecting a set without a template");
+ }
+
+ void collect(sharable::SetNode * node)
+ {
+ visitElements(node);
+ }
+
+ ElementTreeData create(sharable::TreeFragment * elementTree)
+ {
+ OSL_ENSURE(collection.empty(),"warning: trying to reuse a full collection");
+
+ collection.resize(1); // make an empty one for case of failure
+ this->visitTree(elementTree);
+
+ OSL_ENSURE(collection.size()==2,"warning: could not create an element");
+ return collection.back();
+ }
+
+ std::vector<ElementTreeData> collection;
+
+ private:
+ using SetVisitor::handle;
+
+ virtual bool handle(sharable::Node * node);
+
+ virtual bool handle(sharable::ValueNode * node);
+
+ virtual bool handle(sharable::TreeFragment * tree);
+
+ void add(sharable::TreeFragment * node);
+
+ rtl::Reference<Template> m_aTemplate;
+ TemplateProvider m_aTemplateProvider;
+ rtl::Reference<view::ViewStrategy> m_xStrategy;
+ Tree* m_pParentTree;
+ unsigned int m_nPos;
+ unsigned int m_nDepth;
+ };
+ //-------------------------------------------------------------------------
+
+ static
+ rtl::OUString validatedName(ElementTreeData const& aTree)
+ {
+ OSL_ENSURE(aTree.isValid(), "INTERNAL ERROR: Unexpected null tree constructed in set node");
+ if (!aTree.isValid()) throw Exception("INTERNAL ERROR: Unexpected null tree in set node");
+
+ OSL_ENSURE(aTree->nodeCount(), "INTERNAL ERROR: Unexpected empty (!) tree constructed in set node");
+ OSL_ENSURE(aTree->isValidNode(Tree::ROOT), "INTERNAL ERROR: Corrupt tree constructed in set node");
+
+ return aTree->getSimpleRootName();
+ }
+ //-------------------------------------------------------------------------
+
+ static
+ bool isInDefault(SetEntry const& _anEntry)
+ {
+ if (!_anEntry.isValid()) return false;
+
+ node::Attributes aAttributes = _anEntry.getTreeView().getRootAttributes();
+
+ bool bReplaced = aAttributes.isReplacedForUser();
+
+ return !bReplaced;
+ }
+ //-------------------------------------------------------------------------
+ bool CollectElementTrees::handle(sharable::ValueNode * node)
+ {
+ if (m_aTemplate.is())
+ {
+ OSL_ENSURE(m_aTemplate->isInstanceTypeKnown(),"ERROR: Template must have a validated type when building a set.");
+ OSL_ENSURE(m_aTemplate->isInstanceValue(),"ERROR: Found a value node in a Complex Template Set");
+
+ if (!m_aTemplate->isInstanceValue())
+ throw Exception("INTERNAL ERROR: Corrupt tree contains a value node within a template-set");
+
+ com::sun::star::uno::Type aValueType = node->getValueType();
+ com::sun::star::uno::Type aExpectedType = m_aTemplate->getInstanceType();
+
+ if (aValueType.getTypeClass() != aExpectedType.getTypeClass() &&
+ aExpectedType.getTypeClass() != uno::TypeClass_ANY &&
+ aValueType.getTypeClass() != uno::TypeClass_VOID)
+ {
+ OSL_ENSURE(false, "WARNING: ValueType of set node does not match the template type");
+ // throw TypeMismatch(aValueType.getTypeName(),aExpectedType.getTypeName(), "INTERNAL ERROR: - Corrupt tree contains mistyped value node within a value-set")));
+ }
+ }
+ return false;
+ }
+ //-------------------------------------------------------------------------
+ bool CollectElementTrees::handle(sharable::Node * node)
+ {
+ (void) node; // avoid warnings
+ OSL_ENSURE(!node->isValue(), "Unexpected: Value-node dispatched to wrong handler");
+ if (m_aTemplate.is())
+ {
+ OSL_ENSURE(m_aTemplate->isInstanceTypeKnown(),"ERROR: Template must have a validated type when building a set.");
+ OSL_ENSURE(!m_aTemplate->isInstanceValue(),"ERROR: Found a non-leaf node in a Value Set");
+
+ if (m_aTemplate->isInstanceValue())
+ throw Exception("INTERNAL ERROR: Corrupt tree contains a non-leaf node within a value-set");
+
+ }
+ return false;
+ }
+ //-------------------------------------------------------------------------
+ bool CollectElementTrees::handle(sharable::TreeFragment * tree)
+ {
+ bool done = visitNode(tree->getRootNode());
+ if (!done) {
+ add(tree);
+ }
+ return done;
+ }
+ //-------------------------------------------------------------------------
+ void CollectElementTrees::add(sharable::TreeFragment * tree)
+ {
+ node::Attributes const aAttributes = tree->getAttributes();
+
+ bool bReadonly = aAttributes.isReadonly();
+ bool bInDefault = !aAttributes.isReplacedForUser();
+
+ rtl::Reference<view::ViewStrategy> xStrategy = !bReadonly ? m_xStrategy : view::createReadOnlyStrategy();
+
+ ElementTree * pNewTree;
+ if (m_pParentTree)
+ pNewTree = new ElementTree(xStrategy, *m_pParentTree, m_nPos, tree, m_nDepth, m_aTemplate, m_aTemplateProvider);
+
+ else
+ pNewTree = new ElementTree(xStrategy, tree, m_nDepth, m_aTemplate, m_aTemplateProvider);
+
+ collection.push_back( ElementTreeData(pNewTree,bInDefault));
+ }
+}
+
+//-------------------------------------------------------------------------
+// class ElementSet
+//-------------------------------------------------------------------------
+
+bool ElementSet::hasElement(rtl::OUString const& aName) const
+{
+ return m_aData.find(aName) != m_aData.end();
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData* ElementSet::getElement(rtl::OUString const& aName)
+{
+ Data::iterator it = m_aData.find(aName);
+ if (it != m_aData.end())
+ return &it->second;
+ else
+ return 0;
+}
+//-------------------------------------------------------------------------
+
+
+ElementTreeData const* ElementSet::getElement(rtl::OUString const& aName) const
+{
+ Data::const_iterator it = m_aData.find(aName);
+ if (it != m_aData.end())
+ return &it->second;
+ else
+ return 0;
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData ElementSet::findElement(rtl::OUString const& aName)
+{
+ ElementTreeData aRet;
+
+ Data::iterator it = m_aData.find(aName);
+ if (it != m_aData.end())
+ aRet = it->second;
+
+ return aRet;
+}
+//-------------------------------------------------------------------------
+
+void ElementSet::insertElement(rtl::OUString const& aName, ElementTreeData const& aNewEntry)
+{
+ bool bInserted = m_aData.insert(Data::value_type(aName, aNewEntry)).second;
+
+ OSL_ENSURE(bInserted,"INTERNAL ERROR: Inserted set Element was already present");
+ if (!bInserted) throw Exception("INTERNAL ERROR: Inserted set Element was already present");
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData ElementSet::replaceElement(rtl::OUString const& aName, ElementTreeData const& aNewEntry)
+{
+ OSL_ENSURE(m_aData.find(aName) != m_aData.end(),"INTERNAL ERROR: Replaced set Element is not present");
+
+ ElementTreeData& rElement = m_aData[aName];
+
+ ElementTreeData aOld = rElement;
+ rElement = aNewEntry;
+
+ return aOld;
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData ElementSet::removeElement(rtl::OUString const& aName)
+{
+ Data::iterator it = m_aData.find(aName);
+ OSL_ENSURE(it != m_aData.end(),"INTERNAL ERROR: Removed set Element is not present");
+
+ ElementTreeData aOld;
+ if (it != m_aData.end())
+ {
+ aOld = it->second;
+ m_aData.erase(it);
+ }
+ return aOld;
+}
+//-------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class SetEntry
+//-----------------------------------------------------------------------------
+
+SetEntry::SetEntry(ElementTree* pTree_)
+: m_pTree(pTree_)
+{
+ OSL_ENSURE(pTree_ == 0 || pTree_->isValidNode(Tree::ROOT),
+ "INTERNAL ERROR: Invalid empty tree used for SetEntry ");
+}
+
+//-----------------------------------------------------------------------------
+
+view::ViewTreeAccess SetEntry::getTreeView() const
+{
+ OSL_ENSURE(isValid(), "Cannot get View Access for NULL SetEntry");
+ return view::ViewTreeAccess(m_pTree);
+}
+
+//-----------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+
+//-------------------------------------------------------------------------
+// class SetNodeImpl
+//-------------------------------------------------------------------------
+
+SetNodeImpl::SetNodeImpl(sharable::SetNode * _pNodeRef,Template* pTemplate)
+: NodeImpl(reinterpret_cast<sharable::Node *>(_pNodeRef))
+,m_aTemplate(pTemplate)
+,m_aTemplateProvider()
+,m_pParentTree(0)
+,m_nContextPos(0)
+,m_aInit(0)
+{
+}
+ // unbind the original
+//-----------------------------------------------------------------------------
+
+SetNodeImpl::~SetNodeImpl()
+{
+}
+//-----------------------------------------------------------------------------
+
+void SetNodeImpl::rebuildFrom(SetNodeImpl& rOldData, sharable::SetNode * newNode)
+{
+ m_aTemplate = rOldData.m_aTemplate;
+ m_aTemplateProvider = rOldData.m_aTemplateProvider;
+ m_pParentTree = rOldData.m_pParentTree;
+ m_nContextPos = rOldData.m_nContextPos;
+ m_aInit = rOldData.m_aInit;
+
+ if (rOldData.implHasLoadedElements())
+ {
+ rOldData.doTransferElements(m_aDataSet);
+ implRebuildElements(newNode);
+ OSL_ASSERT(this->implHasLoadedElements());
+ }
+ else
+ OSL_ASSERT(!this->implHasLoadedElements());
+
+ rOldData.m_aTemplate.clear();
+ rOldData.m_aTemplateProvider = TemplateProvider();
+ rOldData.m_pParentTree = 0;
+ rOldData.m_nContextPos = 0;
+
+}
+
+//-----------------------------------------------------------------------------
+void SetNodeImpl::doTransferElements(ElementSet& rReplacement)
+{
+ m_aDataSet.swap(rReplacement);
+}
+//-----------------------------------------------------------------------------
+
+void SetNodeImpl::implRebuildElements(sharable::SetNode * newNode)
+{
+ OSL_ENSURE(m_pParentTree,"Cannot rebuild set without context tree");
+ rtl::Reference<view::ViewStrategy> xNewStrategy = m_pParentTree->getViewBehavior();
+
+ for(ElementSet::Iterator it = m_aDataSet.begin(), stop = m_aDataSet.end();
+ it != stop;
+ ++it)
+ {
+ OSL_ASSERT(it->isValid());
+ if (!it->isValid()) continue;
+
+ ElementTreeData aElement = *it;
+ rtl::OUString aName = aElement->getSimpleRootName();
+
+ sharable::TreeFragment * aNewElementAccess = newNode->getElement(aName);
+ OSL_ASSERT(
+ aNewElementAccess != 0 && aElement->getOriginalTreeAccess() != 0);
+
+ aElement->rebuild(xNewStrategy,aNewElementAccess);
+ }
+}
+//-----------------------------------------------------------------------------
+
+sharable::SetNode * SetNodeImpl::getDataAccess() const
+{
+ sharable::Node * node = getOriginalNodeAccess();
+ OSL_ASSERT(node != 0 && node->isSet());
+ return &node->set;
+}
+//-----------------------------------------------------------------------------
+
+Tree* SetNodeImpl::getParentTree() const
+{
+ OSL_ENSURE(m_pParentTree,"Set Node: Parent tree not set !");
+ return m_pParentTree;
+}
+//-----------------------------------------------------------------------------
+
+unsigned int SetNodeImpl::getContextOffset() const
+{
+ OSL_ENSURE(m_nContextPos,"Set Node: Position within parent tree not set !");
+ return m_nContextPos;
+}
+//-----------------------------------------------------------------------------
+
+bool SetNodeImpl::doIsEmpty() const
+{
+ /*
+ for(ElementSet::Iterator it = m_aDataSet.begin(), stop = m_aDataSet.end();
+ it != stop;
+ ++it)
+ {
+ if (!it->isEmpty())
+ return false;
+ }
+ return true;
+ */
+ return m_aDataSet.isEmpty();
+}
+//-------------------------------------------------------------------------
+
+ElementTree* SetNodeImpl::doFindElement(rtl::OUString const& aName)
+{
+ return m_aDataSet.findElement(aName).get();
+}
+//-------------------------------------------------------------------------
+void SetNodeImpl::doDifferenceToDefaultState(SubtreeChange& _rChangeToDefault, ISubtree& _rDefaultTree)
+{
+ OSL_ENSURE(implHasLoadedElements(),"Should not query difference to default state for set that is not loaded");
+ implDifferenceToDefaultState(_rChangeToDefault,_rDefaultTree);
+}
+//-----------------------------------------------------------------------------
+
+SetElementChangeImpl* SetNodeImpl::doAdjustToAddedElement(rtl::OUString const& aName, AddNode const& aAddNodeChange, ElementTreeData const & aNewElement)
+{
+ return implAdjustToAddedElement(aName,aNewElement,aAddNodeChange.isReplacing());
+}
+//-------------------------------------------------------------------------
+
+SetElementChangeImpl* SetNodeImpl::implAdjustToAddedElement(rtl::OUString const& aName, ElementTreeData const & aNewElement, bool _bReplacing)
+{
+ { (void)_bReplacing; }
+ OSL_ENSURE( validatedName(aNewElement) == aName, "Unexpected name on new element" );
+
+ if (hasStoredElement(aName))
+ {
+ OSL_ENSURE( _bReplacing, "Added Element already exists - replacing" );
+
+ ElementTreeData aOldElement = this->replaceElement(aName,aNewElement);
+
+ return implCreateReplace(aName,aNewElement,aOldElement);
+ }
+ else
+ {
+ OSL_ENSURE( !_bReplacing, "Replaced Element doesn't exist - simply adding" );
+ this->insertElement(aName,aNewElement);
+
+ return implCreateInsert(aName,aNewElement);
+ }
+}
+//-------------------------------------------------------------------------
+
+SetElementChangeImpl* SetNodeImpl::doAdjustToRemovedElement(rtl::OUString const& aName, RemoveNode const& /*aRemoveNodeChange*/)
+{
+ return implAdjustToRemovedElement(aName);
+}
+//-------------------------------------------------------------------------
+
+SetElementChangeImpl* SetNodeImpl::implAdjustToRemovedElement(rtl::OUString const& aName)
+{
+ if (ElementTreeData* pOriginal = getStoredElement(aName))
+ {
+ ElementTreeData aOldElement = *pOriginal;
+ this->removeElement(aName);
+
+ return implCreateRemove(aName,aOldElement);
+ }
+ else
+ {
+ OSL_ENSURE( false, "Removed Element doesn't exist - ignoring" );
+ return 0;
+ }
+}
+//-------------------------------------------------------------------------
+
+SetElementChangeImpl* SetNodeImpl::implCreateInsert(rtl::OUString const& aName, ElementTreeData const& aNewElement) const
+{
+ Path::Component aFullName = Path::makeCompositeName(aName, this->getElementTemplate()->getName());
+
+ SetElementChangeImpl* pRet = new SetInsertImpl(aFullName, aNewElement.tree, true);
+ pRet->setTarget( getParentTree(), getContextOffset() );
+ return pRet;
+}
+//-------------------------------------------------------------------------
+
+SetElementChangeImpl* SetNodeImpl::implCreateReplace(rtl::OUString const& aName, ElementTreeData const& aNewElement, ElementTreeData const& aOldElement) const
+{
+ Path::Component aFullName = Path::makeCompositeName(aName, this->getElementTemplate()->getName());
+
+ SetElementChangeImpl* pRet = new SetReplaceImpl(aFullName, aNewElement.tree, aOldElement.tree);
+ pRet->setTarget( getParentTree(), getContextOffset() );
+ return pRet;
+}
+//-------------------------------------------------------------------------
+
+SetElementChangeImpl* SetNodeImpl::implCreateRemove(rtl::OUString const& aName, ElementTreeData const& aOldElement) const
+{
+ Path::Component aFullName = Path::makeCompositeName(aName, this->getElementTemplate()->getName());
+
+ SetElementChangeImpl* pRet = new SetRemoveImpl(aFullName, aOldElement.tree);
+ pRet->setTarget( getParentTree(), getContextOffset() );
+ return pRet;
+}
+//-------------------------------------------------------------------------
+
+void SetNodeImpl::insertElement(rtl::OUString const& aName, ElementTreeData const& aNewElement)
+{
+ attach(aNewElement,aName);
+ try
+ {
+ m_aDataSet.insertElement(aName,aNewElement);
+ }
+ catch (std::exception&)
+ {
+ detach(aNewElement);
+ throw;
+ }
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData SetNodeImpl::replaceElement(rtl::OUString const& aName, ElementTreeData const& aNewElement)
+{
+ attach(aNewElement,aName);
+ try
+ {
+ ElementTreeData aOldElement = m_aDataSet.replaceElement(aName,aNewElement);
+ detach(aOldElement);
+ return aOldElement;
+ }
+ catch (std::exception&)
+ {
+ detach(aNewElement);
+ throw;
+ }
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData SetNodeImpl::removeElement(rtl::OUString const& aName)
+{
+ ElementTreeData aOldElement = m_aDataSet.removeElement(aName);
+ detach(aOldElement);
+ return aOldElement;
+}
+//-------------------------------------------------------------------------
+SetNodeVisitor::Result SetNodeImpl::doDispatchToElements(SetNodeVisitor& aVisitor)
+{
+ SetNodeVisitor::Result eRet = SetNodeVisitor::CONTINUE;
+ for(ElementSet::Iterator it = m_aDataSet.begin(), stop = m_aDataSet.end();
+ it != stop && eRet != SetNodeVisitor::DONE;
+ ++it)
+ {
+ eRet = aVisitor.visit( SetEntry(it->get()) );
+ }
+ return eRet;
+}
+//-----------------------------------------------------------------------------
+
+void SetNodeImpl::attach(ElementTreeData const& aNewElement, rtl::OUString const& aName)
+{
+ // check for name (this also reject NULLs, therefore it should go first)
+ rtl::OUString aActualName = validatedName(aNewElement);
+
+ Tree* pParentContext = getParentTree();
+ unsigned int nParentOffset = getContextOffset();
+
+ OSL_ENSURE(nParentOffset != 0 && pParentContext != 0,"INTERNAL ERROR: Set has no context");
+
+ bool bHasContext = (aNewElement->getContextTree() != 0);
+
+ if (bHasContext)
+ {
+ if (aNewElement->getContextTree() != pParentContext)
+ {
+ OSL_ENSURE(false,"INTERNAL ERROR: New set element belongs to another context tree" );
+ throw Exception("INTERNAL ERROR: New set element belongs to another context tree" );
+ }
+ if (aNewElement->getContextNode() != nParentOffset)
+ {
+ OSL_ENSURE(false,"INTERNAL ERROR: New set element belongs to another context node" );
+ throw Exception("INTERNAL ERROR: New set element belongs to another context node" );
+ }
+ }
+ else
+ {
+ OSL_ENSURE(aNewElement->getContextNode() == 0, "INTERNAL ERROR: New element has context position without a parent");
+ aNewElement->moveTree(pParentContext,nParentOffset);
+ }
+
+ // check for and correct a misnomer - do only after parenthood is assured (else we don't own it anyways)
+ if (aName != aActualName)
+ {
+ // OSL_ENSURE(aActualName.isEmpty(), "WARNING: Wrongly named tree inserted in set node");
+ aNewElement->renameTree(aName);
+
+ aActualName = validatedName(aNewElement);
+ if (aName !=aActualName )
+ {
+ OSL_ENSURE(false, "INTERNAL ERROR: Cannot rename tree in set node");
+ throw Exception("INTERNAL ERROR: Cannot rename tree for insertion into set node");
+ }
+ }
+}
+//-------------------------------------------------------------------------
+
+void SetNodeImpl::detach(ElementTreeData const& aOldElement)
+{
+ if (aOldElement.isValid())
+ {
+ aOldElement->detachTree();
+ }
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData SetNodeImpl::entryToElement(SetEntry const& _anEntry)
+{
+ ElementTree * pTree = _anEntry.tree();
+ return ElementTreeData(pTree, isInDefault(_anEntry));
+}
+//-------------------------------------------------------------------------
+
+
+SetElementChangeImpl* SetNodeImpl::doAdjustChangedElement(NodeChangesInformation& rLocalChanges, rtl::OUString const& aName, Change const& _aElementChange)
+{
+ SetElementChangeImpl* pThisChange = NULL;
+
+ if (ElementTreeData* pElement = getStoredElement(aName))
+ {
+ OSL_ASSERT(pElement->isValid());
+
+ if (SubtreeChange const * subtreeChange = dynamic_cast< SubtreeChange const * >(&_aElementChange))
+ {
+ // recurse to element tree
+ Tree * elementTree = pElement->get();
+
+ view::getViewBehavior(elementTree)->adjustToChanges(rLocalChanges, view::getRootNode(elementTree), *subtreeChange);
+ }
+ else if (ValueChange const * valueChange = dynamic_cast< ValueChange const * >(&_aElementChange))
+ {
+ // make an element for the old element
+ std::auto_ptr<ValueNode> aOldNode = OTreeNodeConverter().createCorrespondingNode(*valueChange);
+ aOldNode->setValue(valueChange->getOldValue());
+
+ bool bWasDefault = (valueChange->getMode() == ValueChange::wasDefault);
+
+ std::auto_ptr<INode> aBasePtr(aOldNode.release());
+ rtl::OUString aElementTypeName = getElementTemplate()->getName();
+ rtl::Reference< data::TreeSegment > aOldBaseTree = data::TreeSegment::create( aBasePtr, aElementTypeName );
+
+ rtl::Reference<ElementTree> aOldElement = new ElementTree(aOldBaseTree, getElementTemplate(), getTemplateProvider());
+
+ OSL_ASSERT(aOldBaseTree.is()); // the tree took ownership
+ OSL_ASSERT(aOldElement->isFree()); // the tree is free-floating
+
+ pThisChange = implCreateReplace(aName,*pElement,ElementTreeData(aOldElement,bWasDefault));
+ }
+ else
+ OSL_ENSURE( false, "Unexpected kind of change to set element" );
+
+ }
+ else
+ {
+ // could be changed to do an insert instead (?)
+ OSL_ENSURE( false, "Changed Element doesn't exist - (and not adding now)" );
+ }
+ return pThisChange;
+}
+//-------------------------------------------------------------------------
+
+bool SetNodeImpl::implHasLoadedElements() const
+{
+ return m_aInit == 0; // cannot check whether init was called though ...
+}
+//-----------------------------------------------------------------------------
+
+void SetNodeImpl::initElements(TemplateProvider const& aTemplateProvider,Tree& rParentTree,unsigned int nPos,unsigned int nDepth)
+{
+ OSL_ENSURE(m_pParentTree == 0 || m_pParentTree == &rParentTree, "WARNING: Set Node: Changing parent");
+ OSL_ENSURE(m_nContextPos == 0 || m_nContextPos == nPos, "WARNING: Set Node: Changing location within parent");
+ m_pParentTree = &rParentTree;
+ m_nContextPos = nPos;
+
+ OSL_ENSURE(!m_aTemplateProvider.isValid() || !implHasLoadedElements(),"ERROR: Reinitializing set"); //doClearElements();
+ OSL_ASSERT(doIsEmpty()); //doClearElements();
+
+ OSL_ENSURE(!m_aTemplate.is() || m_aTemplate->isInstanceTypeKnown(),"ERROR: Need a type-validated template to fill a set");
+ OSL_ENSURE(aTemplateProvider.isValid() || nDepth == 0 || m_aTemplate->isInstanceValue(), "ERROR: Need a template provider to fill a non-primitive set");
+
+ if (nDepth > 0) // dont set a template provider for zero-depth sets
+ {
+ m_aInit = nDepth;
+ m_aTemplateProvider = aTemplateProvider;
+ }
+}
+//-----------------------------------------------------------------------------
+
+bool SetNodeImpl::implLoadElements()
+{
+ if (m_aInit > 0)
+ {
+ OSL_ENSURE(!getElementTemplate().is() || getElementTemplate()->isInstanceTypeKnown(),"ERROR: Need a type-validated template to fill a set");
+ OSL_ENSURE(getTemplateProvider().isValid() || getElementTemplate()->isInstanceValue(), "ERROR: Need a template provider to fill a non-primitive set");
+
+ unsigned int nDepth = m_aInit;
+ implInitElements(this->getDataAccess(),nDepth);
+ m_aInit = 0;
+ }
+ OSL_ASSERT(implHasLoadedElements());
+
+ return m_aInit == 0;
+}
+//-----------------------------------------------------------------------------
+
+void SetNodeImpl::implEnsureElementsLoaded()
+{
+ if (!implLoadElements())
+ throw ConstraintViolation("Trying to access set elements beyond the loaded nestíng level");
+}
+//-----------------------------------------------------------------------------
+
+void SetNodeImpl::implInitElements(sharable::SetNode * node, unsigned int nDepth)
+{
+ Tree* pThisTree = getParentTree();
+
+ OSL_ENSURE(pThisTree,"Cannot load elements of a set that has no parent tree");
+
+ CollectElementTrees aCollector( pThisTree->getViewBehavior(), pThisTree, getContextOffset(),
+ nDepth, getElementTemplate(), getTemplateProvider() );
+ aCollector.collect(node);
+
+ for(std::vector<ElementTreeData>::const_iterator it = aCollector.collection.begin(), stop = aCollector.collection.end();
+ it != stop; ++it)
+ {
+ implInitElement(implValidateElement(*it));
+ }
+}
+//-------------------------------------------------------------------------
+
+void SetNodeImpl::implInitElement(ElementTreeData const& aNewElement)
+{
+ OSL_PRECOND(aNewElement.isValid(),"INTERNAL ERROR: Set element is NULL");
+ OSL_ENSURE(!aNewElement->isFree(),"INTERNAL ERROR: Set element is free-floating");
+
+ OSL_ENSURE(aNewElement->getContextTree() == getParentTree(),"INTERNAL ERROR: Set element has wrong context tree");
+ OSL_ENSURE(aNewElement->getContextNode() == getContextOffset(),"INTERNAL ERROR: Set element has wrong context node");
+
+ rtl::OUString aName = validatedName(aNewElement);
+
+ OSL_ENSURE(aName.getLength() != 0,"INTERNAL ERROR: Unnamed element in set");
+ OSL_ENSURE(m_aDataSet.getElement(aName) == 0,"INTERNAL ERROR: Duplicate element name in set");
+
+ m_aDataSet.insertElement(aName,aNewElement);
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData SetNodeImpl::makeAdditionalElement(rtl::Reference<view::ViewStrategy> const& _xStrategy, AddNode const& aAddNodeChange, unsigned int nDepth)
+{
+ OSL_ENSURE(aAddNodeChange.wasInserted(), "Cannot integrate element that is not in tree yet");
+
+ sharable::TreeFragment * aAddedTree = aAddNodeChange.getInsertedTree();
+ // need 'unsafe', because ownership would be gone when notifications are sent
+ if (aAddedTree != NULL)
+ {
+ CollectElementTrees aCollector( _xStrategy, getParentTree(), getContextOffset(),
+ nDepth, getElementTemplate(), getTemplateProvider() );
+
+ return implValidateElement(aCollector.create(aAddedTree));
+ }
+
+ return ElementTreeData();
+}
+//-------------------------------------------------------------------------
+
+ElementTreeData SetNodeImpl::implValidateElement(ElementTreeData const& aNewElement)
+{
+ rtl::Reference<Template> aTemplate = getElementTemplate();
+ OSL_ENSURE(aTemplate.is(),"INTERNAL ERROR: No template in set node");
+ OSL_ENSURE(aTemplate->isInstanceTypeKnown(),"INTERNAL ERROR: Unspecifed template in set node");
+
+ OSL_ENSURE(aNewElement.isValid(),"INTERNAL ERROR: Unexpected NULL element in set node");
+ if (aNewElement.isValid())
+ {
+ if (aTemplate->isInstanceValue())
+ {
+ if (aNewElement->nodeCount() == 0)
+ {
+ OSL_ENSURE(false,"INTERNAL ERROR: Invalid (empty) element tree in value set");
+ throw Exception("INTERNAL ERROR: Invalid (empty) element tree in value set");
+ }
+ if (aNewElement->nodeCount() > 1)
+ {
+ OSL_ENSURE(false,"INTERNAL ERROR: Complex element tree in value set");
+ throw Exception("INTERNAL ERROR: Complex element tree in value set");
+ }
+
+ view::Node aElementRoot = view::getRootNode(aNewElement.get());
+
+ OSL_ENSURE(aElementRoot.isValueNode(),"INTERNAL ERROR: Inserting complex type into value set node");
+
+ view::ValueNode aValueNode(aElementRoot);
+ com::sun::star::uno::Type aValueType = aValueNode.get_impl()->getValueType();
+
+ OSL_ENSURE( aValueType.getTypeClass() != uno::TypeClass_INTERFACE,
+ "INTERNAL ERROR: Inserting complex type into value set node");
+
+ com::sun::star::uno::Type aElementType = aTemplate->getInstanceType();
+
+ if (aValueType != aElementType)
+ {
+ // handle 'Any'
+ if (aElementType.getTypeClass() != uno::TypeClass_ANY)
+ {
+ OSL_ENSURE(false,"INTERNAL ERROR: ´Wrong value type inserting into value set");
+ throw TypeMismatch(aValueType.getTypeName(), aElementType.getTypeName(),
+ "- INTERNAL ERROR: Mistyped element in value set");
+ }
+ }
+ }
+ else // a complete tree
+ {
+ // TODO: add some validation here
+ if (!aNewElement->isTemplateInstance())
+ {
+ throw TypeMismatch( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<Unknown> [Missing Template]")),
+ aTemplate->getName(),
+ " - Trying to insert element without template into set");
+ }
+ if (!aNewElement->isInstanceOf(aTemplate))
+ {
+ throw TypeMismatch( aNewElement->getTemplate()->getPathString(),
+ aTemplate->getPathString(),
+ " - Trying to insert element with wrong template into set");
+ }
+ }
+ }
+ return aNewElement;
+}
+//-------------------------------------------------------------------------
+
+namespace
+{
+ //-------------------------------------------------------------------------
+ class DiffToDefault : data::SetVisitor
+ {
+ SubtreeChange& m_rChange;
+ ISubtree& m_rDefaultTree;
+ OTreeChangeFactory& m_rChangeFactory;
+ public:
+ explicit
+ DiffToDefault(SubtreeChange& _rChange, ISubtree& _rDefaultTree)
+ : m_rChange(_rChange)
+ , m_rDefaultTree(_rDefaultTree)
+ , m_rChangeFactory( getDefaultTreeChangeFactory() )
+ {
+ }
+
+ void diff(sharable::SetNode * actualTree)
+ {
+ translate(m_rDefaultTree);
+ visitElements(actualTree);
+ }
+
+ private:
+ void translate(ISubtree& _rDefaultTree);
+ void handleDefault(rtl::Reference< data::TreeSegment > const & _pDefaultElement);
+ void handleActual(sharable::TreeFragment * element);
+
+ using SetVisitor::handle;
+ virtual bool handle(sharable::TreeFragment * tree)
+ { handleActual(tree); return false; }
+ };
+ //-------------------------------------------------------------------------
+
+ void DiffToDefault::translate(ISubtree& _rDefaultTree)
+ {
+ rtl::OUString aTypeName = _rDefaultTree.getElementTemplateName();
+ OSL_ENSURE(aTypeName.getLength(),"Cannot get element type for default set");
+
+ CollectNames aCollector;
+ aCollector.applyToChildren(_rDefaultTree);
+
+ std::vector<rtl::OUString> const& aNames = aCollector.list();
+
+ for(std::vector<rtl::OUString>::const_iterator it = aNames.begin(); it != aNames.end(); ++it)
+ {
+ std::auto_ptr<INode> aChild = _rDefaultTree.removeChild(*it);
+ handleDefault( data::TreeSegment::create(aChild,aTypeName) );
+ }
+
+ }
+ //-------------------------------------------------------------------------
+
+ void DiffToDefault::handleDefault(rtl::Reference< data::TreeSegment > const &_pDefaultElement)
+ {
+ OSL_PRECOND(_pDefaultElement.is(), "Unexpected NULL default node");
+
+ rtl::OUString sName = _pDefaultElement->fragment->getName();
+
+ OSL_ENSURE(_pDefaultElement->fragment->getAttributes().isDefault(), "Missing default state on default element tree");
+ OSL_ENSURE(_pDefaultElement->fragment->nodes[0].isDefault(), "Missing default attribute on default node");
+
+ std::auto_ptr<AddNode> pAddIt( m_rChangeFactory.createAddNodeChange(_pDefaultElement, sName,true) );
+
+ m_rChange.addChange(base_ptr(pAddIt));
+ }
+ //-------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+ void DiffToDefault::handleActual(sharable::TreeFragment * element)
+ {
+ bool bDefaultElement = element->getRootNode()->isDefault();
+
+ rtl::OUString sName = element->getName();
+
+ if (Change* pDefaultNode = m_rChange.getChange(sName) )
+ {
+
+ if (AddNode * addNode = dynamic_cast< AddNode * >(pDefaultNode))
+ {
+ if (bDefaultElement)
+ {
+ rtl::Reference< data::TreeSegment > aDefaultTree = addNode->getNewTree();
+ m_rDefaultTree.addChild(data::convertTree(aDefaultTree.is() ? aDefaultTree->fragment : 0, true));
+
+ // no change needed - remove the change and recover the default
+ m_rChange.removeChange(sName);
+ }
+ }
+ else
+ {
+ // should never happen
+ OSL_ASSERT(false);
+ if (bDefaultElement) m_rChange.removeChange(sName);
+ }
+ }
+ else
+ {
+ OSL_ENSURE(!bDefaultElement, "Node marked 'default' not found in actual default data");
+
+ std::auto_ptr<RemoveNode> pRemoveIt( m_rChangeFactory.createRemoveNodeChange(sName,true) );
+ // pRemoveIt->expectRemovedNode(pActualNode);
+ m_rChange.addChange(base_ptr(pRemoveIt));
+ }
+ }
+//-----------------------------------------------------------------------------
+}
+//-----------------------------------------------------------------------------
+void SetNodeImpl::implDifferenceToDefaultState(SubtreeChange& _rChangeToDefault, ISubtree& _rDefaultTree) const
+{
+ DiffToDefault(_rChangeToDefault,_rDefaultTree).diff( getDataAccess() );
+}
+//-----------------------------------------------------------------------------
+void SetNodeImpl::convertChanges(NodeChangesInformation& rLocalChanges, SubtreeChange const& rExternalChange,
+ unsigned int nDepth)
+{
+ OSL_ASSERT(nDepth > 0);
+
+ if (Tree* pParentTree = this->getParentTree())
+ {
+ unsigned int nNode = getContextOffset();
+
+ OSL_ENSURE(pParentTree->isValidNode(nNode), "Invalid context node in Set");
+ OSL_ENSURE(view::Node(pParentTree, nNode).get_impl() == this,
+ "Wrong context node in Set");
+
+ CollectChanges aCollector(rLocalChanges, *pParentTree, nNode, getElementTemplate(), nDepth);
+
+ aCollector.collectFromChildren(rExternalChange);
+ }
+ else
+ OSL_ENSURE(false, "Missing context tree in Set");
+}
+//-----------------------------------------------------------------------------
+
+ }
+}
+
diff --git a/configmgr/source/treemgr/setnodeimpl.hxx b/configmgr/source/treemgr/setnodeimpl.hxx
new file mode 100644
index 000000000000..3a10f4fa4232
--- /dev/null
+++ b/configmgr/source/treemgr/setnodeimpl.hxx
@@ -0,0 +1,309 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: setnodeimpl.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_SETNODEBEHAVIOR_HXX_
+#define CONFIGMGR_SETNODEBEHAVIOR_HXX_
+
+#include "nodeimpl.hxx"
+#include "tree.hxx"
+#include "template.hxx"
+#include <rtl/ref.hxx>
+
+#ifndef INCUDED_MAP
+#include <map>
+#define INCUDED_MAP
+#endif
+#ifndef INCLUDED_MEMORY
+#include <memory>
+#define INCLUDED_MEMORY
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ class SubtreeChange;
+ class AddNode;
+ class RemoveNode;
+ namespace view { class ViewTreeAccess; }
+//-----------------------------------------------------------------------------
+
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ class SetElementChangeImpl;
+
+//-----------------------------------------------------------------------------
+
+ struct SetEntry
+ {
+ SetEntry(ElementTree* _pTree);
+
+ bool isValid() const { return m_pTree != 0; }
+
+ ElementTree* tree() const { return m_pTree; };
+
+ view::ViewTreeAccess getTreeView() const;
+ private:
+ ElementTree* m_pTree;
+ };
+ //-------------------------------------------------------------------------
+
+ struct SetNodeVisitor
+ {
+ enum Result { DONE, CONTINUE };
+ virtual Result visit(SetEntry const& anEntry) = 0;
+ };
+
+ //-----------------------------------------------------------------------------
+
+ // basic implementations of set node contents
+ //-----------------------------------------------------------------------------
+
+ struct ElementTreeData
+ {
+ // construction
+ ElementTreeData() : tree(), inDefault(false) {}
+
+ ElementTreeData(rtl::Reference<ElementTree> const& _tree, bool _bDefault)
+ : tree(_tree), inDefault(_bDefault) {}
+
+ // ORef compatibility
+ sal_Bool isValid() const { return this->tree.is(); }
+ ElementTree* get() const { return this->tree.get(); }
+ rtl::Reference<ElementTree> const& operator->() const { return this->tree; }
+ ElementTree& operator*() const { return *get(); }
+
+ // data
+ rtl::Reference<ElementTree> tree;
+ bool inDefault;
+ };
+ //-----------------------------------------------------------------------------
+
+ class ElementSet
+ {
+ struct FastLess
+ {
+ bool operator ()(
+ rtl::OUString const & a, rtl::OUString const & b) const
+ {
+ // first sort by length; order is immaterial, and it is fast
+ return a.getLength() == b.getLength()
+ ? a < b : a.getLength() < b.getLength();
+ }
+ };
+
+ public:
+ typedef std::map<rtl::OUString, ElementTreeData, FastLess> Data;
+
+ // the following must be implemented by derived classes
+ bool isEmpty() const { return m_aData.empty(); }
+
+ bool hasElement(rtl::OUString const& aName) const;
+ ElementTreeData* getElement(rtl::OUString const& aName);
+ ElementTreeData const* getElement(rtl::OUString const& aName) const;
+ ElementTreeData findElement(rtl::OUString const& aName);
+
+ void insertElement(rtl::OUString const& aName, ElementTreeData const& aNewEntry);
+ ElementTreeData replaceElement(rtl::OUString const& aName, ElementTreeData const& aNewEntry);
+ ElementTreeData removeElement(rtl::OUString const& aName);
+
+ void clearElements() { m_aData.clear(); }
+
+ void swap(ElementSet& aOther) { m_aData.swap(aOther.m_aData); }
+
+ // STL style iteration
+ class ConstIterator
+ {
+ public:
+ ConstIterator(Data::const_iterator const& it) : m_base(it) {}
+
+ ElementTreeData const& operator* () const { return m_base->second; }
+ ElementTreeData const* operator->() const { return &m_base->second; }
+
+ ConstIterator& operator++() { ++m_base; return *this; }
+ ConstIterator operator++(int) { return ConstIterator(m_base++); }
+
+ ConstIterator& operator--() { --m_base; return *this; }
+ ConstIterator operator--(int) { return ConstIterator(m_base--); }
+
+ friend bool operator ==(ConstIterator const& lhs, ConstIterator const& rhs)
+ { return lhs.m_base == rhs.m_base; }
+ friend bool operator !=(ConstIterator const& lhs, ConstIterator const& rhs)
+ { return lhs.m_base != rhs.m_base; }
+ private:
+ Data::const_iterator m_base;
+ };
+ ConstIterator begin() const { return ConstIterator(m_aData.begin()); }
+ ConstIterator end() const { return ConstIterator(m_aData.end()); }
+
+ class Iterator
+ {
+ public:
+ Iterator(Data::iterator const& it) : m_base(it) {}
+
+ ElementTreeData& operator* () const { return m_base->second; }
+ ElementTreeData* operator->() const { return &m_base->second; }
+
+ Iterator& operator++() { ++m_base; return *this; }
+ Iterator operator++(int) { return Iterator(m_base++); }
+
+ Iterator& operator--() { --m_base; return *this; }
+ Iterator operator--(int) { return Iterator(m_base--); }
+
+ friend bool operator ==(Iterator const& lhs, Iterator const& rhs)
+ { return lhs.m_base == rhs.m_base; }
+ friend bool operator !=(Iterator const& lhs, Iterator const& rhs)
+ { return lhs.m_base != rhs.m_base; }
+
+ operator ConstIterator() const { return ConstIterator(m_base); }
+ private:
+ Data::iterator m_base;
+ };
+ Iterator begin() { return Iterator(m_aData.begin()); }
+ Iterator end() { return Iterator(m_aData.end()); }
+
+ Data::const_iterator beginNative() const { return m_aData.begin(); }
+ Data::const_iterator endNative() const { return m_aData.end(); }
+ private:
+ Data m_aData;
+ };
+ //-------------------------------------------------------------------------
+
+ // Basic implementation of a set node
+ //-------------------------------------------------------------------------
+
+ class SetNodeImpl : public NodeImpl
+ {
+ friend class view::ViewStrategy;
+ ElementSet m_aDataSet;
+ rtl::Reference<Template> m_aTemplate;
+ TemplateProvider m_aTemplateProvider;
+ Tree* m_pParentTree;
+ unsigned int m_nContextPos;
+
+ unsigned int m_aInit;
+
+ public:
+ SetNodeImpl(sharable::SetNode * _pNodeRef, Template* pTemplate);
+
+ sharable::SetNode * getDataAccess() const;
+
+ /// Get the template that describes elements of this set
+ rtl::Reference<Template> getElementTemplate() const { return m_aTemplate; }
+
+ /// Get a template provider that can create new elements for this set
+ TemplateProvider getTemplateProvider() const { return m_aTemplateProvider; }
+
+ void convertChanges(NodeChangesInformation& rLocalChanges, SubtreeChange const& rExternalChange, unsigned int nDepth);
+
+ void insertElement(rtl::OUString const& aName, ElementTreeData const& aNewElement);
+ ElementTreeData replaceElement(rtl::OUString const& aName, ElementTreeData const& aNewElement);
+ ElementTreeData removeElement(rtl::OUString const& aName);
+
+ void rebuildFrom(SetNodeImpl& rOldData, sharable::SetNode * newNode);
+
+ protected:
+ ~SetNodeImpl();
+
+ protected:
+ // new overrideables
+ virtual bool doIsEmpty() const;
+ virtual ElementTree* doFindElement(rtl::OUString const& aName) ;
+ virtual SetNodeVisitor::Result doDispatchToElements( SetNodeVisitor& aVisitor);
+ virtual void doDifferenceToDefaultState( SubtreeChange& _rChangeToDefault, ISubtree& _rDefaultTree);
+
+ virtual SetElementChangeImpl* doAdjustToAddedElement( rtl::OUString const& aName, AddNode const& aAddNodeChange, ElementTreeData const & aNewElement);
+ virtual SetElementChangeImpl* doAdjustToRemovedElement( rtl::OUString const& aName, RemoveNode const& aRemoveNodeChange);
+ virtual SetElementChangeImpl* doAdjustChangedElement( NodeChangesInformation& rLocalChanges, rtl::OUString const& aName, Change const& aChange);
+
+ virtual void doTransferElements(ElementSet& rReplacement);
+
+ protected:
+ // helpers
+ Tree* getParentTree() const;
+ unsigned int getContextOffset() const;
+
+ ElementTreeData makeElement( SetEntry const & _anEntry);
+ static ElementTreeData entryToElement(SetEntry const& _anEntry);
+ view::ViewTreeAccess getElementView();
+
+ /// Initialize the set data: Set context information, and build the view (actually loading the elements may be deferred)
+ friend class TreeImplBuilder;
+ void initElements(TemplateProvider const& aTemplateProvider, Tree& rParentTree, unsigned int nPos, unsigned int nDepth);
+
+ protected:
+ /// does this set contain any elements (loads elements if needed)
+ bool implHasLoadedElements() const;
+ bool implLoadElements();
+ void implEnsureElementsLoaded();
+ void implInitElements(sharable::SetNode * node, unsigned int nDepth);
+ void implInitElement(ElementTreeData const& aNewElement);
+
+ void implRebuildElements(sharable::SetNode * newNode);
+ protected:
+ SetElementChangeImpl* implCreateInsert ( rtl::OUString const& aName, ElementTreeData const& aNewElement) const;
+ SetElementChangeImpl* implCreateReplace ( rtl::OUString const& aName, ElementTreeData const& aNewElement, ElementTreeData const& aOldElement) const;
+ SetElementChangeImpl* implCreateRemove ( rtl::OUString const& aName, ElementTreeData const& aOldElement) const;
+
+ SetElementChangeImpl* implAdjustToAddedElement( rtl::OUString const& aName, ElementTreeData const& aNewElement, bool _bReplacing);
+ SetElementChangeImpl* implAdjustToRemovedElement( rtl::OUString const& aName);
+
+ ElementTreeData makeAdditionalElement( rtl::Reference<view::ViewStrategy> const& _xStrategy, AddNode const& aAddNodeChange, unsigned int nDepth);
+
+ ElementTreeData implValidateElement(ElementTreeData const& aNewElement);
+
+ void implDifferenceToDefaultState( SubtreeChange& _rChangeToDefault, ISubtree& _rDefaultTree) const;
+ protected:
+ bool hasStoredElement(rtl::OUString const& aName) const
+ { return m_aDataSet.hasElement(aName); }
+ ElementTreeData* getStoredElement(rtl::OUString const& aName)
+ { return m_aDataSet.getElement(aName); }
+ ElementTreeData const* getStoredElement(rtl::OUString const& aName) const
+ { return m_aDataSet.getElement(aName); }
+
+ ElementSet::Data::const_iterator beginElementSet() const
+ { return m_aDataSet.beginNative(); }
+ ElementSet::Data::const_iterator endElementSet() const
+ { return m_aDataSet.endNative(); }
+
+ void attach(ElementTreeData const& aNewElement, rtl::OUString const& aName);
+ void detach(ElementTreeData const& aNewElement);
+ };
+
+//-----------------------------------------------------------------------------
+ // domain-specific 'dynamic_cast' replacement
+ SetNodeImpl& AsSetNode (NodeImpl& rNode);
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_SETNODEBEHAVIOR_HXX_
diff --git a/configmgr/source/treemgr/template.cxx b/configmgr/source/treemgr/template.cxx
new file mode 100644
index 000000000000..819f5590c85e
--- /dev/null
+++ b/configmgr/source/treemgr/template.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: template.cxx,v $
+ * $Revision: 1.18 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "node.hxx"
+#include "template.hxx"
+#include "templateimpl.hxx"
+#include "apitypes.hxx"
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+// class TemplateProvider
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+TemplateProvider::TemplateProvider()
+: m_aImpl()
+{
+}
+
+//-----------------------------------------------------------------------------
+TemplateProvider::TemplateProvider(rtl::Reference< TreeManager > const & xProvider, RequestOptions const& aOptions)
+: m_aImpl( new TemplateProvider_Impl(xProvider,aOptions) )
+{
+}
+
+//-----------------------------------------------------------------------------
+TemplateProvider::TemplateProvider(TemplateProvider const& aOther)
+: m_aImpl(aOther.m_aImpl)
+{
+}
+
+//-----------------------------------------------------------------------------
+TemplateProvider& TemplateProvider::operator =(TemplateProvider const& aOther)
+{
+ m_aImpl = aOther.m_aImpl;
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+TemplateProvider::~TemplateProvider()
+{
+}
+
+//-----------------------------------------------------------------------------
+// class Template
+//-----------------------------------------------------------------------------
+
+Template::Template(rtl::OUString const& aName, rtl::OUString const& aModule,com::sun::star::uno::Type const& aType)
+: m_aName(aName)
+, m_aModule(aModule)
+, m_aInstanceType(aType)
+{
+}
+//-----------------------------------------------------------------------------
+
+bool Template::isInstanceTypeKnown() const
+{
+ OSL_ASSERT( TemplateImplHelper::getNoTypeAvailable().getTypeClass() == uno::TypeClass_VOID );
+ return m_aInstanceType.getTypeClass() != uno::TypeClass_VOID;
+}
+//-----------------------------------------------------------------------------
+
+/// checks if this is a 'value' template
+bool Template::isInstanceValue() const
+{
+ OSL_ENSURE( isInstanceTypeKnown(), "Template instance type unknown - cannot determine kind");
+ return m_aInstanceType.getTypeClass() != uno::TypeClass_INTERFACE;
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Type Template::getInstanceType() const
+{
+ OSL_ENSURE( isInstanceTypeKnown(), "Template instance type unknown - returning invalid (VOID) type");
+ return m_aInstanceType;
+}
+//-----------------------------------------------------------------------------
+
+/// get the path where the template is located
+rtl::OUString Template::getPathString() const
+{
+ TemplateName aNames(m_aName,m_aModule);
+ return aNames.makePathString( );
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference<Template> makeSetElementTemplate(sharable::SetNode * set, TemplateProvider const& _aProvider)
+{
+ TemplateName aNames( set->getElementTemplateName(), set->getElementTemplateModule() );
+ return TemplateImplHelper::makeElementTemplateWithType(aNames, _aProvider, set);
+}
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/templateimpl.cxx b/configmgr/source/treemgr/templateimpl.cxx
new file mode 100644
index 000000000000..24702aa1c362
--- /dev/null
+++ b/configmgr/source/treemgr/templateimpl.cxx
@@ -0,0 +1,364 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: templateimpl.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+#include "templateimpl.hxx"
+#include "treemanager.hxx"
+#include "node.hxx"
+#include "nodevisitor.hxx"
+#include "strdecl.hxx"
+#include "typeconverter.hxx"
+#include "localizedtreeactions.hxx"
+#include "treeactions.hxx"
+#include "apitypes.hxx"
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Type TemplateName::resolveSimpleTypeName(rtl::OUString const& aName)
+{
+ rtl::OUString sTypeName = aName;
+ return parseTemplateName(sTypeName);
+}
+//-----------------------------------------------------------------------------
+#if OSL_DEBUG_LEVEL > 0
+rtl::OUString TemplateName::makeNativeTypeModuleName()
+{
+ return rtl::OUString( TEMPLATE_MODULE_NATIVE_VALUE );
+}
+
+//-----------------------------------------------------------------------------
+rtl::OUString TemplateName::makeLocalizedTypeModuleName()
+{
+ return rtl::OUString( TEMPLATE_MODULE_LOCALIZED_VALUE );
+}
+#endif
+//-----------------------------------------------------------------------------
+bool TemplateName::isSimpleTypeName() const
+{
+ bool bIsSimple = (aModule.compareToAscii(TEMPLATE_MODULE_NATIVE_PREFIX,
+ TEMPLATE_MODULE_NATIVE_PREFIX.getLength()) == 0);
+
+ OSL_ENSURE(!bIsSimple ||
+ aModule == makeNativeTypeModuleName() ||
+ aModule == makeLocalizedTypeModuleName(),
+ "ERROR: Invalid template module with native prefix found");
+
+ return bIsSimple;
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Type TemplateName::resolveToSimpleType() const
+{
+ com::sun::star::uno::Type aType;
+ if ( isSimpleTypeName() )
+ {
+ aType = resolveSimpleTypeName( aName );
+ }
+ else
+ OSL_ENSURE(false, "TemplateName::resolveToSimpleType must be called only for simple type name pairs");
+ return aType;
+}
+//-----------------------------------------------------------------------------
+// class TemplateImplHelper
+//-----------------------------------------------------------------------------
+
+rtl::Reference<Template> TemplateImplHelper::createNew (TemplateName const& aNames,com::sun::star::uno::Type const& aType)
+{
+ return new Template(aNames.aName, aNames.aModule, aType);
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference<Template> TemplateImplHelper::makeElementTemplateWithType(TemplateName const& _aNames, TemplateProvider const& _aProvider, sharable::SetNode * set)
+{
+ OSL_ENSURE(_aProvider.m_aImpl.is(), "ERROR: Cannot find a template without a provider");
+
+ if (_aProvider.m_aImpl.is())
+ return _aProvider.m_aImpl->makeElementTemplateWithType(_aNames, set);
+
+ else
+ return rtl::Reference<Template>(0);
+}
+//-----------------------------------------------------------------------------
+
+void TemplateImplHelper::assignActualType (Template& aTemplate,com::sun::star::uno::Type const& aType)
+{
+ OSL_PRECOND( aType != getNoTypeAvailable(), "ERROR: Assigning NO type to a template" );
+
+ if (!aTemplate.isInstanceTypeKnown())
+ aTemplate.m_aInstanceType = aType;
+
+ OSL_ENSURE(aTemplate.isInstanceTypeKnown(), "ERROR: Could not assign given type to a template");
+ OSL_ENSURE(aTemplate.getInstanceType() == aType, "ERROR: Trying to change instance type of a template");
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class TemplateProvider_Impl
+//-----------------------------------------------------------------------------
+
+TemplateProvider_Impl::TemplateProvider_Impl(rtl::Reference< TreeManager > const & xProvider, RequestOptions const& aOptions)
+: m_xProvider(xProvider)
+, m_aOptions(aOptions)
+, m_aRepository()
+{
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< data::TreeSegment > TemplateProvider_Impl::instantiate(rtl::Reference<Template> const& aTemplate)
+{
+ if (aTemplate.is())
+ {
+ sharable::TreeFragment * aTemplateData = m_xProvider->requestTemplate(aTemplate->getName(), aTemplate->getModule());
+
+ return cloneExpandedForLocale(aTemplateData, m_aOptions.getLocale());
+ } else {
+ return rtl::Reference< data::TreeSegment >();
+ }
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+namespace
+{
+//-----------------------------------------------------------------------------
+ struct TypeDetector : data::SetVisitor
+ {
+ enum State
+ {
+ Contradicting = -1,
+ NotFound = 0,
+ SomeValue,
+ VariousValue,
+ SomeTree
+ };
+
+ State result;
+ com::sun::star::uno::Type type;
+
+ TypeDetector() : result(NotFound), type() {}
+
+ private:
+ using SetVisitor::handle;
+ virtual bool handle(sharable::Node * node);
+ virtual bool handle(sharable::ValueNode * node);
+ };
+//-----------------------------------------------------------------------------
+ static com::sun::star::uno::Type detectNodeType(sharable::TreeFragment * element)
+ {
+ if (element == 0)
+ throw configuration::Exception("Could not load required template to detect set elements");
+
+ TypeDetector aDetector;
+ aDetector.visitTree(element);
+
+ switch(aDetector.result)
+ {
+ case TypeDetector::SomeTree: // found tree
+ case TypeDetector::VariousValue: // found an Any
+ case TypeDetector::SomeValue: // found a particular value type
+ break;
+
+#ifdef DBG_UTIL
+ case TypeDetector::NotFound: OSL_ENSURE(false,"Impossible Result: Node not handled"); if (false) // dirty abuse of case
+ case TypeDetector::Contradicting: OSL_ENSURE(false,"Impossible Result: Node contradicts itself"); if (false) // dirty abuse of case
+#endif // DBG_UTIL
+ default: OSL_ENSURE(false,"Impossible Result: Unknown result code");
+
+ throw configuration::Exception("INTERNAL ERROR: Could not detect set element type from loaded instance");
+ }
+ return aDetector.type;
+ }
+
+ //-------------------------------------------------------------------------
+ static bool detectElementType(com::sun::star::uno::Type& aType, sharable::SetNode * set)
+ {
+ TypeDetector aDetector;
+ aDetector.visitElements(set);
+
+ bool bResult = false;
+ switch(aDetector.result)
+ {
+ case TypeDetector::SomeTree: // found tree
+ case TypeDetector::VariousValue: // found an Any
+ aType = aDetector.type;
+ bResult = true;
+ break;
+
+ case TypeDetector::SomeValue: // found a value or an any
+ case TypeDetector::NotFound: // found no element
+ break;
+
+ case TypeDetector::Contradicting:
+ OSL_ENSURE(false,"Invalid Set: contains values and subtrees");
+ break;
+
+ default: OSL_ENSURE(false,"Unreachable code"); break;
+ }
+ return bResult;
+ }
+//-----------------------------------------------------------------------------
+
+}
+//-----------------------------------------------------------------------------
+rtl::Reference<Template> TemplateProvider_Impl::makeElementTemplateWithType(TemplateName const& _aNames, sharable::SetNode * set)
+{
+ TemplateRepository::iterator it = m_aRepository.find(_aNames);
+
+ if (it == m_aRepository.end() || !it->second->isInstanceTypeKnown())
+ {
+ com::sun::star::uno::Type aType;
+ if (_aNames.isSimpleTypeName()) // native type found
+ {
+ aType = _aNames.resolveToSimpleType();
+
+ if (aType == TemplateImplHelper::getNoTypeAvailable())
+ throw configuration::Exception("INTERNAL ERROR: Could not resolve native type");
+ }
+
+ else if (!detectElementType(aType, set))
+ {
+ OSL_ASSERT(_aNames.aName == set->getElementTemplateName());
+ OSL_ASSERT(_aNames.aModule == set->getElementTemplateModule());
+
+ sharable::TreeFragment * aTemplateData = m_xProvider->requestTemplate(_aNames.aName, _aNames.aModule);
+
+ aType = detectNodeType(aTemplateData); // throws if necessary
+ }
+ OSL_ASSERT( aType != TemplateImplHelper::getNoTypeAvailable() );
+
+ if (it == m_aRepository.end())
+ it = m_aRepository.insert( TemplateRepository::value_type( _aNames, TemplateImplHelper::createNew(_aNames,aType) ) ).first;
+
+ else
+ TemplateImplHelper::assignActualType(*it->second, aType);
+
+ OSL_ENSURE(it->second->isInstanceTypeKnown(), "No type assigned to Template");
+ OSL_ENSURE(it->second->getInstanceType() == aType, "Inconsistent type found for Template");
+ }
+
+#ifdef DBG_UTIL
+ else
+ {
+ OSL_ENSURE(it->second->isInstanceTypeKnown(), "No type assigned to Template");
+ com::sun::star::uno::Type aTestType;
+ if (detectElementType(aTestType, set))
+ OSL_ENSURE(it->second->getInstanceType() == aTestType, "Inconsistent type found for Template");
+ }
+#endif // DBG_UTIL
+
+ return it->second;
+
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+namespace
+{
+//-----------------------------------------------------------------------------
+ bool TypeDetector::handle(sharable::ValueNode * node)
+ {
+ com::sun::star::uno::Type aFoundType = node->getValueType();
+
+ bool isNullType = (aFoundType.getTypeClass() == uno::TypeClass_VOID);
+ bool isAnyType = (aFoundType.getTypeClass() == uno::TypeClass_ANY);
+
+ switch (this->result) // transition depends on previous state
+ {
+ case NotFound:
+ this->type = aFoundType;
+
+ if (isAnyType)
+ this->result = VariousValue;
+
+ else if (!isNullType)
+ this->result = SomeValue;
+
+ break;
+
+ case SomeValue:
+ if (!isNullType && this->type != aFoundType)
+ {
+ this->result = VariousValue;
+ this->type = configapi::getAnyType();
+ OSL_ASSERT(type.getTypeClass() == uno::TypeClass_ANY);
+ }
+ break;
+
+ case VariousValue: // remain unchanged - type already is 'Any'
+ break;
+
+ case SomeTree: OSL_ENSURE(false, "Found value node does not match previous (tree) sibling");
+ default:
+ this->result = Contradicting;
+ break;
+ }
+ return false; // always continue to detect errors in data
+ }
+//-----------------------------------------------------------------------------
+ bool TypeDetector::handle(sharable::Node * node)
+ {
+ (void) node; // avoid warnings
+ OSL_ENSURE(!node->isValue(), "Value node dipatched to wrong handler");
+ switch (this->result) // transition depends on previous state
+ {
+ case NotFound:
+ this->type = configapi::getUnoInterfaceType();
+ this->result = SomeTree;
+ break;
+
+ case SomeTree: // remain unchanged - type already is Tree
+ break;
+
+ case SomeValue:
+ case VariousValue: OSL_ENSURE(false, "Found Subtree node does not match previous (value) sibling");
+ default:
+ this->result = Contradicting;
+ break;
+ }
+ return false; // always continue to detect errors in data
+ }
+
+//-----------------------------------------------------------------------------
+} // anonymous
+//-----------------------------------------------------------------------------
+ } // configuration
+} // configmgr
+
diff --git a/configmgr/source/treemgr/templateimpl.hxx b/configmgr/source/treemgr/templateimpl.hxx
new file mode 100644
index 000000000000..2422ab3bc42c
--- /dev/null
+++ b/configmgr/source/treemgr/templateimpl.hxx
@@ -0,0 +1,175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: templateimpl.hxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_TEMPLATEIMPL_HXX_
+#define CONFIGMGR_TEMPLATEIMPL_HXX_
+
+#include "template.hxx"
+#include "configpath.hxx"
+#include "requestoptions.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include "utility.hxx"
+
+#ifndef INCLUDED_MAP
+#include <map>
+#define INCLUDED_MAP
+#endif
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace data { class TreeSegment; }
+//-----------------------------------------------------------------------------
+
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+
+
+ //-----------------------------------------------------------------------------
+ // class TemplateName
+ //-----------------------------------------------------------------------------
+ struct TemplateName
+ {
+ //-----------------------------------------------------------------
+ rtl::OUString aName, aModule;
+
+ //-----------------------------------------------------------------
+ TemplateName()
+ : aName()
+ , aModule()
+ {}
+
+ TemplateName(rtl::OUString const& aName_)
+ : aName(aName_)
+ , aModule()
+ {}
+
+ TemplateName(rtl::OUString const& aName_, rtl::OUString const& aModule_)
+ : aName(aName_)
+ , aModule(aModule_)
+ {}
+
+ //-----------------------------------------------------------------
+
+ /// compose the path where the template is located
+ rtl::OUString makePathString() const
+ {
+ rtl::OUStringBuffer aBuffer;
+
+ if (aModule.getLength() != 0)
+ aBuffer.append( this->aModule ).append(sal_Unicode('/'));
+
+ aBuffer.append( this->aName );
+
+ return aBuffer.makeStringAndClear();
+ }
+ //-----------------------------------------------------------------
+ bool isEmpty() const
+ {
+ return aName.getLength() == 0;
+ }
+
+ bool isSimpleTypeName() const;
+
+ com::sun::star::uno::Type resolveToSimpleType() const;
+ //-----------------------------------------------------------------
+
+ bool operator<(TemplateName const& aOther) const
+ {
+ return (aModule == aOther.aModule) ? (aName < aOther.aName) : (aModule < aOther.aModule);
+ }
+
+ //-----------------------------------------------------------------
+ static com::sun::star::uno::Type resolveSimpleTypeName(rtl::OUString const& aName);
+ //-----------------------------------------------------------------
+#if OSL_DEBUG_LEVEL > 0
+ static rtl::OUString makeNativeTypeModuleName();
+ //-----------------------------------------------------------------
+ static rtl::OUString makeLocalizedTypeModuleName();
+#endif
+ //-----------------------------------------------------------------
+ };
+ //-------------------------------------------------------------------------
+
+ //---------------------------------------------------------------------
+ // class TemplateImplHelper
+ //---------------------------------------------------------------------
+
+ class TemplateImplHelper
+ {
+ public:
+ //-----------------------------------------------------------------
+
+ static com::sun::star::uno::Type getNoTypeAvailable()
+ {
+ return getVoidCppuType();
+ }
+ //-----------------------------------------------------------------
+
+ static void assignActualType (Template& aTemplate,com::sun::star::uno::Type const& aType);
+ //-----------------------------------------------------------------
+
+ static rtl::Reference<Template> makeElementTemplateWithType(TemplateName const& aNames, TemplateProvider const& _aProvider, sharable::SetNode * set);
+ //-----------------------------------------------------------------
+
+ static rtl::Reference<Template> createNew (TemplateName const& aNames,com::sun::star::uno::Type const& aType);
+ //-----------------------------------------------------------------
+ };
+ //-------------------------------------------------------------------------
+
+ typedef std::map< TemplateName, rtl::Reference<Template> > TemplateRepository;
+ //-------------------------------------------------------------------------
+
+ //---------------------------------------------------------------------
+ // class TemplateProvider_Impl
+ //---------------------------------------------------------------------
+
+ struct TemplateProvider_Impl : salhelper::SimpleReferenceObject
+ {
+ TemplateProvider_Impl(rtl::Reference< TreeManager > const & xProvider, RequestOptions const& aOptions);
+
+ rtl::Reference< data::TreeSegment > instantiate(rtl::Reference<Template> const& aTemplate);
+
+ rtl::Reference<Template> makeElementTemplateWithType(TemplateName const& _aNames, sharable::SetNode * set);
+ private:
+ rtl::Reference< TreeManager > m_xProvider;
+ RequestOptions m_aOptions;
+
+ TemplateRepository m_aRepository;
+ };
+
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_TEMPLATEIMPL_HXX_
diff --git a/configmgr/source/treemgr/treeimpl.cxx b/configmgr/source/treemgr/treeimpl.cxx
new file mode 100644
index 000000000000..66b26092e5e4
--- /dev/null
+++ b/configmgr/source/treemgr/treeimpl.cxx
@@ -0,0 +1,1373 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treeimpl.cxx,v $
+ * $Revision: 1.33 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+#include "anynoderef.hxx"
+#include "builddata.hxx"
+#include "configset.hxx"
+#include "tracer.hxx"
+#include "tree.hxx"
+#include "roottreeimpl.hxx"
+#include "nodeimpl.hxx"
+#include "nodechange.hxx"
+#include "nodechangeimpl.hxx"
+#include "noderef.hxx"
+#include "template.hxx"
+#include "nodevisitor.hxx"
+#include "valueref.hxx"
+#include "valuenode.hxx"
+#include "change.hxx"
+#include "valuenodeimpl.hxx"
+#include "setnodeimpl.hxx"
+#include "groupnodeimpl.hxx"
+#include "viewaccess.hxx"
+#include "viewfactory.hxx"
+#include "nodefactory.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+// class TreeImplBuilder - friend of Tree
+//-----------------------------------------------------------------------------
+
+/** is a visitor-style algorithm to construct a <type>Tree::NodeList</type>
+ representing a configuration hierarchy
+*/
+class TreeImplBuilder : public data::NodeVisitor
+{
+public:
+ /** constructs a TreeImplBuilder to append onto <var>rList</var>
+ the products of <var>rFactory</var> up to depth <var>nDepth</var>
+ */
+ TreeImplBuilder(
+ TemplateProvider const& aTemplateProvider,
+ rtl::Reference<view::ViewStrategy> const& _xStrategy,
+ Tree& rTree
+ )
+ : m_xStrategy(_xStrategy)
+ , m_aTemplateProvider(aTemplateProvider)
+ , m_rFactory(_xStrategy->getNodeFactory())
+ , m_rTree(rTree)
+ , m_nParent(0)
+ , m_nDepthLeft(rTree.m_nDepth)
+ {
+ OSL_ASSERT(m_rTree.m_aNodes.empty());
+ OSL_DEBUG_ONLY(m_bMemberCheck = false);
+ m_rTree.m_xStrategy = _xStrategy;
+ }
+
+private:
+ using NodeVisitor::handle;
+
+ virtual bool handle(sharable::ValueNode * node);
+
+ virtual bool handle(sharable::GroupNode * node);
+
+ virtual bool handle(sharable::SetNode * node);
+
+ /// add a Node for group node <var>_aGroup</var> to the list
+ void addGroup(sharable::GroupNode * group);
+ /// add a Node for set node <var>_aSet</var> to the list
+ void addSet(sharable::SetNode * set);
+ /// add a Node for value node <var>rValue</var> to the list
+ void addValueElement(sharable::ValueNode * value);
+ /// add a Member for value node <var>rValue</var> to the list
+ void addValueMember(sharable::ValueNode * value);
+
+ rtl::Reference<view::ViewStrategy> m_xStrategy;
+ TemplateProvider m_aTemplateProvider;
+ view::NodeFactory& m_rFactory;
+ Tree& m_rTree;
+ unsigned int m_nParent;
+ unsigned int m_nDepthLeft;
+#if OSL_DEBUG_LEVEL > 0
+ bool m_bMemberCheck;
+#endif
+};
+//-----------------------------------------------------------------------------
+
+bool TreeImplBuilder::handle(sharable::ValueNode * node)
+{
+ if (m_nParent == 0)
+ addValueElement(node); // if it is the root it is a value set element
+ else
+ addValueMember(node); // if it is not the root it is a group member
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+bool TreeImplBuilder::handle(sharable::GroupNode * node)
+{
+ addGroup(node);
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+bool TreeImplBuilder::handle(sharable::SetNode * node)
+{
+ addSet(node);
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+void TreeImplBuilder::addValueElement(sharable::ValueNode * value)
+{
+ rtl::Reference<NodeImpl> aValueNode( m_rFactory.makeValueNode(value) );
+ OSL_ENSURE( aValueNode.is(), "could not make value node wrapper" );
+
+ OSL_ENSURE( m_nParent == 0, "Adding value element that is not root of its fragment" );
+ // TODO:!isValid() => maybe substitute a SimpleValueNodeImpl if possible
+ if( aValueNode.is() )
+ {
+ m_rTree.m_aNodes.push_back( NodeData(aValueNode, value->info.getName(), m_nParent) );
+ }
+}
+//-----------------------------------------------------------------------------
+
+void TreeImplBuilder::addValueMember(sharable::ValueNode *)
+{
+ // nothing to do
+ OSL_DEBUG_ONLY(m_bMemberCheck = true);
+}
+//-----------------------------------------------------------------------------
+
+void TreeImplBuilder::addGroup(sharable::GroupNode * group)
+{
+ rtl::Reference<NodeImpl> aGroupNode( m_rFactory.makeGroupNode(group) );
+ OSL_ENSURE( aGroupNode.is(), "could not make group node wrapper" );
+
+ // TODO:!isValid() => maybe substitute a SimpleValueNodeImpl if possible
+ if( aGroupNode.is() )
+ {
+ m_rTree.m_aNodes.push_back( NodeData(aGroupNode,group->info.getName(),m_nParent) );
+
+ // now fill in group members
+ if (m_nDepthLeft > 0)
+ {
+ unsigned int nSaveParent = m_nParent;
+ decDepth(m_nDepthLeft);
+
+ m_nParent = m_rTree.m_aNodes.size() + Tree::ROOT - 1;
+
+ #if OSL_DEBUG_LEVEL > 0
+ bool bSaveMemberCheck = m_bMemberCheck;
+ m_bMemberCheck = false;
+ #endif
+
+ // now recurse:
+ this->visitChildren(group);
+
+ OSL_ENSURE(m_nParent < m_rTree.m_aNodes.size() || m_bMemberCheck,
+ "WARNING: Configuration: Group within requested depth has no members");
+
+ OSL_DEBUG_ONLY(m_bMemberCheck = bSaveMemberCheck);
+
+ incDepth(m_nDepthLeft);
+ m_nParent = nSaveParent;
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+
+void TreeImplBuilder::addSet(sharable::SetNode * set)
+{
+ rtl::Reference<Template> aTemplate = makeSetElementTemplate(set, m_aTemplateProvider);
+ OSL_ASSERT(aTemplate.is());
+ OSL_ENSURE(aTemplate->isInstanceTypeKnown(),"ERROR: Cannor create set instance without knowing the instance type");
+
+ rtl::Reference<NodeImpl> aSetNode( m_rFactory.makeSetNode(set, aTemplate.get()) );
+ OSL_ENSURE( aSetNode.is(), "could not make set node wrapper" );
+
+ // TODO:!isValid() => maybe substitute a SimpleValueNodeImpl if possible
+ if( aSetNode.is() )
+ {
+ m_rTree.m_aNodes.push_back( NodeData(aSetNode, set->info.getName(), m_nParent) );
+
+ // this also relies on one based offsets
+ unsigned int nNodeAdded = m_rTree.m_aNodes.size() + Tree::ROOT - 1;
+
+ OSL_ASSERT(&m_rTree.m_aNodes.back().nodeImpl() == aSetNode.get());
+ static_cast<SetNodeImpl&>(*aSetNode).initElements(m_aTemplateProvider, m_rTree, nNodeAdded, m_nDepthLeft);
+ }
+}
+
+namespace {
+ class FindNonDefaultElement: public SetNodeVisitor {
+ public:
+ static bool hasNonDefaultElement(
+ view::ViewTreeAccess const & view, view::SetNode const & set)
+ {
+ FindNonDefaultElement visitor;
+ return view.dispatchToElements(set, visitor) == DONE;
+ }
+
+ protected:
+ virtual Result visit(SetEntry const & entry) {
+ OSL_ASSERT(entry.isValid());
+ rtl::Reference< Tree > tree(entry.tree());
+ OSL_ASSERT(tree.is());
+ node::Attributes atts(tree->getAttributes(tree->getRootNode()));
+ // A set element is considered default iff it is not replaced/added:
+ bool dflt = !atts.isReplacedForUser();
+ return dflt ? CONTINUE : DONE;
+ }
+ };
+
+ class SetVisitorAdapter: public SetNodeVisitor {
+ public:
+ explicit SetVisitorAdapter(NodeVisitor & visitor): m_visitor(visitor) {}
+
+ protected:
+ virtual Result visit(SetEntry const & entry) {
+ OSL_ASSERT(entry.isValid());
+ rtl::Reference< Tree > tree(entry.tree());
+ if (tree.is()) {
+ OSL_ASSERT(
+ Result(NodeVisitor::DONE) == SetNodeVisitor::DONE &&
+ Result(NodeVisitor::CONTINUE) == SetNodeVisitor::CONTINUE);
+ return Result(tree->visit(tree->getRootNode(), m_visitor));
+ } else {
+ return CONTINUE;
+ }
+ }
+
+ private:
+ NodeVisitor & m_visitor;
+ };
+
+ class GroupVisitorAdapter: public GroupMemberVisitor {
+ public:
+ GroupVisitorAdapter(
+ rtl::Reference< Tree > const & parentTree,
+ NodeRef const & parentNode, NodeVisitor & visitor):
+ m_parentTree(parentTree), m_parentPos(parentNode.getOffset()),
+ m_visitor(visitor)
+ {
+ OSL_ASSERT(
+ !isEmpty(parentTree.get()) && parentNode.isValid() &&
+ parentTree->isValidNode(parentNode.getOffset()));
+ }
+
+ protected:
+ virtual Result visit(ValueMemberNode const & value) {
+ OSL_ASSERT(
+ value.isValid() &&
+ Result(NodeVisitor::DONE) == GroupMemberVisitor::DONE &&
+ Result(NodeVisitor::CONTINUE) == GroupMemberVisitor::CONTINUE);
+ return Result(
+ m_parentTree->visit(
+ ValueRef(value.getNodeName(), m_parentPos), m_visitor));
+ }
+
+ private:
+ rtl::Reference< Tree > m_parentTree;
+ unsigned int m_parentPos;
+ NodeVisitor & m_visitor;
+ };
+}
+
+//-----------------------------------------------------------------------------
+// class NodeData
+//-----------------------------------------------------------------------------
+
+NodeData::NodeData(rtl::Reference<NodeImpl> const& aSpecificNode, rtl::OUString const& aName, unsigned int nParent)
+: m_pSpecificNode(aSpecificNode)
+, m_aName_(aName)
+, m_nParent(nParent)
+{
+}
+
+//-----------------------------------------------------------------------------
+
+void NodeData::rebuild(rtl::Reference<view::ViewStrategy> const & _xNewStrategy, sharable::Node * newData)
+{
+ rtl::Reference<NodeImpl> aNewImpl;
+ if (this->isSetNode())
+ {
+ sharable::SetNode * newSet = newData == 0 ? 0 : newData->setData();
+ aNewImpl = _xNewStrategy->getNodeFactory().makeSetNode(newSet, 0);
+
+ SetNodeImpl & rOldSetData = this->setImpl();
+ SetNodeImpl & rNewSetData = static_cast<SetNodeImpl &>(*aNewImpl);
+
+ rNewSetData.rebuildFrom(rOldSetData, newSet);
+ }
+ else if (this->isGroupNode())
+ aNewImpl = _xNewStrategy->getNodeFactory().makeGroupNode(newData == 0 ? 0 : newData->groupData());
+
+ else if (this->isValueElementNode())
+ aNewImpl = _xNewStrategy->getNodeFactory().makeValueNode(newData == 0 ? 0 : newData->valueData());
+
+ m_pSpecificNode = aNewImpl;
+}
+
+//-----------------------------------------------------------------------------
+
+bool NodeData::isSetNode() const
+{
+ sharable::Node * node = getOriginalNodeAccess();
+ return node != 0 && node->isSet();
+}
+//-----------------------------------------------------------------------------
+
+bool NodeData::isValueElementNode() const
+{
+ sharable::Node * node = getOriginalNodeAccess();
+ return node != 0 && node->isValue();
+}
+//-----------------------------------------------------------------------------
+
+bool NodeData::isGroupNode() const
+{
+ sharable::Node * node = getOriginalNodeAccess();
+ return node != 0 && node->isGroup();
+}
+//-----------------------------------------------------------------------------
+
+SetNodeImpl& NodeData::implGetSetImpl() const
+{
+ OSL_ASSERT(m_pSpecificNode != 0);
+ OSL_ASSERT(isSetNode());
+
+ if (!isSetNode())
+ throw Exception( "INTERNAL ERROR: Node is not a set node. Cast failing." );
+
+ return static_cast<SetNodeImpl&>(*m_pSpecificNode);
+}
+//---------------------------------------------------------------------
+
+GroupNodeImpl& NodeData::implGetGroupImpl() const
+{
+ OSL_ASSERT(m_pSpecificNode != 0);
+ OSL_ASSERT(isGroupNode());
+
+ if (!isGroupNode())
+ throw Exception( "INTERNAL ERROR: Node is not a group node. Cast failing." );
+
+ return static_cast<GroupNodeImpl&>(*m_pSpecificNode);
+}
+//---------------------------------------------------------------------
+
+ValueElementNodeImpl& NodeData::implGetValueImpl() const
+{
+ OSL_ASSERT(m_pSpecificNode != 0);
+ OSL_ASSERT(isValueElementNode());
+
+ if (!isValueElementNode())
+ throw Exception( "INTERNAL ERROR: Node is not a value node. Cast failing." );
+
+ return static_cast<ValueElementNodeImpl&>(*m_pSpecificNode);
+}
+
+sharable::Node * NodeData::getOriginalNodeAccess() const
+{
+ return m_pSpecificNode->getOriginalNodeAccess();
+}
+
+NodeImpl & NodeData::implGetNodeImpl() const
+{
+ OSL_ASSERT(m_pSpecificNode != 0);
+ return *m_pSpecificNode;
+}
+
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// class Tree
+//-----------------------------------------------------------------------------
+
+/// creates a Tree for a detached, virgin instance of <var>aTemplate</var>
+Tree::Tree( )
+: m_aNodes()
+, m_pParentTree(0)
+, m_nParentNode(0)
+, m_nDepth(0)
+{
+}
+//-----------------------------------------------------------------------------
+
+Tree::Tree( Tree& rParentTree, unsigned int nParentNode )
+: m_aNodes()
+, m_pParentTree(&rParentTree)
+, m_nParentNode(nParentNode)
+, m_nDepth(0)
+{
+}
+//-----------------------------------------------------------------------------
+
+Tree::~Tree()
+{
+}
+//-----------------------------------------------------------------------------
+
+void Tree::disposeData()
+{
+ m_aNodes.clear();
+}
+
+bool Tree::isRootNode(NodeRef const & node) const {
+ OSL_ASSERT(
+ nodeCount() != 0 && (!node.isValid() || isValidNode(node.getOffset())));
+ return node.isValid() && node.getOffset() == ROOT;
+}
+
+NodeRef Tree::getRootNode() const {
+ OSL_ASSERT(nodeCount() != 0);
+ return NodeRef(ROOT, m_nDepth);
+}
+
+NodeRef Tree::getContextNodeRef() const {
+ OSL_ASSERT(nodeCount() != 0 && (m_pParentTree == 0 || m_nParentNode != 0));
+ return m_pParentTree == 0
+ ? NodeRef() : m_pParentTree->getNode(m_nParentNode);
+}
+
+bool Tree::isValidValueNode(ValueRef const & value) {
+ OSL_ASSERT(nodeCount() != 0);
+ if (!(value.isValid() &&
+ value.checkValidState() &&
+ isValidNode(value.m_nParentPos) &&
+ view::ViewTreeAccess(this).isGroupNodeAt(value.m_nParentPos) &&
+ getMemberNode(value).isValid()))
+ {
+ return false;
+ }
+ OSL_ASSERT(value.m_sNodeName.getLength() != 0); // old value handling?
+ return true;
+}
+
+#if OSL_DEBUG_LEVEL > 0
+bool Tree::isValidAnyNode(AnyNodeRef const & node) {
+ OSL_ASSERT(nodeCount() != 0);
+ return node.isValid() && isValidNode(node.m_nUsedPos) &&
+ (node.isNode() ||
+ (view::ViewTreeAccess(this).isGroupNodeAt(node.m_nUsedPos) &&
+ getMemberNode(node.toValue()).isValid()));
+}
+#endif
+
+bool Tree::hasElements(NodeRef const & node) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth" );
+ }
+ view::ViewTreeAccess v(this);
+ return v.isSetNode(node) && !v.isEmpty(v.toSetNode(node));
+}
+
+bool Tree::hasElement(NodeRef const & node, rtl::OUString const & name) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ return v.isSetNode(node) &&
+ v.findElement(v.toSetNode(node), name).isValid();
+}
+
+bool Tree::hasElement(NodeRef const & node, Path::Component const & name) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ if (v.isSetNode(node)) {
+ SetEntry e(v.findElement(v.toSetNode(node), name.getName()));
+ // Check if types match:
+ return e.isValid() &&
+ Path::matches(e.tree()->getExtendedRootName(), name);
+ } else {
+ return false;
+ }
+}
+
+rtl::Reference< ElementTree > Tree::getElement(NodeRef const & node, rtl::OUString const & name) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ if (v.isSetNode(node)) {
+ SetEntry e(v.findElement(v.toSetNode(node), name));
+ return rtl::Reference< ElementTree >(e.tree());
+ } else {
+ return rtl::Reference< ElementTree >();
+ }
+}
+
+rtl::Reference< ElementTree > Tree::getAvailableElement(
+ NodeRef const & node, rtl::OUString const & name)
+{
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ view::ViewTreeAccess v(this);
+ if (v.isSetNode(node)) {
+ SetEntry e(v.findAvailableElement(v.toSetNode(node), name));
+ return rtl::Reference< ElementTree >(e.tree());
+ } else {
+ return rtl::Reference< ElementTree >();
+ }
+}
+
+bool Tree::hasChildren(NodeRef const & node) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ if (v.isGroupNode(node)) {
+ view::GroupNode g(v.toGroupNode(node));
+ return v.hasValue(g) || g.getFirstChild().is();
+ } else {
+ return false;
+ }
+}
+
+bool Tree::hasChildValue(NodeRef const & node, rtl::OUString const & name) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ return v.isGroupNode(node) && v.hasValue(v.toGroupNode(node), name);
+}
+
+bool Tree::hasChildNode(NodeRef const & node, rtl::OUString const & name) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ return v.isGroupNode(node) && v.toGroupNode(node).findChild(name).is();
+}
+
+bool Tree::hasChild(NodeRef const & node, rtl::OUString const & name) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ if (v.isGroupNode(node)) {
+ view::GroupNode g(v.toGroupNode(node));
+ return v.hasValue(g, name) || g.findChild(name).is();
+ } else {
+ return false;
+ }
+}
+
+ValueRef Tree::getChildValue(NodeRef const & node, rtl::OUString const & name) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ return v.isGroupNode(node) && v.hasValue(v.toGroupNode(node), name)
+ ? ValueRef(name, node.getOffset()) : ValueRef();
+}
+
+NodeRef Tree::getChildNode(NodeRef const & node, rtl::OUString const & name)
+{
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ return NodeRef(
+ (v.isGroupNode(node)
+ ? v.toGroupNode(node).findChild(name).get_offset() : 0),
+ childDepth(node.getDepth()));
+}
+
+AnyNodeRef Tree::getAnyChild(NodeRef const & node, rtl::OUString const & name) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ unsigned int n = 0;
+ if (v.isGroupNode(node)) {
+ if (v.hasValue(v.toGroupNode(node), name)) {
+ return AnyNodeRef(name, node.getOffset());
+ }
+ n = v.toGroupNode(node).findChild(name).get_offset();
+ }
+ return AnyNodeRef(n, childDepth(node.getDepth()));
+}
+
+node::Attributes Tree::getAttributes(NodeRef const & node) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ return view::ViewTreeAccess(this).getAttributes(node);
+}
+
+node::Attributes Tree::getAttributes(AnyNodeRef const & node) {
+ OSL_ASSERT(nodeCount() != 0 && isValidAnyNode(node));
+ if (node.isNode()) {
+ return view::ViewTreeAccess(this).getAttributes(node.toNode());
+ } else {
+ return getMemberNode(node.toValue()).getAttributes();
+ }
+}
+
+node::Attributes Tree::getAttributes(ValueRef const & value) {
+ OSL_ASSERT(nodeCount() != 0 && isValidValueNode(value));
+ return getMemberNode(value).getAttributes();
+}
+
+com::sun::star::uno::Type Tree::getUnoType(ValueRef const & value) {
+ OSL_ASSERT(nodeCount() != 0 && isValidValueNode(value));
+ return getMemberNode(value).getValueType();
+}
+
+NodeRef Tree::getParent(NodeRef const & node) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ view::ViewTreeAccess v(this);
+ OSL_ASSERT(!v.makeNode(getRootNode()).getParent().is());
+ view::Node p(v.makeNode(node).getParent());
+ OSL_ASSERT(isValidNode(p.get_offset()));
+ return NodeRef(p.get_offset(), parentDepth(node.getDepth()));
+}
+
+NodeRef Tree::getParent(ValueRef const & value) {
+ OSL_ASSERT(nodeCount() != 0 && isValidValueNode(value));
+ unsigned int n = value.m_nParentPos;
+ OSL_ASSERT(n == 0 || value.m_sNodeName.getLength() != 0);
+ return getNode(n);
+}
+
+AbsolutePath Tree::getAbsolutePath(NodeRef const & node) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ Path::Rep r;
+ prependLocalPathTo(node.getOffset(), r);
+ r.prepend(getRootPath().rep());
+ return AbsolutePath(r);
+}
+
+com::sun::star::uno::Any Tree::getNodeValue(ValueRef const & value) {
+ OSL_ASSERT(isValidValueNode(value));
+ return getMemberNode(value).getValue();
+}
+
+bool Tree::hasNodeDefault(ValueRef const & value) {
+ OSL_ASSERT(nodeCount() != 0 && isValidValueNode(value));
+ return getMemberNode(value).canGetDefaultValue();
+}
+
+bool Tree::isNodeDefault(ValueRef const & value) {
+ OSL_ASSERT(nodeCount() != 0 && isValidValueNode(value));
+ return hasNodeDefault(value) && getMemberNode(value).isDefault();
+}
+
+bool Tree::hasNodeDefault(NodeRef const & node) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ // Not a set, then it has no default:
+ return view::ViewTreeAccess(this).isSetNode(node);
+}
+
+bool Tree::isNodeDefault(NodeRef const & node) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (!hasNodeDefault(node)) {
+ return false;
+ }
+ view::ViewTreeAccess v(this);
+ OSL_ASSERT(v.isSetNode(node)); // not a set, then it has no default
+ // A set is default if all its elements are default:
+ return !FindNonDefaultElement::hasNonDefaultElement(v, v.toSetNode(node));
+}
+
+bool Tree::hasNodeDefault(AnyNodeRef const & node) {
+ OSL_ASSERT(nodeCount() != 0 && isValidAnyNode(node));
+ return node.isNode()
+ ? hasNodeDefault(node.toNode()) : hasNodeDefault(node.toValue());
+}
+
+bool Tree::isNodeDefault(AnyNodeRef const & node) {
+ OSL_ASSERT(nodeCount() != 0 && isValidAnyNode(node));
+ return node.isNode()
+ ? isNodeDefault(node.toNode()) : isNodeDefault(node.toValue());
+}
+
+bool Tree::areValueDefaultsAvailable(NodeRef const & node) {
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ view::ViewTreeAccess v(this);
+ OSL_ASSERT(v.isGroupNode(node));
+ return v.isGroupNode(node) &&
+ v.areValueDefaultsAvailable(v.toGroupNode(node));
+}
+
+com::sun::star::uno::Any Tree::getNodeDefaultValue(ValueRef const & value) {
+ OSL_ASSERT(nodeCount() != 0 && isValidValueNode(value));
+ ValueMemberNode m(getMemberNode(value));
+ return m.canGetDefaultValue() ?
+ m.getDefaultValue() : com::sun::star::uno::Any();
+}
+
+bool Tree::hasChanges() {
+ return view::ViewTreeAccess(this).hasChanges();
+}
+
+bool Tree::collectChanges(NodeChanges & changes) {
+ OSL_ASSERT(nodeCount() != 0);
+ view::ViewTreeAccess v(this);
+ if (v.hasChanges()) {
+ v.collectChanges(changes);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void Tree::integrate(NodeChange & change, NodeRef const & node, bool local)
+{
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (change.test().isChange()) {
+ change.apply();
+ if (local) {
+ view::ViewTreeAccess(this).markChanged(node);
+ } else {
+ rtl::Reference< Tree > at(change.getAffectedTree());
+ NodeRef an(change.getAffectedNode());
+ OSL_ASSERT(
+ !isEmpty(at.get()) && an.isValid() &&
+ at->isValidNode(an.getOffset()));
+ view::ViewTreeAccess(at.get()).markChanged(an);
+ OSL_ASSERT(view::ViewTreeAccess(this).hasChanges());
+ }
+ }
+}
+
+void Tree::integrate(NodeChanges& changes, NodeRef const & node, bool local)
+{
+ for (std::vector< NodeChange >::iterator it(changes.begin());
+ it != changes.end(); ++it)
+ {
+ integrate(*it, node, local);
+ }
+}
+
+NodeVisitor::Result Tree::dispatchToChildren(
+ NodeRef const & node, NodeVisitor & visitor)
+{
+ OSL_ASSERT(
+ nodeCount() != 0 && node.isValid() && isValidNode(node.getOffset()));
+ if (node.getDepth() == 0) {
+ CFG_TRACE_WARNING(
+ "configuration: Querying node beyond available depth");
+ }
+ view::ViewTreeAccess v(this);
+ if (v.isGroupNode(node)) {
+ view::GroupNode const p(v.toGroupNode(node));
+ OSL_ASSERT(
+ (NodeVisitor::Result(GroupMemberVisitor::DONE) ==
+ NodeVisitor::DONE) &&
+ (NodeVisitor::Result(GroupMemberVisitor::CONTINUE) ==
+ NodeVisitor::CONTINUE));
+ GroupVisitorAdapter adapter(this, node, visitor);
+ NodeVisitor::Result ret = NodeVisitor::Result(
+ v.dispatchToValues(p, adapter));
+ unsigned int n = childDepth(node.getDepth());
+ for (view::Node c(p.getFirstChild());
+ c.is() && ret != NodeVisitor::DONE; c = p.getNextChild(c))
+ {
+ ret = visit(NodeRef(c.get_offset(), n), visitor);
+ }
+ return ret;
+ } else if (v.isSetNode(node)) {
+ OSL_ASSERT(
+ NodeVisitor::Result(SetNodeVisitor::DONE) == NodeVisitor::DONE &&
+ (NodeVisitor::Result(SetNodeVisitor::CONTINUE) ==
+ NodeVisitor::CONTINUE));
+ SetVisitorAdapter adapter(visitor);
+ return NodeVisitor::Result(
+ v.dispatchToElements(v.toSetNode(node), adapter));
+ } else {
+ OSL_TRACE("configuration: Trying to iterate a value node");
+ return NodeVisitor::CONTINUE;
+ }
+}
+
+NodeRef Tree::getNode(unsigned int offset) const {
+ if (offset == 0) {
+ return NodeRef();
+ } else {
+ OSL_ASSERT(isValidNode(offset));
+ return NodeRef(
+ offset, remainingDepth(getAvailableDepth(), depthTo(offset)));
+ }
+}
+
+rtl::Reference< Template > Tree::extractElementInfo(NodeRef const & node) {
+ OSL_ASSERT(node.isValid() && isValidNode(node.getOffset()));
+ view::ViewTreeAccess v(this);
+ OSL_ASSERT(v.isSetNode(node));
+ return v.getElementTemplate(v.toSetNode(node));
+}
+
+//-----------------------------------------------------------------------------
+void Tree::rebuild(rtl::Reference<view::ViewStrategy> const & _xNewStrategy, sharable::Node * newData)
+{
+ m_xStrategy = _xNewStrategy;
+ this->implRebuild(ROOT, newData);
+}
+
+//-----------------------------------------------------------------------------
+void Tree::implRebuild(unsigned int nNode, sharable::Node * newData)
+{
+ NodeData * pNode = nodeData(nNode);
+ if (pNode->isGroupNode())
+ {
+ // first rebuild the children
+ OSL_ASSERT(newData != 0 && newData->isGroup());
+ sharable::GroupNode * newGroup = &newData->group;
+
+ for (unsigned int nChild = firstChild_(nNode); isValidNode(nChild); nChild = findNextChild_(nNode,nChild))
+ {
+ sharable::Node * childAccess = newGroup->getChild(implGetOriginalName(nChild));
+ OSL_ASSERT(childAccess != 0);
+ implRebuild(nChild, childAccess);
+ }
+ }
+
+ pNode->rebuild(m_xStrategy, newData);
+}
+
+//-----------------------------------------------------------------------------
+
+void ElementTree::doFinishRootPath(Path::Rep& rPath) const
+{
+ rPath.prepend( doGetRootName() );
+ rPath.prepend( AbsolutePath::detachedRoot().rep() );
+}
+//-----------------------------------------------------------------------------
+
+void RootTree::doFinishRootPath(Path::Rep& rPath) const
+{
+ rPath.prepend( m_aRootPath.rep() );
+}
+
+//-----------------------------------------------------------------------------
+
+void Tree::implPrependRootPath(Path::Rep& rPath) const
+{
+ if (m_pParentTree)
+ {
+ rPath.prepend( doGetRootName() );
+ OSL_ASSERT(m_nParentNode);
+ m_pParentTree->prependLocalPathTo(m_nParentNode,rPath);
+ m_pParentTree->implPrependRootPath(rPath);
+ }
+ else
+ {
+ doFinishRootPath( rPath );
+ }
+}
+//-----------------------------------------------------------------------------
+
+AbsolutePath Tree::getRootPath() const
+{
+ Path::Rep aPath;
+ implPrependRootPath(aPath);
+ return AbsolutePath(aPath);
+}
+//-----------------------------------------------------------------------------
+void Tree::build(rtl::Reference<view::ViewStrategy> const& _xStrategy, sharable::Node * rootNode, unsigned int nDepth, TemplateProvider const& aTemplateProvider)
+{
+ OSL_ASSERT(m_aNodes.empty());
+ m_nDepth = nDepth;
+ TreeImplBuilder a(aTemplateProvider, _xStrategy,*this);
+ a.visitNode(rootNode);
+}
+//-----------------------------------------------------------------------------
+
+rtl::Reference< view::ViewStrategy > Tree::getViewBehavior() const
+{
+ return m_xStrategy;
+}
+
+// context handling
+//-----------------------------------------------------------------------------
+
+void Tree::setContext(Tree* pParentTree, unsigned int nParentNode)
+{
+ OSL_ENSURE(pParentTree,"ERROR: Moving tree to nowhere");
+
+ if (pParentTree)
+ {
+ OSL_ENSURE( pParentTree->isValidNode(nParentNode),"ERROR: Moving tree to invalid node");
+ if (!pParentTree->isValidNode(nParentNode))
+ throw Exception("INTERNAL ERROR: Moving tree to invalid parent node");
+
+ // OSL_ENSURE( pParentTree->isSetNodeAt(nParentNode),"WARNING: Moving tree to node that is not a set");
+ }
+ else
+ {
+ OSL_ENSURE( nParentNode == 0,"WARNING: Moving tree to node without a tree");
+ nParentNode = 0;
+ }
+
+ m_pParentTree = pParentTree;
+ m_nParentNode = nParentNode;
+}
+//-----------------------------------------------------------------------------
+
+void Tree::clearContext()
+{
+ m_pParentTree = 0;
+ m_nParentNode = 0;
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Node Collection navigation
+//-----------------------------------------------------------------------------
+
+unsigned int Tree::parent_(unsigned int nNode) const
+{
+ OSL_ASSERT(isValidNode(nNode));
+ return nodeData(nNode)->getParent();
+}
+//-----------------------------------------------------------------------------
+inline // is protected and should be used only here
+rtl::OUString Tree::implGetOriginalName(unsigned int nNode) const
+{
+ OSL_ASSERT(isValidNode(nNode));
+
+ return nodeData(nNode)->getName();
+}
+//-----------------------------------------------------------------------------
+
+Path::Component ElementTree::doGetRootName() const
+{
+ return makeExtendedName( m_aElementName );
+}
+
+//-----------------------------------------------------------------------------
+
+rtl::OUString ElementTree::getSimpleRootName() const
+{
+ // Tree::getSimpleRootName tends to parse &
+ // then split the same name, burning CPU L&R
+ return m_aElementName;
+}
+
+//-----------------------------------------------------------------------------
+
+Path::Component RootTree::doGetRootName() const
+{
+ return m_aRootPath.getLocalName();
+}
+//-----------------------------------------------------------------------------
+
+
+rtl::OUString Tree::getSimpleNodeName(unsigned int nNode) const
+{
+ if (nNode == ROOT) return getSimpleRootName();
+
+ return implGetOriginalName(nNode);
+}
+//-----------------------------------------------------------------------------
+
+rtl::OUString Tree::getSimpleRootName() const
+{
+ return doGetRootName().getName();
+}
+
+//-----------------------------------------------------------------------------
+
+Path::Component Tree::getExtendedRootName() const
+{
+ return doGetRootName();
+}
+//-----------------------------------------------------------------------------
+
+unsigned int Tree::depthTo(unsigned int nNode) const
+{
+ OSL_ASSERT(isValidNode(nNode));
+
+ unsigned int nDepth = 0;
+ while( 0 != (nNode=parent_(nNode)) )
+ {
+ ++nDepth;
+ }
+
+ return nDepth;
+}
+//-----------------------------------------------------------------------------
+
+void Tree::prependLocalPathTo(unsigned int nNode, Path::Rep& rNames)
+{
+ OSL_ASSERT(isValidNode(nNode));
+
+ for (; nNode != ROOT; nNode = parent_(nNode) )
+ {
+ OSL_ENSURE( isValidNode(nNode), "ERROR: Configuration: node has invalid parent");
+ rNames.prepend( Path::wrapSimpleName( implGetOriginalName(nNode) ) );
+ }
+
+ OSL_ASSERT(nNode == ROOT);
+}
+//-----------------------------------------------------------------------------
+
+// Node iteration and access
+unsigned int Tree::firstChild_ (unsigned int nParent) const
+{
+ return findNextChild_(nParent,nParent);
+}
+//-----------------------------------------------------------------------------
+
+unsigned int Tree::findNextChild_(unsigned int nParent, unsigned int nStartAfter) const
+{
+ OSL_ASSERT(isValidNode(nParent));
+ OSL_ASSERT(nStartAfter == 0 || isValidNode(nStartAfter));
+
+ unsigned int nPos = nStartAfter ? nStartAfter : ROOT - 1;
+ unsigned int const nAfterLast = nodeCount() + ROOT;
+ while (++nPos < nAfterLast)
+ {
+ if(parent_(nPos) == nParent) return nPos;
+ }
+ return 0;
+}
+//-----------------------------------------------------------------------------
+
+unsigned int Tree::findChild_(unsigned int nParent, rtl::OUString const& aName) const
+{
+ OSL_ASSERT(isValidNode(nParent));
+
+ unsigned int nPos = nParent;
+ unsigned int const nAfterLast = nodeCount() + ROOT;
+ while (++nPos < nAfterLast)
+ {
+ if(parent_(nPos) == nParent && implGetOriginalName(nPos) == aName)
+ return nPos;
+ }
+ return 0;
+}
+
+ValueMemberNode Tree::getMemberNode(ValueRef const & value) {
+ OSL_ASSERT(nodeCount() != 0);
+ view::ViewTreeAccess v(this);
+ return v.getValue(v.getGroupNodeAt(value.m_nParentPos), value.m_sNodeName);
+}
+
+//-----------------------------------------------------------------------------
+// class RootTree
+//-----------------------------------------------------------------------------
+
+RootTree::RootTree( rtl::Reference<view::ViewStrategy> const& _xStrategy,
+ AbsolutePath const& aRootPath,
+ sharable::Node * cacheNode, unsigned int nDepth,
+ TemplateProvider const& aTemplateProvider)
+: Tree()
+, m_aRootPath(aRootPath)
+{
+// OSL_ENSURE( aRootPath.getLocalName().getName() == cacheNode->getName(),
+// "Constructing root node: Path does not match node name");
+
+ Tree::build(_xStrategy,cacheNode,nDepth,aTemplateProvider);
+}
+
+bool isEmpty(Tree * tree)
+{
+ return tree == 0 || tree->nodeCount() == 0;
+}
+
+//-----------------------------------------------------------------------------
+// class ElementTree
+//-----------------------------------------------------------------------------
+
+ElementTree::ElementTree( rtl::Reference<view::ViewStrategy> const& _xStrategy,
+ sharable::TreeFragment * cacheTree, unsigned int nDepth,
+ rtl::Reference<Template> aTemplateInfo,
+ TemplateProvider const& aTemplateProvider )
+: Tree()
+, m_aInstanceInfo(aTemplateInfo)
+, m_aElementName(cacheTree->getName())
+, m_aDataAddress(cacheTree)
+, m_aOwnData()
+{
+ Tree::build( _xStrategy, cacheTree->getRootNode(), nDepth, aTemplateProvider );
+}
+//-----------------------------------------------------------------------------
+
+ElementTree::ElementTree( rtl::Reference<view::ViewStrategy> const& _xStrategy,
+ Tree& rParentTree, unsigned int nParentNode,
+ sharable::TreeFragment * cacheTree, unsigned int nDepth,
+ rtl::Reference<Template> aTemplateInfo,
+ TemplateProvider const& aTemplateProvider )
+: Tree( rParentTree, nParentNode )
+, m_aInstanceInfo(aTemplateInfo)
+, m_aElementName(cacheTree->getName())
+, m_aDataAddress(cacheTree)
+, m_aOwnData()
+{
+ Tree::build( _xStrategy, cacheTree->getRootNode(), nDepth, aTemplateProvider );
+}
+//-----------------------------------------------------------------------------
+
+ElementTree::ElementTree( rtl::Reference< data::TreeSegment > const& pNewTree,
+ rtl::Reference<Template> aTemplate,
+ TemplateProvider const& aTemplateProvider )
+: Tree()
+, m_aInstanceInfo(aTemplate)
+, m_aOwnData(pNewTree)
+{
+ if (!pNewTree.is())
+ throw Exception("ERROR: Provider can't create Element Instance From Template");
+ m_aElementName = pNewTree->fragment->getName();
+ m_aDataAddress = pNewTree->fragment;
+
+ Tree::build( view::createDirectAccessStrategy(m_aOwnData), m_aOwnData->fragment->nodes, c_TreeDepthAll, aTemplateProvider );
+}
+//-----------------------------------------------------------------------------
+
+ElementTree::~ElementTree()
+{
+}
+//-----------------------------------------------------------------------------
+
+bool ElementTree::isUpdatableSegment(Tree& _rTree)
+{
+ Tree * pTree = &_rTree;
+
+ while (ElementTree * pElement = dynamic_cast< ElementTree * >(pTree))
+ {
+ if (pElement->m_aOwnData.is())
+ {
+ OSL_ENSURE( pElement->getContextTree()==NULL ||
+ pElement->getContextTree()->getViewBehavior() != pElement->getViewBehavior(),
+ "ElementTree with parent in same fragment should not own its data");
+ return true;
+ }
+
+ pTree = pElement->getContextTree();
+
+ if (!pTree)
+ {
+ OSL_ENSURE( false, "ElementTree without own data should have a parent");
+ return false;
+ }
+
+ }
+ OSL_ENSURE( false, "Tree is not part of free-floating segment - cannot support direct update");
+
+ return false;
+}
+//-----------------------------------------------------------------------------
+
+void ElementTree::disposeData()
+{
+ Tree::disposeData();
+ m_aOwnData.clear();
+}
+//-----------------------------------------------------------------------------
+
+Path::Component ElementTree::makeExtendedName(rtl::OUString const& _aSimpleName) const
+{
+ rtl::OUString aTypeName = implGetOriginalName(ROOT);
+
+ OSL_ENSURE(this->isTemplateInstance(), "ElementTree: Cannot discover the type this instantiatiates");
+
+ OSL_ENSURE(! this->isTemplateInstance() || this->getTemplate()->getName() == aTypeName,
+ "ElementTree: Type name does not match template");
+
+ return Path::makeCompositeName(_aSimpleName, aTypeName);
+}
+//-----------------------------------------------------------------------------
+
+// ownership handling
+//-----------------------------------------------------------------------------
+void ElementTree::rebuild(rtl::Reference<view::ViewStrategy> const & _aStrategy, sharable::TreeFragment * newTree)
+{
+ Tree::rebuild(_aStrategy, newTree->getRootNode());
+ m_aDataAddress = newTree;
+ m_aElementName = newTree->getName();
+}
+
+//-----------------------------------------------------------------------------
+/// transfer ownership to the given set
+// -----------------------------------------------------------------------------
+void ElementTree::attachTo(sharable::SetNode * owningSet, rtl::OUString const& aElementName)
+{
+ OSL_ENSURE(m_aOwnData.is(), "ERROR: Cannot add a non-owned node to a subtree");
+
+ if (m_aOwnData.is())
+ {
+ OSL_ENSURE(this->getSimpleRootName() == aElementName,"ElementTree: Attaching with unexpected element name");
+ m_aOwnData->fragment->setName(aElementName);
+
+ Tree* pOwningTree = this->getContextTree();
+ OSL_ENSURE(pOwningTree, "Element Tree Context must be set before attaching data");
+
+ if (isUpdatableSegment(*pOwningTree))
+ {
+ // copy over to the new segment
+ sharable::TreeFragment * aNewElement = data::buildTree(m_aOwnData->fragment);
+
+ owningSet->addElement(aNewElement);
+
+ rtl::Reference<view::ViewStrategy> xNewBehavior = pOwningTree->getViewBehavior();
+
+ this->rebuild(xNewBehavior,aNewElement);
+ }
+ else
+ OSL_ENSURE( false, "Cannot attach directly to new tree - no update access available");
+
+ m_aOwnData.clear();
+ OSL_ASSERT(!m_aOwnData.is());
+ }
+}
+//-----------------------------------------------------------------------------
+
+/// tranfer ownership from the given set
+void ElementTree::detachFrom(sharable::SetNode * owningSet, rtl::OUString const& aElementName)
+{
+ OSL_ENSURE(!m_aOwnData.is(),"ERROR: Cannot detach a already owned node from a subtree");
+ OSL_ENSURE(this->getSimpleRootName() == aElementName,"ElementTree: Detaching with unexpected element name");
+
+ rtl::Reference< view::ViewStrategy > xOldStrategy = this->getViewBehavior();
+ OSL_ENSURE(xOldStrategy.is(), "Element Tree Context must still have the old strategy when detaching data");
+
+ {
+ // make a new segment with a copy of the data
+ rtl::Reference< data::TreeSegment > aNewSegment = data::TreeSegment::create( this->getOriginalTreeAccess() );
+
+ OSL_ENSURE(aNewSegment.is(),"ERROR: Could not create detached copy of elment data");
+
+ this->takeTreeAndRebuild( aNewSegment );
+
+ sharable::TreeFragment * aOldElement = owningSet->removeElement(aElementName );
+ OSL_ENSURE(aOldElement != NULL,"ERROR: Detached node not found in the given subtree");
+
+ data::destroyTree(aOldElement);
+ }
+
+ OSL_ENSURE(m_aOwnData.is(),"ERROR: Could not create own data segment for detached node");
+}
+//-----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+/// transfer ownership from the given owner
+void ElementTree::takeTreeBack(rtl::Reference< data::TreeSegment > const & _aDataSegment)
+{
+ OSL_ENSURE(!m_aOwnData.is(), "ERROR: Cannot take over a node - already owning");
+ OSL_ENSURE(_aDataSegment.is(), "ERROR: Cannot take over NULL tree segment");
+
+ m_aOwnData = _aDataSegment;
+ OSL_ENSURE(m_aOwnData.is(), "ERROR: Could not take over data segment");
+
+ m_aDataAddress = m_aOwnData->fragment;
+ m_aElementName = m_aOwnData->fragment->getName();
+}
+//-----------------------------------------------------------------------------
+
+/// transfer ownership from the given owner
+void ElementTree::takeTreeAndRebuild(rtl::Reference< data::TreeSegment > const & _aDataSegment)
+{
+ OSL_ENSURE(!m_aOwnData.is(), "ERROR: Cannot take over a node - already owning");
+ OSL_ENSURE(_aDataSegment.is(), "ERROR: Cannot take over NULL tree segment");
+ this->rebuild(view::createDirectAccessStrategy(_aDataSegment), _aDataSegment->fragment);
+ m_aOwnData = _aDataSegment;
+}
+//-----------------------------------------------------------------------------
+
+/// release ownership
+rtl::Reference< data::TreeSegment > ElementTree::releaseOwnedTree()
+{
+ OSL_ENSURE(m_aOwnData.is(), "ERROR: Cannot release and rename a non-owned node");
+ rtl::Reference< data::TreeSegment > aTree(m_aOwnData);
+ m_aOwnData.clear();
+ aTree->fragment->setName(m_aElementName);
+ return aTree;
+}
+//-----------------------------------------------------------------------------
+
+// context handling
+//-----------------------------------------------------------------------------
+
+/// renames the tree's root without concern for context consistency !
+void ElementTree::renameTree(rtl::OUString const& aNewName)
+{
+ m_aElementName = aNewName;
+}
+//-----------------------------------------------------------------------------
+
+void ElementTree::moveTree(Tree* pParentTree, unsigned int nParentNode)
+{
+ Tree::setContext(pParentTree,nParentNode);
+}
+//-----------------------------------------------------------------------------
+
+void ElementTree::detachTree()
+{
+ Tree::clearContext();
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+ } // namespace configuration
+} // namespace configmgr
+
diff --git a/configmgr/source/treemgr/valuemembernode.cxx b/configmgr/source/treemgr/valuemembernode.cxx
new file mode 100644
index 000000000000..20ed6df1e28d
--- /dev/null
+++ b/configmgr/source/treemgr/valuemembernode.cxx
@@ -0,0 +1,336 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valuemembernode.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <stdio.h>
+
+#include "valuemembernode.hxx"
+#include "nodeimplobj.hxx"
+#include "nodechangeimpl.hxx"
+#include "change.hxx"
+#include "valuenode.hxx"
+#include <osl/diagnose.h>
+
+namespace configmgr
+{
+ namespace configuration
+ {
+
+// helpers
+//-----------------------------------------------------------------------------
+
+namespace
+{
+
+//-----------------------------------------------------------------------------
+// internal accessors for direct updates to data
+//-----------------------------------------------------------------------------
+
+inline
+void setOriginalValue(sharable::ValueNode * const& rOriginalAddress, com::sun::star::uno::Any const& aNewValue)
+{
+ rOriginalAddress->setValue(aNewValue);
+}
+//-----------------------------------------------------------------------------
+
+inline
+void setOriginalToDefault(sharable::ValueNode * const& rOriginalAddress)
+{
+ rOriginalAddress->setToDefault();
+}
+} // anonymous namespace
+
+
+//-----------------------------------------------------------------------------
+// class ValueMemberNode
+//-----------------------------------------------------------------------------
+
+ValueMemberNode::ValueMemberNode(sharable::ValueNode * node)
+ : m_node(node)
+ , m_xDeferredOperation()
+{}
+//-----------------------------------------------------------------------------
+ValueMemberNode::ValueMemberNode(rtl::Reference<DeferredImpl> const& _xDeferred) // must be valid
+ : m_node( _xDeferred->getOriginalNode() )
+ , m_xDeferredOperation(_xDeferred)
+{}
+//-----------------------------------------------------------------------------
+
+ValueMemberNode::ValueMemberNode(ValueMemberNode const& rOriginal)
+ : m_node(rOriginal.m_node)
+ , m_xDeferredOperation(rOriginal.m_xDeferredOperation)
+{}
+//-----------------------------------------------------------------------------
+ValueMemberNode& ValueMemberNode::operator=(ValueMemberNode const& rOriginal)
+{
+ m_node = rOriginal.m_node;
+ m_xDeferredOperation = rOriginal.m_xDeferredOperation;
+ return *this;
+}
+//-----------------------------------------------------------------------------
+ValueMemberNode::~ValueMemberNode()
+{
+}
+//-----------------------------------------------------------------------------
+
+bool ValueMemberNode::isValid() const
+{
+ OSL_ASSERT( !m_xDeferredOperation.is() ||
+ m_node == m_xDeferredOperation->getOriginalNode());
+
+ return m_node != 0;
+}
+//-----------------------------------------------------------------------------
+
+bool ValueMemberNode::hasChange() const
+{
+ return m_xDeferredOperation.is()
+ && m_xDeferredOperation->isChange();
+}
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// external accessors
+//-----------------------------------------------------------------------------
+
+rtl::OUString ValueMemberNode::getNodeName() const
+{
+ return m_node->info.getName();
+}
+//-----------------------------------------------------------------------------
+
+node::Attributes ValueMemberNode::getAttributes() const
+{
+ return sharable::node(m_node)->getAttributes();
+}
+//-----------------------------------------------------------------------------
+
+
+bool ValueMemberNode::isDefault() const
+{
+ if (hasChange())
+ return m_xDeferredOperation->isToDefault();
+
+ return m_node->info.isDefault();
+}
+//-----------------------------------------------------------------------------
+
+bool ValueMemberNode::canGetDefaultValue() const
+{
+ return m_node->hasUsableDefault();
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any ValueMemberNode::getValue() const
+{
+ if (hasChange())
+ return m_xDeferredOperation->getNewValue();
+
+ return m_node->getValue();
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Any ValueMemberNode::getDefaultValue() const
+{
+ return m_node->getDefaultValue();
+}
+//-----------------------------------------------------------------------------
+
+com::sun::star::uno::Type ValueMemberNode::getValueType() const
+{
+ return m_node->getValueType();
+}
+//-----------------------------------------------------------------------------
+
+
+void ValueMemberUpdate::setValue(com::sun::star::uno::Any const& aNewValue)
+{
+ if (m_aMemberNode.m_xDeferredOperation.is())
+ m_aMemberNode.m_xDeferredOperation->setValue(aNewValue, m_aMemberNode.m_node);
+ else
+ setOriginalValue(m_aMemberNode.m_node, aNewValue );
+}
+//-----------------------------------------------------------------------------
+
+void ValueMemberUpdate::setDefault()
+{
+ if (m_aMemberNode.m_xDeferredOperation.is())
+ m_aMemberNode.m_xDeferredOperation->setValueToDefault(m_aMemberNode.m_node);
+ else
+ setOriginalToDefault(m_aMemberNode.m_node);
+}
+
+//-----------------------------------------------------------------------------
+// class ValueMemberNode::DeferredImpl
+//-----------------------------------------------------------------------------
+
+ValueMemberNode::DeferredImpl::DeferredImpl(sharable::ValueNode * valueNode)
+: m_valueNode(valueNode)
+, m_aNewValue(valueNode->getValue())
+, m_bToDefault(false)
+, m_bChange(false)
+{}
+//-----------------------------------------------------------------------------
+
+void ValueMemberNode::DeferredImpl::setValue(com::sun::star::uno::Any const& aNewValue, sharable::ValueNode * originalNode)
+{
+ OSL_ENSURE(originalNode == m_valueNode, "Incorrect original node passed");
+
+ m_aNewValue = aNewValue;
+ m_bToDefault = false;
+
+ m_bChange = originalNode->info.isDefault() || aNewValue != originalNode->getValue();
+}
+//-----------------------------------------------------------------------------
+
+void ValueMemberNode::DeferredImpl::setValueToDefault(sharable::ValueNode * originalNode)
+{
+ OSL_ENSURE(originalNode == m_valueNode, "Incorrect original node passed");
+
+ m_aNewValue = originalNode->getDefaultValue();
+ m_bToDefault = true;
+
+ m_bChange = !originalNode->info.isDefault();
+}
+//-----------------------------------------------------------------------------
+
+std::auto_ptr<ValueChange> ValueMemberNode::DeferredImpl::preCommitChange()
+{
+ OSL_ENSURE(isChange(), "Trying to commit a non-change");
+
+ sharable::ValueNode * originalNode = getOriginalNode();
+
+ // first find the mode of the change
+ ValueChange::Mode eMode;
+
+ if (m_bToDefault)
+ eMode = ValueChange::setToDefault;
+
+ else if (! originalNode->info.isDefault())
+ eMode = ValueChange::changeValue;
+
+ else
+ eMode = ValueChange::wasDefault;
+
+ // now make a ValueChange
+ std::auto_ptr<ValueChange>pChange( new ValueChange( originalNode->info.getName(),
+ sharable::node(originalNode)->getAttributes(),
+ eMode,
+ this->getNewValue(),
+ originalNode->getValue()
+ ) );
+
+ return pChange;
+}
+//-----------------------------------------------------------------------------
+
+void ValueMemberNode::DeferredImpl::finishCommit(ValueChange& rChange)
+{
+ { (void)rChange; }
+ OSL_ENSURE(rChange.getNewValue() == this->getNewValue(),"Committed change does not match the intended value");
+
+ sharable::ValueNode * originalNode = getOriginalNode();
+
+ m_aNewValue = originalNode->getValue();
+ m_bToDefault = false;
+
+ OSL_ENSURE(rChange.getNewValue() == m_aNewValue,"Committed change does not match the actual value");
+ m_bChange= false;
+}
+//-----------------------------------------------------------------------------
+
+void ValueMemberNode::DeferredImpl::revertCommit(ValueChange& rChange)
+{
+ { (void)rChange; }
+
+ OSL_ENSURE(rChange.getNewValue() == this->getNewValue(),"Reverted change does not match the intended value");
+ OSL_ENSURE(isChange(), "ValueMemeberNode::DeferredImpl: No Changes to revert");
+}
+//-----------------------------------------------------------------------------
+
+void ValueMemberNode::DeferredImpl::failedCommit(ValueChange&)
+{
+ sharable::ValueNode * originalNode = getOriginalNode();
+
+ // discard the change
+ m_aNewValue = originalNode->getValue();
+ m_bToDefault = false;
+
+ m_bChange= false;
+}
+//-----------------------------------------------------------------------------
+ValueChangeImpl* ValueMemberNode::DeferredImpl::collectChange()
+{
+ sharable::ValueNode * originalNode = getOriginalNode();
+
+ com::sun::star::uno::Any aOldValue = originalNode->getValue();
+ if (!m_bChange)
+ {
+ return NULL;
+ }
+ else if (m_bToDefault)
+ {
+ OSL_ASSERT( m_aNewValue == originalNode->getDefaultValue() );
+ return new ValueResetImpl( m_aNewValue, aOldValue );
+ }
+
+ else
+ {
+ return new ValueReplaceImpl( m_aNewValue, aOldValue );
+ }
+}
+//-----------------------------------------------------------------------------
+
+ValueChangeImpl* ValueMemberNode::DeferredImpl::adjustToChange(ValueChange const& rExternalChange)
+{
+ if (!m_bChange)
+ {
+ return NULL;
+ }
+ else if (m_bToDefault && rExternalChange.getMode() == ValueChange::changeDefault)
+ {
+ OSL_ASSERT( m_aNewValue == rExternalChange.getOldValue() );
+
+ m_aNewValue = rExternalChange.getNewValue();
+
+ return new ValueReplaceImpl(m_aNewValue, rExternalChange.getOldValue());
+ }
+ else // return Surrogate - does not honor m_bToDefault
+ {
+ return new ValueReplaceImpl(m_aNewValue, m_aNewValue);
+ }
+}
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+ }
+}
diff --git a/configmgr/source/treemgr/valuemembernode.hxx b/configmgr/source/treemgr/valuemembernode.hxx
new file mode 100644
index 000000000000..f8d1e7168be3
--- /dev/null
+++ b/configmgr/source/treemgr/valuemembernode.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valuemembernode.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_VALUEMEMBERNODE_HXX_
+#define CONFIGMGR_VALUEMEMBERNODE_HXX_
+
+#include "nodeimpl.hxx"
+
+namespace configmgr
+{
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+ /// handle class for values that are not nodes themselves, but members of a group
+ class ValueMemberNode
+ {
+ public:
+ class DeferredImpl;
+ private:
+ sharable::ValueNode * m_node;
+ rtl::Reference<DeferredImpl> m_xDeferredOperation;
+ private:
+ friend class GroupNodeImpl;
+ friend class DeferredGroupNodeImpl;
+ friend class ValueMemberUpdate;
+
+ /// create a ValueMemberNode for a given node
+ explicit ValueMemberNode(sharable::ValueNode * node);
+ /// create a deferred ValueMemberNode (xOriginal must not be empty)
+ ValueMemberNode(rtl::Reference<DeferredImpl> const& _xDeferred);
+ public:
+ ValueMemberNode(ValueMemberNode const& rOriginal);
+ ValueMemberNode& operator=(ValueMemberNode const& rOriginal);
+ ~ValueMemberNode();
+
+ /// does this wrap a valid value ?
+ bool isValid() const;
+
+ /// does this wrap a change
+ bool hasChange() const;
+
+ /// retrieve the name of the underlying node
+ rtl::OUString getNodeName() const;
+ /// retrieve the attributes
+ node::Attributes getAttributes() const;
+
+ /// Does this node assume its default value
+ bool isDefault() const;
+ /// is the default value of this node available
+ bool canGetDefaultValue() const;
+ /// retrieve the current value of this node
+ com::sun::star::uno::Any getValue() const;
+ /// retrieve the default value of this node
+ com::sun::star::uno::Any getDefaultValue() const;
+
+ com::sun::star::uno::Type getValueType() const;
+
+ };
+ //-------------------------------------------------------------------------
+
+ /// handle class for updating values that are members of a group
+ class ValueMemberUpdate
+ {
+ ValueMemberNode m_aMemberNode;
+ view::ViewStrategy * m_pStrategy;
+ private:
+ friend class view::ViewStrategy;
+
+ ValueMemberUpdate(ValueMemberNode const& rOriginal, view::ViewStrategy& _rStrategy)
+ : m_aMemberNode(rOriginal), m_pStrategy(&_rStrategy) {}
+
+ public:
+ /// does this wrap a valid value ?
+ bool isValid() const { return m_aMemberNode.isValid(); }
+
+ /// get access to the wrapped data
+ ValueMemberNode getNode() const { return m_aMemberNode; }
+
+ /// Set this node to a new value
+ void setValue(com::sun::star::uno::Any const& aNewValue);
+
+ /// Set this node to assume its default value
+ void setDefault();
+ };
+
+//-----------------------------------------------------------------------------
+ }
+}
+
+#endif // CONFIGMGR_GROUPNODEBEHAVIOR_HXX_
diff --git a/configmgr/source/treemgr/valuenodeimpl.hxx b/configmgr/source/treemgr/valuenodeimpl.hxx
new file mode 100644
index 000000000000..4dc0f8c7ec9e
--- /dev/null
+++ b/configmgr/source/treemgr/valuenodeimpl.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valuenodeimpl.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_VALUENODEBEHAVIOR_HXX_
+#define CONFIGMGR_VALUENODEBEHAVIOR_HXX_
+
+#include "nodeimpl.hxx"
+
+namespace configmgr
+{
+ class ValueChange;
+
+ namespace configuration
+ {
+//-----------------------------------------------------------------------------
+// Another types of node
+//-----------------------------------------------------------------------------
+
+ /** a special kind of node that is used to represent an element of a set of values
+ <p> This is an immutable value (changes are done by adding/replacing/removing set elements)
+ </p>
+ */
+ class ValueElementNodeImpl : public NodeImpl
+ {
+ public:
+ explicit ValueElementNodeImpl(sharable::ValueNode * const& _aNodeRef) ;
+
+ // the following delegate directly to the original node
+ public:
+ /// Does this node assume its default value
+ /// retrieve the current value of this node
+ com::sun::star::uno::Any getValue() const;
+
+ /// get the type of this value
+ com::sun::star::uno::Type getValueType() const;
+
+ sharable::ValueNode * getDataAccess() const;
+ };
+
+ // domain-specific 'dynamic_cast' replacement
+ ValueElementNodeImpl& AsValueNode(NodeImpl& rNode);
+ }
+}
+
+#endif // CONFIGMGR_VALUENODEBEHAVIOR_HXX_
diff --git a/configmgr/source/treemgr/viewaccess.cxx b/configmgr/source/treemgr/viewaccess.cxx
new file mode 100644
index 000000000000..9e09cd95a7f1
--- /dev/null
+++ b/configmgr/source/treemgr/viewaccess.cxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viewaccess.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "viewaccess.hxx"
+#include "tree.hxx"
+#include "noderef.hxx"
+
+//-----------------------------------------------------------------------------
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+configuration::NodeData* ViewTreeAccess::nodeData(configuration::NodeRef const& _aNodeArg) const
+{
+ return this->nodeData(_aNodeArg.getOffset());
+}
+
+//-----------------------------------------------------------------------------
+configuration::NodeData* ViewTreeAccess::nodeData(unsigned int _aNodePos) const
+{
+ return m_tree->nodeData(_aNodePos);
+}
+
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/viewaccess.hxx b/configmgr/source/treemgr/viewaccess.hxx
new file mode 100644
index 000000000000..735345184b0f
--- /dev/null
+++ b/configmgr/source/treemgr/viewaccess.hxx
@@ -0,0 +1,231 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viewaccess.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_VIEWACCESS_HXX_
+#define CONFIGMGR_VIEWACCESS_HXX_
+
+#include "viewnode.hxx"
+#include "viewstrategy.hxx"
+#include <rtl/ref.hxx>
+
+//-----------------------------------------------------------------------------
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration { class NodeRef; }
+//-----------------------------------------------------------------------------
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+
+ class ViewTreeAccess
+ {
+ rtl::Reference< ViewStrategy > m_xStrategy;
+ configuration::Tree * m_tree;
+
+ public:
+ explicit ViewTreeAccess(configuration::Tree * tree):
+ m_xStrategy(tree->getViewBehavior()), m_tree(tree) {}
+
+ rtl::Reference< view::ViewStrategy > getViewBehavior() { return m_xStrategy; }
+ public:
+ configuration::NodeData* nodeData(configuration::NodeRef const& _aNodeArg) const;
+ configuration::NodeData* nodeData(unsigned int _aNodePos) const;
+
+ Node makeNode(configuration::NodeRef const& _aNodeArg) const { return Node(m_tree,nodeData(_aNodeArg)); }
+ Node makeNode(unsigned int _aNodePos) const { return Node(m_tree,nodeData(_aNodePos)); }
+
+ bool isSetNode (configuration::NodeRef const& _aNodeArg) const { return makeNode(_aNodeArg).isSetNode(); }
+ bool isGroupNode(configuration::NodeRef const& _aNodeArg) const { return makeNode(_aNodeArg).isGroupNode(); }
+ bool isValueNode(configuration::NodeRef const& _aNodeArg) const { return makeNode(_aNodeArg).isValueNode(); }
+
+ bool isSetNodeAt (unsigned int _aNodeArg) const { return makeNode(_aNodeArg).isSetNode(); }
+ bool isGroupNodeAt(unsigned int _aNodeArg) const { return makeNode(_aNodeArg).isGroupNode(); }
+ bool isValueNodeAt(unsigned int _aNodeArg) const { return makeNode(_aNodeArg).isValueNode(); }
+
+ SetNode toSetNode (configuration::NodeRef const& _aNodeArg) const
+ { return SetNode (makeNode(_aNodeArg)); }
+
+ GroupNode toGroupNode(configuration::NodeRef const& _aNodeArg) const
+ { return GroupNode(makeNode(_aNodeArg)); }
+
+ ValueNode toValueNode(configuration::NodeRef const& _aNodeArg) const
+ { return ValueNode(makeNode(_aNodeArg)); }
+
+ SetNode getSetNodeAt (unsigned int _aNodeArg) const
+ { return SetNode (makeNode(_aNodeArg)); }
+
+ GroupNode getGroupNodeAt(unsigned int _aNodeArg) const
+ { return GroupNode(makeNode(_aNodeArg)); }
+
+ ValueNode getValueNodeAt(unsigned int _aNodeArg) const
+ { return ValueNode(makeNode(_aNodeArg)); }
+ // node attributes
+ public:
+ /// retrieve the name of the node
+ rtl::OUString getName(configuration::NodeRef const& _aNode) const
+ { return m_xStrategy->getName(makeNode(_aNode)); }
+
+ /// retrieve the attributes of the node
+ node::Attributes getAttributes(configuration::NodeRef const& _aNode) const
+ { return m_xStrategy->getAttributes(makeNode(_aNode)); }
+
+ /// retrieve the name of the tree root
+ rtl::OUString getRootName() const
+ { return m_xStrategy->getName( getRootNode(m_tree) ); }
+
+ /// retrieve the attributes of the tree root
+ node::Attributes getRootAttributes() const
+ { return m_xStrategy->getAttributes( getRootNode(m_tree) ); }
+
+ // tracking pending changes
+ public:
+ void collectChanges(configuration::NodeChanges& rChanges) const
+ { m_xStrategy->collectChanges(m_tree,rChanges); }
+
+ bool hasChanges() const
+ { return m_xStrategy->hasChanges(m_tree); }
+
+ bool hasChanges(configuration::NodeRef const& _aNode) const
+ { return m_xStrategy->hasChanges(makeNode(_aNode)); }
+
+ void markChanged(configuration::NodeRef const& _aNode)
+ { m_xStrategy->markChanged(makeNode(_aNode)); }
+
+ // commit protocol
+ public:
+ std::auto_ptr<SubtreeChange> preCommitChanges(std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements)
+ { return m_xStrategy->preCommitChanges(m_tree,_rRemovedElements); }
+
+ void finishCommit(SubtreeChange& rRootChange)
+ { m_xStrategy->finishCommit(m_tree,rRootChange); }
+
+ void revertCommit(SubtreeChange& rRootChange)
+ { m_xStrategy->revertCommit(m_tree,rRootChange); }
+
+ void recoverFailedCommit(SubtreeChange& rRootChange)
+ { m_xStrategy->recoverFailedCommit(m_tree,rRootChange); }
+
+ // notification protocol
+ public:
+ /// Adjust the internal representation after external changes to the original data - build NodeChangeInformation objects for notification
+ void adjustToChanges(configuration::NodeChangesInformation& rLocalChanges, configuration::NodeRef const& _aNode, SubtreeChange const& aExternalChange)
+ { m_xStrategy->adjustToChanges(rLocalChanges,makeNode(_aNode), aExternalChange); }
+
+ // visitor dispatch
+ public:
+ configuration::GroupMemberVisitor::Result dispatchToValues(GroupNode const& _aNode, configuration::GroupMemberVisitor& _aVisitor) const
+ { return m_xStrategy->dispatchToValues(_aNode,_aVisitor); }
+
+ /// Call <code>aVisitor.visit(aElement)</code> for each element in this set until SetNodeVisitor::DONE is returned.
+ configuration::SetNodeVisitor::Result dispatchToElements(SetNode const& _aNode, configuration::SetNodeVisitor& _aVisitor) const
+ { return m_xStrategy->dispatchToElements(_aNode,_aVisitor); }
+
+ // value (element) node specific operations
+ public:
+ /// Does this node assume its default value
+ /// retrieve the current value of this node
+ com::sun::star::uno::Any getValue(ValueNode const& _aNode) const
+ { return m_xStrategy->getValue(_aNode); }
+#if OSL_DEBUG_LEVEL > 0
+ /// get the type of this value
+ com::sun::star::uno::Type getValueType(ValueNode const& _aNode) const
+ { return m_xStrategy->getValueType(_aNode); }
+#endif
+
+ // group node specific operations
+ public:
+ /// does this hold a child value of the given name
+ bool hasValue(GroupNode const& _aNode, rtl::OUString const& _aName) const
+ { return m_xStrategy->hasValue(_aNode,_aName); }
+
+ /// does this hold a child value
+ bool hasValue(GroupNode const& _aNode) const
+ { return m_xStrategy->hasValue(_aNode); }
+
+ /// are defaults for this node available ?
+ bool areValueDefaultsAvailable(GroupNode const& _aNode) const
+ { return m_xStrategy->areValueDefaultsAvailable(_aNode); }
+
+ /// retrieve data for the child value of the given name
+ configuration::ValueMemberNode getValue(GroupNode const& _aNode, rtl::OUString const& _aName) const
+ { return m_xStrategy->getValue(_aNode,_aName); }
+
+ /// retrieve data for updating the child value of the given name
+ configuration::ValueMemberUpdate getValueForUpdate(GroupNode const & _aNode, rtl::OUString const& _aName) const
+ { return m_xStrategy->getValueForUpdate(_aNode,_aName); }
+
+ // set node specific operations
+ public:
+ /// does this set contain any elements (loads elements if needed)
+ bool isEmpty(SetNode const& _aNode) const
+ { return m_xStrategy->isEmpty(_aNode); }
+
+ /// does this set contain an element named <var>aName</var> (loads elements if needed)
+ configuration::SetEntry findElement(SetNode const& _aNode, rtl::OUString const& aName) const
+ { return m_xStrategy->findElement(_aNode,aName); }
+
+ /// does this set contain an element named <var>aName</var> (and is that element loaded ?)
+ configuration::SetEntry findAvailableElement(SetNode const& _aNode, rtl::OUString const& aName) const
+ { return m_xStrategy->findAvailableElement(_aNode,aName); }
+
+ /// insert a new entry into this set
+ void insertElement(SetNode const& _aNode, rtl::OUString const& aName, configuration::SetEntry const& aNewEntry)
+ { m_xStrategy->insertElement(_aNode,aName,aNewEntry); }
+
+ /// remove an existing entry into this set
+ void removeElement(SetNode const& _aNode, rtl::OUString const& aName)
+ { m_xStrategy->removeElement(_aNode,aName); }
+
+ /** Create a Subtree change as 'diff' which allows transforming the set to its default state
+ (given that <var>_rDefaultTree</var> points to a default instance of this set)
+ <p>Ownership of added trees should be transferred to the SubtreeChange.</p>
+ */
+ std::auto_ptr<SubtreeChange> differenceToDefaultState(SetNode const& _aNode, ISubtree& _rDefaultTree)
+ { return m_xStrategy->differenceToDefaultState(_aNode,_rDefaultTree); }
+
+ /// Get the template that describes elements of this set
+ rtl::Reference<configuration::Template> getElementTemplate(SetNode const& _aNode) const
+ { return m_xStrategy->getElementTemplate(_aNode); }
+
+ /// Get a template provider that can create new elements for this set
+ configuration::TemplateProvider getTemplateProvider(SetNode const& _aNode) const
+ { return m_xStrategy->getTemplateProvider(_aNode); }
+
+ // changing state/strategy
+ public:
+ // replace m_xStrategy by a direct ViewStrategy (commiting changes to the data), if possible
+ // void makeDirect ();
+
+ };
+ }
+}
+
+#endif // CONFIGMGR_VIEWACCESS_HXX_
diff --git a/configmgr/source/treemgr/viewfactory.hxx b/configmgr/source/treemgr/viewfactory.hxx
new file mode 100644
index 000000000000..b9a4da820107
--- /dev/null
+++ b/configmgr/source/treemgr/viewfactory.hxx
@@ -0,0 +1,56 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viewfactory.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_
+#define CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace data { class TreeSegment; }
+
+ namespace view
+ {
+ // Different standard (static) strategies
+ //---------------------------------------------------------------------
+ /// provides a factory for read-only node implementations
+ rtl::Reference<ViewStrategy> createReadOnlyStrategy();
+ /// provides a factory for nodes that cache changes temporarily
+ rtl::Reference<ViewStrategy> createDeferredChangeStrategy();
+ /// provides a factory for immediately commiting node implementations
+ rtl::Reference<ViewStrategy> createDirectAccessStrategy(rtl::Reference< data::TreeSegment > const & _aTreeSegment);
+ //---------------------------------------------------------------------
+ }
+
+//-----------------------------------------------------------------------------
+
+}
+
+#endif // CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_
diff --git a/configmgr/source/treemgr/viewnode.cxx b/configmgr/source/treemgr/viewnode.cxx
new file mode 100644
index 000000000000..2f57dba05dda
--- /dev/null
+++ b/configmgr/source/treemgr/viewnode.cxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viewnode.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "viewnode.hxx"
+#include "setnodeimpl.hxx"
+#include "groupnodeimpl.hxx"
+#include "valuenodeimpl.hxx"
+#include "tree.hxx"
+#include "viewstrategy.hxx"
+
+//-----------------------------------------------------------------------------
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+ rtl::Reference< view::ViewStrategy > getViewBehavior(configuration::Tree * _aTree)
+ {
+ return _aTree->getViewBehavior();
+ }
+
+//-----------------------------------------------------------------------------
+ static inline Node makeNode_(configuration::Tree * _aTree, unsigned int nOffset)
+ {
+ return Node(_aTree, _aTree->nodeData(nOffset));
+ }
+//-----------------------------------------------------------------------------
+ Node Node::getParent() const
+ {
+ configuration::Tree * pTreeData = this->tree();
+ return makeNode_(tree(), pTreeData->parent_(this->get_offset()));
+ }
+
+//-----------------------------------------------------------------------------
+ Node GroupNode::findChild(rtl::OUString const& _aName) const
+ {
+ configuration::Tree * pTreeData = this->tree();
+ return makeNode_(tree(), pTreeData->findChild_(node().get_offset(), _aName));
+ }
+
+//-----------------------------------------------------------------------------
+ Node GroupNode::getFirstChild() const
+ {
+ configuration::Tree * pTreeData = this->tree();
+ return makeNode_(tree(), pTreeData->firstChild_(node().get_offset()));
+ }
+
+//-----------------------------------------------------------------------------
+ Node GroupNode::getNextChild(Node const& _aAfterNode) const
+ {
+ configuration::Tree * pTreeData = this->tree();
+ OSL_ASSERT(pTreeData->parent_(_aAfterNode.get_offset()) == this->node().get_offset());
+ return makeNode_(tree(), pTreeData->findNextChild_(node().get_offset(),_aAfterNode.get_offset()));
+ }
+
+//-----------------------------------------------------------------------------
+ sharable::Node * Node::getAccessRef() const
+ {
+ return get_impl()->getOriginalNodeAccess();
+ }
+
+//-----------------------------------------------------------------------------
+ sharable::GroupNode * GroupNode::getAccess() const
+ {
+ return get_impl()->getDataAccess();
+ }
+
+//-----------------------------------------------------------------------------
+ sharable::SetNode * SetNode::getAccess() const
+ {
+ return get_impl()->getDataAccess();
+ }
+
+//-----------------------------------------------------------------------------
+ }
+}
+
diff --git a/configmgr/source/treemgr/viewnode.hxx b/configmgr/source/treemgr/viewnode.hxx
new file mode 100644
index 000000000000..d8f81346b908
--- /dev/null
+++ b/configmgr/source/treemgr/viewnode.hxx
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viewnode.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_VIEWNODE_HXX_
+#define CONFIGMGR_VIEWNODE_HXX_
+
+#include "tree.hxx"
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+ struct ElementTreeData;
+ }
+ namespace sharable { struct GroupNode; }
+//-----------------------------------------------------------------------------
+ namespace view
+ {
+ //-------------------------------------------------------------------------
+ struct Node
+ {
+ Node(configuration::Tree * _tree, configuration::NodeData* _addr)
+ : m_tree(_tree), m_addr(_addr)
+ {}
+
+ Node(configuration::Tree * _tree, unsigned int _offs)
+ : m_tree(_tree), m_addr( _tree->nodeData(_offs))
+ {}
+
+ bool is() const { return m_addr != 0; }
+
+ Node getParent() const;
+
+ bool isSetNode() const { return is() && data().isSetNode(); }
+ bool isGroupNode() const { return is() && data().isGroupNode(); }
+ bool isValueNode() const { return is() && data().isValueElementNode(); }
+
+ // low-level access
+// configuration::NodeImpl * operator->() const { return &data().nodeImpl(); }
+
+ configuration::NodeData& data() const { return *m_addr; }
+
+ configuration::NodeImpl * get_impl() const
+ { return is() ? &data().nodeImpl() : NULL; }
+
+ unsigned int get_offset() const
+ { return is() ? m_tree->nodeOffset( this->data() ) : 0; }
+
+ configuration::Tree * tree() const // has a tree
+ { return m_tree; }
+
+ sharable::Node * getAccessRef() const; // has a Node
+
+ private:
+ configuration::Tree * m_tree; // has a Tree + Accessor
+ configuration::NodeData* m_addr; // has a configuration::NodeImpl *
+ };
+ //-------------------------------------------------------------------------
+ struct ValueNode // has/is a Node
+ {
+ Node m_node;
+
+ explicit
+ ValueNode(Node const& _node)
+ : m_node(_node)
+ {}
+
+ bool is() const { return m_node.isValueNode(); }
+
+ // low-level access
+ // configuration::ValueElementNodeImpl* operator->() const { return &m_node.data().valueElementImpl(); }
+
+ configuration::ValueElementNodeImpl* get_impl() const
+ { return is() ? &m_node.data().valueElementImpl() : NULL; }
+
+ Node node() const // has a Node
+ { return m_node; }
+
+ configuration::Tree * tree() const // has a tree
+ { return m_node.tree(); }
+ };
+ //-------------------------------------------------------------------------
+ struct GroupNode // has/is a Node
+ {
+ Node m_node;
+
+ explicit
+ GroupNode(Node const& _node)
+ : m_node(_node)
+ {}
+
+ bool is() const { return m_node.isGroupNode(); }
+
+ Node findChild(rtl::OUString const& _aName) const;
+ Node getFirstChild() const;
+ Node getNextChild(Node const& _aAfterNode) const;
+
+// configuration::GroupNodeImpl* operator->() const { return &m_node.data().groupImpl(); }
+
+ configuration::GroupNodeImpl* get_impl() const
+ { return is() ? &m_node.data().groupImpl() : NULL; }
+
+ Node node() const // has a Node
+ { return m_node; }
+
+ configuration::Tree * tree() const // has a tree
+ { return m_node.tree(); }
+
+ sharable::GroupNode * getAccess() const; // has a GroupNode
+ };
+ //-------------------------------------------------------------------------
+ struct SetNode // has/is a Node
+ {
+ Node m_node;
+
+ explicit
+ SetNode(Node const& _node)
+ : m_node(_node)
+ {}
+
+ bool is() const { return m_node.isSetNode(); }
+
+ // configuration::SetNodeImpl* operator->() const { return &m_node.data().setImpl(); }
+
+ configuration::SetNodeImpl* get_impl() const
+ { return is() ? &m_node.data().setImpl() : 0; }
+
+ Node node() const // has a Node
+ { return m_node; }
+
+ configuration::Tree * tree() const // has a tree
+ { return m_node.tree(); }
+
+ sharable::SetNode * getAccess() const; // has a SetNode
+ };
+ //-------------------------------------------------------------------------
+ inline
+ Node getRootNode(configuration::Tree * _aTree)
+ {
+ return Node(_aTree,_aTree->nodeData(configuration::Tree::ROOT));
+ }
+
+ //-------------------------------------------------------------------------
+ inline
+ rtl::OUString getSimpleRootName(configuration::Tree * _aTree)
+ {
+ return _aTree->getSimpleRootName();
+ }
+
+ //-------------------------------------------------------------------------
+ inline
+ bool isValidNode(Node const & _aNode)
+ {
+ configuration::Tree* pTreeData = _aNode.tree();
+ return pTreeData->isValidNode(_aNode.get_offset());
+ }
+
+ //-------------------------------------------------------------------------
+ inline
+ rtl::OUString getSimpleNodeName(Node const & _aNode)
+ {
+ configuration::Tree* pTreeData = _aNode.tree();
+ return pTreeData->getSimpleNodeName(_aNode.get_offset());
+ }
+
+ //-------------------------------------------------------------------------
+ extern
+ rtl::Reference< view::ViewStrategy > getViewBehavior(configuration::Tree * _aTree);
+ //-------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+//-----------------------------------------------------------------------------
+
+#endif // CONFIGMGR_VIEWNODE_HXX_
diff --git a/configmgr/source/treemgr/viewstrategy.cxx b/configmgr/source/treemgr/viewstrategy.cxx
new file mode 100644
index 000000000000..661720eb65ea
--- /dev/null
+++ b/configmgr/source/treemgr/viewstrategy.cxx
@@ -0,0 +1,623 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viewstrategy.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "viewstrategy.hxx"
+#include "valuenodeimpl.hxx"
+#include "groupnodeimpl.hxx"
+#include "setnodeimpl.hxx"
+#include "change.hxx"
+#include "nodevisitor.hxx"
+#include "nodechange.hxx"
+#include "nodechangeimpl.hxx"
+#include "nodeconverter.hxx"
+//-----------------------------------------------------------------------------
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+ static
+ inline
+ sharable::ValueNode * getMemberValueAccess( GroupNode const & _aGroupNode, rtl::OUString const & _aName )
+ {
+ configuration::GroupNodeImpl* pGroupData = _aGroupNode.get_impl();
+ return pGroupData->getOriginalValueNode(_aName);
+ }
+
+//-----------------------------------------------------------------------------
+ void ViewStrategy::checkInstance(configuration::Tree * tree) const
+ {
+ (void) tree; // avoid warnings
+ OSL_ENSURE( getViewBehavior(tree).get() == this,
+ "Tree operation dispatched to wrong strategy instance");
+ }
+//-----------------------------------------------------------------------------
+ void ViewStrategy::collectChanges(configuration::Tree * tree, configuration::NodeChanges& rChanges) const
+ {
+ checkInstance(tree);
+ doCollectChanges( getRootNode(tree), rChanges );
+ }
+
+ bool ViewStrategy::hasChanges(configuration::Tree * tree) const
+ {
+ checkInstance(tree);
+ return hasChanges( getRootNode(tree) );
+ }
+
+ // mark the given node and all its ancestors (we can stop when we hit a node that already is marked)
+ void ViewStrategy::markChanged(Node const& _aNode)
+ {
+ configuration::Tree * tree = _aNode.tree();
+ checkInstance(tree);
+
+ Node aNode = _aNode;
+ if (aNode.is())
+ {
+ do
+ {
+ this->doMarkChanged(aNode);
+
+ aNode = aNode.getParent();
+ }
+ while (aNode.is() && !this->hasChanges( aNode ));
+ }
+
+ if (!aNode.is()) // just marked the root
+ {
+ configuration::Tree* pContext = tree->getContextTree();
+ unsigned int nContext = tree->getContextNode();
+ if (pContext)
+ {
+ OSL_ASSERT(pContext->isValidNode(nContext));
+
+ view::Node aContextNode(pContext,nContext);
+ pContext->getViewBehavior()->markChanged(aContextNode);
+ }
+ }
+ }
+
+//-----------------------------------------------------------------------------
+ std::auto_ptr<SubtreeChange> ViewStrategy::preCommitChanges(configuration::Tree * tree, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements)
+ {
+ checkInstance(tree);
+ return doPreCommitChanges( tree, _rRemovedElements);
+ }
+
+ void ViewStrategy::finishCommit(configuration::Tree * tree, SubtreeChange& rRootChange)
+ {
+ checkInstance(tree);
+ doFinishCommit(tree, rRootChange);
+ }
+
+ void ViewStrategy::revertCommit(configuration::Tree * tree, SubtreeChange& rRootChange)
+ {
+ checkInstance(tree);
+ doRevertCommit(tree, rRootChange);
+ }
+
+ void ViewStrategy::recoverFailedCommit(configuration::Tree * tree, SubtreeChange& rRootChange)
+ {
+ checkInstance(tree);
+ doFailedCommit(tree, rRootChange);
+ }
+
+//-----------------------------------------------------------------------------
+ void ViewStrategy::adjustToChanges(configuration::NodeChangesInformation& rLocalChanges, Node const& _aNode, SubtreeChange const& aExternalChange)
+ {
+ OSL_PRECOND( isValidNode(_aNode), "ERROR: Valid node required for adjusting to changes" );
+ OSL_PRECOND( getSimpleNodeName(_aNode) == aExternalChange.getNodeName(), "name of change does not match actual node" );
+
+ checkInstance(_aNode.tree());
+
+ configuration::Tree * pTreeData = _aNode.tree();
+
+ if (_aNode.isSetNode())
+ {
+ OSL_ENSURE(aExternalChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
+
+ unsigned int nDepth = pTreeData->getRemainingDepth(_aNode.get_offset());
+
+ implAdjustToElementChanges( rLocalChanges, SetNode(_aNode), aExternalChange, nDepth);
+ }
+ else if (_aNode.isGroupNode())
+ {
+ OSL_ENSURE(!aExternalChange.isSetNodeChange(),"ERROR: Change type SET does not match group");
+
+ GroupNode aGroupNode(_aNode);
+
+ implAdjustToValueChanges(rLocalChanges, aGroupNode, aExternalChange);
+ implAdjustToSubChanges( rLocalChanges, aGroupNode, aExternalChange);
+ }
+ else // might occur on external change (?)
+ {
+ OSL_ENSURE(_aNode.isValueNode(), "Tree: Unknown node type to adjust to changes");
+
+ OSL_ENSURE(_aNode.get_offset() == configuration::Tree::ROOT, "Tree: Unexpected node type - non-root value element");
+
+ OSL_ENSURE(false,"ERROR: Change type does not match node: Trying to apply subtree change to value element.");
+ }
+ }
+
+//-----------------------------------------------------------------------------
+
+ void ViewStrategy::addLocalChangeHelper( configuration::NodeChangesInformation& rLocalChanges_, configuration::NodeChange const& aChange_)
+ {
+ aChange_.getChangeInfos(rLocalChanges_);
+ }
+
+//-----------------------------------------------------------------------------
+ // TO DO: create CommitAction class, which is returned by precommit (if applicable)
+
+ std::auto_ptr<SubtreeChange> ViewStrategy::doPreCommitChanges(configuration::Tree * tree, std::vector< rtl::Reference<configuration::ElementTree> >& )
+ {
+ (void) tree; // avoid warnings
+ OSL_ENSURE(!hasChanges(getRootNode(tree)),"Unexpected changes in View");
+ return std::auto_ptr<SubtreeChange>();
+ }
+
+ void ViewStrategy::doFinishCommit(configuration::Tree * tree, SubtreeChange& )
+ {
+ (void) tree; // avoid warnings
+ OSL_ENSURE(!hasChanges(getRootNode(tree)),"Unexpected changes in View");
+ OSL_ENSURE(false,"ERROR: Cannot finish commit for unexpected changes");
+ }
+
+ void ViewStrategy::doRevertCommit(configuration::Tree * tree, SubtreeChange& )
+ {
+ (void) tree; // avoid warnings
+ OSL_ENSURE(!hasChanges(getRootNode(tree)),"Unexpected changes in View");
+ OSL_ENSURE(false,"ERROR: Cannot revert commit for unexpected changes");
+ }
+
+ void ViewStrategy::doFailedCommit(configuration::Tree * tree, SubtreeChange& )
+ {
+ (void) tree; // avoid warnings
+ OSL_ENSURE(!hasChanges(getRootNode(tree)),"Unexpected changes in View");
+ OSL_ENSURE(false,"ERROR: Cannot recover commit for unexpected changes");
+ }
+
+//-----------------------------------------------------------------------------
+ void ViewStrategy::implAdjustToElementChange(configuration::NodeChangesInformation& rLocalChanges, SetNode const& _aSetNode, Change const& rElementChange, unsigned int nDepth)
+ {
+ configuration::SetNodeImpl * pSetData = _aSetNode.get_impl();
+
+ OSL_ENSURE( pSetData->implHasLoadedElements() , "Unexpected call: Processing element change in uninitialized set");
+
+ rtl::OUString aName( rElementChange.getNodeName() );
+
+ configuration::SetElementChangeImpl* pThisChange = 0;
+ if (AddNode const * addNode = dynamic_cast< AddNode const *>(&rElementChange))
+ {
+ configuration::ElementTreeData aNewElement = pSetData->makeAdditionalElement(this, *addNode, nDepth);
+
+ pThisChange = pSetData->doAdjustToAddedElement(aName, *addNode, aNewElement);
+ }
+ else if (RemoveNode const * removeNode = dynamic_cast< RemoveNode const * >(&rElementChange))
+ {
+ pThisChange = pSetData->doAdjustToRemovedElement(aName, *removeNode);
+ }
+ else
+ {
+ if (nDepth > 0 || (NULL != pSetData->doFindElement(aName)) )// found even beyond nDepth ?
+ {
+ pThisChange = pSetData->doAdjustChangedElement(rLocalChanges,aName, rElementChange);
+ }
+ }
+
+ if (pThisChange)
+ {
+ addLocalChangeHelper( rLocalChanges, configuration::NodeChange(pThisChange) );
+ }
+ }
+
+ void ViewStrategy::implAdjustToElementChanges(configuration::NodeChangesInformation& rLocalChanges, SetNode const& _aSetNode, SubtreeChange const& rExternalChanges, unsigned int nDepth)
+ {
+
+ if (nDepth > 0)
+ {
+ configuration::SetNodeImpl * pSetData = _aSetNode.get_impl();
+
+ OSL_ENSURE( pSetData->getTemplateProvider().isValid(), "Cannot adjust SetNode to changes - node was never initialized" );
+
+ if (pSetData->implHasLoadedElements())
+ {
+ unsigned int const nElementDepth = configuration::childDepth(nDepth);
+ for (SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it)
+ {
+ this->implAdjustToElementChange(rLocalChanges, _aSetNode, *it, nElementDepth);
+ }
+ }
+ else
+ {
+ OSL_ENSURE( !hasChanges(_aSetNode.node()),"Cannot have changes to consider when no elements are loaded");
+
+ pSetData->convertChanges( rLocalChanges, rExternalChanges, nDepth);
+ }
+ }
+ }
+
+ configuration::ValueChangeImpl* ViewStrategy::doAdjustToValueChange(GroupNode const& _aGroupNode, rtl::OUString const& _aName, ValueChange const& _rExternalChange)
+ {
+ configuration::ValueChangeImpl* pChangeImpl = NULL;
+
+ sharable::ValueNode * localNode = getMemberValueAccess(_aGroupNode,_aName);
+ if (localNode != 0)
+ {
+ switch( _rExternalChange. getMode() )
+ {
+ case ValueChange::wasDefault:
+ case ValueChange::changeValue:
+ pChangeImpl = new configuration::ValueReplaceImpl( _rExternalChange.getNewValue(), _rExternalChange.getOldValue() );
+ break;
+
+ case ValueChange::setToDefault:
+ pChangeImpl = new configuration::ValueResetImpl( _rExternalChange.getNewValue(), _rExternalChange.getOldValue() );
+ break;
+
+ default: OSL_ENSURE(false, "Unknown change mode");
+ // fall thru to next case for somewhat meaningful return value
+ case ValueChange::changeDefault:
+ {
+ com::sun::star::uno::Any aLocalValue = localNode->getValue();
+
+ pChangeImpl = new configuration::ValueReplaceImpl( aLocalValue, aLocalValue );
+ }
+ break;
+ }
+ OSL_ASSERT( pChangeImpl );
+ }
+ else
+ {
+ OSL_ENSURE(false, "ERROR: Notification tries to change nonexistent value within group");
+ }
+
+ return pChangeImpl;
+ }
+
+ void ViewStrategy::implAdjustToValueChanges(configuration::NodeChangesInformation& rLocalChanges, GroupNode const& _aGroupNode, SubtreeChange const& rExternalChanges)
+ {
+ for (SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it)
+ {
+ if (ValueChange const * valueChange = dynamic_cast< ValueChange const * >(&*it))
+ {
+ rtl::OUString aValueName( valueChange->getNodeName() );
+
+ if (configuration::ValueChangeImpl* pThisChange = doAdjustToValueChange(_aGroupNode, aValueName, *valueChange))
+ {
+ pThisChange->setTarget(_aGroupNode,aValueName);
+ addLocalChangeHelper(rLocalChanges, configuration::NodeChange(pThisChange));
+ }
+ else
+ OSL_TRACE("WARNING: Configuration: derived class hides an external value member change from listeners");
+ }
+ else
+ OSL_ENSURE(dynamic_cast< SubtreeChange const * >(&*it) != 0, "Unexpected change type within group");
+ }
+ }
+
+ void ViewStrategy::implAdjustToSubChanges(configuration::NodeChangesInformation& rLocalChanges, GroupNode const& _aGroupNode, SubtreeChange const& rExternalChanges)
+ {
+#if (OSL_DEBUG_LEVEL > 0)
+ configuration::Tree * pTreeData = _aGroupNode.tree();
+#endif
+ for(SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it)
+ {
+ if (SubtreeChange const * subtreeChange = dynamic_cast< SubtreeChange const * >(&*it))
+ {
+ Node aSubNode = _aGroupNode.findChild( it->getNodeName() );
+ OSL_ENSURE( aSubNode.is() || pTreeData->depthTo(_aGroupNode.node().get_offset()) >= pTreeData->getAvailableDepth(), "Changed node not found in tree");
+
+ if (aSubNode.is())
+ {
+ OSL_ENSURE( pTreeData->getRemainingDepth(_aGroupNode.node().get_offset()) > 0, "Depth is smaller than expected for tree");
+ this->adjustToChanges(rLocalChanges, aSubNode, *subtreeChange);
+ }
+ }
+ else
+ {
+ OSL_ENSURE(dynamic_cast< ValueChange const * >(&*it) != 0, "Unexpected change type for child of group node; change is ignored");
+ OSL_ENSURE( !_aGroupNode.findChild(it->getNodeName()).is(),
+ "Found sub(tree) node where a value was expected");
+ }
+ }
+ }
+//-----------------------------------------------------------------------------
+ void ViewStrategy::doCollectChanges(Node const& _aNode, configuration::NodeChanges& ) const
+ {
+ { (void)_aNode; }
+ // no-op: there are no changes to collect
+ OSL_ENSURE(!hasChanges(_aNode),"Unexpected changes in View");
+ }
+
+
+//-----------------------------------------------------------------------------
+ com::sun::star::uno::Any ViewStrategy::getValue(ValueNode const& _aNode) const
+ {
+ checkInstance(_aNode.tree());
+ return _aNode.get_impl()->getValue();
+ }
+#if OSL_DEBUG_LEVEL > 0
+ com::sun::star::uno::Type ViewStrategy::getValueType(ValueNode const& _aNode) const
+ {
+ checkInstance(_aNode.tree());
+ return _aNode.get_impl()->getValueType();
+ }
+#endif
+//-----------------------------------------------------------------------------
+// group member access
+
+//-----------------------------------------------------------------------------
+ namespace { // helpers
+ struct GroupMemberDispatch : data::NodeVisitor
+ {
+ GroupMemberDispatch(ViewStrategy& _rStrategy, GroupNode const& _aGroup, configuration::GroupMemberVisitor& rVisitor)
+ : m_rStrategy(_rStrategy)
+ , m_aGroup(_aGroup)
+ , m_rVisitor(rVisitor)
+ {}
+
+ static bool mapResult(configuration::GroupMemberVisitor::Result _aResult)
+ {
+ return _aResult == configuration::GroupMemberVisitor::DONE;
+ }
+
+ static configuration::GroupMemberVisitor::Result unmapResult(bool done)
+ {
+ return done
+ ? configuration::GroupMemberVisitor::DONE
+ : configuration::GroupMemberVisitor::CONTINUE;
+ }
+
+ using NodeVisitor::handle;
+ virtual bool handle(sharable::Node * node);
+ virtual bool handle(sharable::ValueNode * node);
+#if (OSL_DEBUG_LEVEL > 0)
+ bool test_value(sharable::Node * node) const;
+#endif
+ ViewStrategy& m_rStrategy;
+ GroupNode m_aGroup;
+ configuration::GroupMemberVisitor& m_rVisitor;
+
+ configuration::GroupMemberVisitor::Result m_aResult;
+ };
+
+#if (OSL_DEBUG_LEVEL > 0)
+ bool GroupMemberDispatch::test_value(sharable::Node * node) const
+ {
+ return m_rStrategy.hasValue(m_aGroup, node->getName());
+ }
+#endif
+
+ bool GroupMemberDispatch::handle(sharable::ValueNode * node)
+ {
+ OSL_ENSURE( test_value(sharable::node(node)), "ERROR: Group MemberDispatch:Did not find a ValueMember for a value child.");
+
+ rtl::OUString aValueName = node->info.getName();
+
+ return mapResult( m_rVisitor.visit( m_rStrategy.getValue(m_aGroup,aValueName) ) );
+ }
+
+ bool GroupMemberDispatch::handle(sharable::Node * node)
+ {
+ (void) node; // avoid warnings
+ OSL_ENSURE( !test_value(node), "ERROR: Group MemberDispatch:Found a ValueMember for a subtree child.");
+
+ return false;
+ }
+ }
+//-----------------------------------------------------------------------------
+ configuration::ValueMemberNode ViewStrategy::doGetValueMember(GroupNode const& _aNode, rtl::OUString const& _aName, bool ) const
+ {
+ sharable::ValueNode * valueData = getMemberValueAccess(_aNode,_aName);
+ return _aNode.get_impl()->makeValueMember(valueData);
+ }
+
+ bool ViewStrategy::hasValue(GroupNode const& _aNode, rtl::OUString const& _aName) const
+ {
+ checkInstance(_aNode.tree());
+ return getMemberValueAccess(_aNode,_aName) != 0;
+ }
+
+ bool ViewStrategy::hasValue(GroupNode const& _aNode) const
+ {
+ checkInstance(_aNode.tree());
+ configuration::GroupNodeImpl* pGroupNode=_aNode.get_impl();
+ sharable::GroupNode * group = pGroupNode->getDataAccess();
+ return group->numDescendants > 0;
+ }
+
+
+ bool ViewStrategy::areValueDefaultsAvailable(GroupNode const& _aNode) const
+ {
+ checkInstance(_aNode.tree());
+
+ return _aNode.get_impl()->areValueDefaultsAvailable();
+ }
+
+ configuration::ValueMemberNode ViewStrategy::getValue(GroupNode const& _aNode, rtl::OUString const& _aName) const
+ {
+ checkInstance(_aNode.tree());
+ return doGetValueMember(_aNode,_aName,false);
+ }
+
+ configuration::ValueMemberUpdate ViewStrategy::getValueForUpdate(GroupNode const & _aNode, rtl::OUString const& _aName)
+ {
+ checkInstance(_aNode.tree());
+ return configuration::ValueMemberUpdate( doGetValueMember(_aNode,_aName,true), *this );
+ }
+
+ configuration::GroupMemberVisitor::Result ViewStrategy::dispatchToValues(GroupNode const& _aNode, configuration::GroupMemberVisitor& _aVisitor)
+ {
+ checkInstance(_aNode.tree());
+
+ GroupMemberDispatch aDispatch(*this,_aNode,_aVisitor);
+
+ bool done = aDispatch.visitChildren( _aNode.getAccess() );
+
+ return aDispatch.unmapResult(done);
+ }
+
+//-----------------------------------------------------------------------------
+ configuration::ElementTreeData ViewStrategy::implMakeElement(SetNode const& _aNode, configuration::SetEntry const& anEntry) const
+ {
+ configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
+ return pNodeData->implValidateElement(pNodeData->entryToElement(anEntry));
+ }
+//-----------------------------------------------------------------------------
+ configuration::SetEntry ViewStrategy::implFindElement(SetNode const& _aNode, rtl::OUString const& aName) const
+ {
+ configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
+
+ OSL_ENSURE(pNodeData->implHasLoadedElements(),"Cannot find elements in set that is not loaded");
+ configuration::ElementTree * pElement = pNodeData->doFindElement(aName);
+
+ return configuration::SetEntry(pElement);
+ }
+
+ configuration::SetEntry ViewStrategy::findElement(SetNode const& _aNode, rtl::OUString const& aName) const
+ {
+ checkInstance(_aNode.tree());
+ _aNode.get_impl()->implEnsureElementsLoaded();
+ return implFindElement(_aNode,aName);
+ }
+
+ configuration::SetEntry ViewStrategy::findAvailableElement(SetNode const& _aNode, rtl::OUString const& aName) const
+ {
+ checkInstance(_aNode.tree());
+ if (_aNode.get_impl()->implHasLoadedElements())
+ return implFindElement(_aNode,aName);
+ else
+ return configuration::SetEntry(0);
+ }
+
+ static
+ inline
+ std::auto_ptr<SubtreeChange> makeChangeToDefault(sharable::SetNode * setNode)
+ {
+ return std::auto_ptr<SubtreeChange>(
+ new SubtreeChange(
+ setNode->info.getName(),
+ setNode->getElementTemplateName(),
+ setNode->getElementTemplateModule(),
+ sharable::node(setNode)->getAttributes(),
+ true // to default
+ ) );
+ }
+
+ std::auto_ptr<SubtreeChange> ViewStrategy::differenceToDefaultState(SetNode const& _aNode, ISubtree& _rDefaultTree) const
+ {
+ checkInstance(_aNode.tree());
+ std::auto_ptr<SubtreeChange> aResult;
+
+ sharable::SetNode * originalSetNode = _aNode.getAccess();
+ OSL_ASSERT(originalSetNode != 0);
+ if (!originalSetNode->info.isDefault())
+ {
+ aResult = makeChangeToDefault(originalSetNode);
+
+ configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
+ if (this->hasChanges(_aNode.node()))
+ {
+ OSL_ENSURE(pNodeData->implHasLoadedElements(),"Unexpected: Found set with changes but elements are not loaded");
+ pNodeData->doDifferenceToDefaultState(*aResult,_rDefaultTree);
+ }
+ else
+ pNodeData->implDifferenceToDefaultState(*aResult,_rDefaultTree);
+ }
+ return aResult;
+ }
+
+ rtl::Reference<configuration::Template> ViewStrategy::getElementTemplate(SetNode const& _aNode) const
+ {
+ checkInstance(_aNode.tree());
+ return _aNode.get_impl()->getElementTemplate();
+ }
+
+ configuration::TemplateProvider ViewStrategy::getTemplateProvider(SetNode const& _aNode) const
+ {
+ checkInstance(_aNode.tree());
+ return _aNode.get_impl()->getTemplateProvider();
+ }
+
+ node::Attributes ViewStrategy::getNodeAttributes(Node const& _aNode) const
+ {
+ checkInstance(_aNode.tree());
+ return _aNode.getAccessRef()->getAttributes();
+ }
+
+//-----------------------------------------------------------------------------
+ configuration::SetNodeVisitor::Result ViewStrategy::dispatchToElements(SetNode const& _aNode, configuration::SetNodeVisitor& _aVisitor)
+ {
+ checkInstance(_aNode.tree());
+
+ configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
+
+ if (pNodeData->implLoadElements())
+ return pNodeData->doDispatchToElements(_aVisitor);
+
+ else
+ return configuration::SetNodeVisitor::CONTINUE;
+ }
+
+ bool ViewStrategy::isEmpty(SetNode const& _aNode) const
+ {
+ checkInstance(_aNode.tree());
+
+ configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
+
+ return !pNodeData->implLoadElements() || pNodeData->doIsEmpty();
+ }
+//-----------------------------------------------------------------------------
+
+ void ViewStrategy::insertElement(SetNode const& _aNode, rtl::OUString const& _aName, configuration::SetEntry const& _aNewEntry)
+ {
+ // cannot insert, if we cannot check for collisions
+ checkInstance(_aNode.tree());
+ _aNode.get_impl()->implEnsureElementsLoaded();
+ doInsertElement(_aNode,_aName,_aNewEntry);
+ }
+
+ void ViewStrategy::removeElement(SetNode const& _aNode, rtl::OUString const& _aName)
+ {
+ // cannot remove, if we cannot check for existance
+ checkInstance(_aNode.tree());
+ _aNode.get_impl()->implEnsureElementsLoaded();
+ doRemoveElement(_aNode,_aName);
+ }
+
+//-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
diff --git a/configmgr/source/treemgr/viewstrategy.hxx b/configmgr/source/treemgr/viewstrategy.hxx
new file mode 100644
index 000000000000..d3ebb69bc7ac
--- /dev/null
+++ b/configmgr/source/treemgr/viewstrategy.hxx
@@ -0,0 +1,231 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: viewstrategy.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_
+#define CONFIGMGR_VIEWBEHAVIOR_HXX_
+
+#include "viewnode.hxx"
+#include "groupnodeimpl.hxx"
+#include "setnodeimpl.hxx"
+#include "utility.hxx"
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+
+namespace configmgr
+{
+//-----------------------------------------------------------------------------
+ namespace configuration
+ {
+ class SetElementChangeImpl;
+ class ValueChangeImpl;
+ }
+//-----------------------------------------------------------------------------
+ namespace view
+ {
+//-----------------------------------------------------------------------------
+ struct NodeFactory;
+//-----------------------------------------------------------------------------
+ class ViewStrategy : public salhelper::SimpleReferenceObject
+ {
+ // node attributes
+ public:
+ /// retrieve the attributes of the node
+ rtl::OUString getName(Node const& _aNode) const;
+
+ /// retrieve the attributes of the node
+ node::Attributes getAttributes(Node const& _aNode) const;
+
+ // tracking pending changes
+ public:
+ void collectChanges(configuration::Tree * tree, configuration::NodeChanges& rChanges) const;
+
+ bool hasChanges(configuration::Tree * tree) const;
+
+ bool hasChanges(Node const& _aNode) const;
+
+ void markChanged(Node const& _aNode);
+
+ // commit protocol
+ public:
+ std::auto_ptr<SubtreeChange> preCommitChanges(configuration::Tree * tree, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements);
+
+ void finishCommit(configuration::Tree * tree, SubtreeChange& rRootChange);
+
+ void revertCommit(configuration::Tree * tree, SubtreeChange& rRootChange);
+
+ void recoverFailedCommit(configuration::Tree * tree, SubtreeChange& rRootChange);
+
+ // notification protocol
+ public:
+ /// Adjust the internal representation after external changes to the original data - build NodeChangeInformation objects for notification
+ void adjustToChanges(configuration::NodeChangesInformation& rLocalChanges, Node const & _aNode, SubtreeChange const& aExternalChange);
+
+ // visitor dispatch
+ public:
+ configuration::GroupMemberVisitor::Result dispatchToValues(GroupNode const& _aNode, configuration::GroupMemberVisitor& _aVisitor);
+
+ /// Call <code>aVisitor.visit(aElement)</code> for each element in this set until SetNodeVisitor::DONE is returned.
+ configuration::SetNodeVisitor::Result dispatchToElements(SetNode const& _aNode, configuration::SetNodeVisitor& _aVisitor);
+
+ // value (element) node specific operations
+ public:
+ /// Does this node assume its default value
+ /// retrieve the current value of this node
+ com::sun::star::uno::Any getValue(ValueNode const& _aNode) const;
+#if OSL_DEBUG_LEVEL > 0
+ /// get the type of this value
+ com::sun::star::uno::Type getValueType(ValueNode const& _aNode) const;
+#endif
+
+ // group node specific operations
+ public:
+ /// does this hold a child value of the given name
+ bool hasValue(GroupNode const& _aNode, rtl::OUString const& _aName) const;
+
+ /// does this hold a child value
+ bool hasValue(GroupNode const& _aNode) const;
+
+ /// are defaults for this node available ?
+ bool areValueDefaultsAvailable(GroupNode const& _aNode) const;
+
+ /// retrieve data for the child value of the given name
+ configuration::ValueMemberNode getValue(GroupNode const& _aNode, rtl::OUString const& _aName) const;
+
+ /// retrieve data for updating the child value of the given name
+ configuration::ValueMemberUpdate getValueForUpdate(GroupNode const & _aNode, rtl::OUString const& _aName);
+
+ // set node specific operations
+ public:
+ /// does this set contain any elements (loads elements if needed)
+ bool isEmpty(SetNode const& _aNode) const;
+
+ /// does this set contain an element named <var>aName</var> (loads elements if needed)
+ configuration::SetEntry findElement(SetNode const& _aNode, rtl::OUString const& aName) const;
+
+ /// does this set contain an element named <var>aName</var> (and is that element loaded ?)
+ configuration::SetEntry findAvailableElement(SetNode const& _aNode, rtl::OUString const& aName) const;
+
+ /// insert a new entry into this set
+ void insertElement(SetNode const& _aNode, rtl::OUString const& aName, configuration::SetEntry const& aNewEntry);
+
+ /// remove an existing entry into this set
+ void removeElement(SetNode const& _aNode, rtl::OUString const& aName);
+
+ /** Create a Subtree change as 'diff' which allows transforming the set to its default state
+ (given that <var>_rDefaultTree</var> points to a default instance of this set)
+ <p>Ownership of added trees should be transferred to the SubtreeChange.</p>
+ */
+ std::auto_ptr<SubtreeChange> differenceToDefaultState(SetNode const& _aNode, ISubtree& _rDefaultTree) const;
+
+ /// Get the template that describes elements of this set
+ rtl::Reference<configuration::Template> getElementTemplate(SetNode const& _aNode) const;
+
+ /// Get a template provider that can create new elements for this set
+ configuration::TemplateProvider getTemplateProvider(SetNode const& _aNode) const;
+
+ // create a configuration::Tree * from a configuration::SetEntry
+ configuration::Tree * extractTree(configuration::SetEntry const& _anEntry);
+
+ // creating/changing state/strategy
+ public:
+ NodeFactory& getNodeFactory();
+
+ // access to node innards
+ protected:
+ /// provide access to the address of the underlying node
+ sharable::Node * getNodeAddress(Node const& _aNode) const;
+
+ /// retrieve the attributes of the underlying node
+ node::Attributes getNodeAttributes(Node const& _aNode) const;
+
+ protected:
+ //helper for migration to new (info based) model for adjusting to changes
+ static void addLocalChangeHelper( configuration::NodeChangesInformation& rLocalChanges, configuration::NodeChange const& aChange);
+
+ private:
+ void implAdjustToValueChanges(configuration::NodeChangesInformation& rLocalChanges, GroupNode const& _aGroupNode, SubtreeChange const& rExternalChanges);
+ void implAdjustToSubChanges(configuration::NodeChangesInformation& rLocalChanges, GroupNode const & _aGroupNode, SubtreeChange const& rExternalChanges);
+ void implAdjustToElementChanges(configuration::NodeChangesInformation& rLocalChanges, SetNode const& _aNode, SubtreeChange const& rExternalChanges, unsigned int nDepth);
+ void implAdjustToElementChange (configuration::NodeChangesInformation& rLocalChanges, SetNode const& _aNode, Change const& rElementChange, unsigned int nElementDepth);
+ void implCommitDirectIn(sharable::TreeFragment * placeHolder, Node const& _aNode);
+
+ protected:
+ void checkInstance(configuration::Tree * tree) const;
+ configuration::SetEntry implFindElement(SetNode const& _aNode, rtl::OUString const& aName) const;
+ configuration::ElementTreeData implMakeElement(SetNode const& _aNode, configuration::SetEntry const& anEntry) const;
+
+ // virtual interface - these functions must be provided
+ private:
+ // change handling
+ virtual bool doHasChanges(Node const& _aNode) const = 0;
+ virtual void doMarkChanged(Node const& _aNode) = 0;
+
+ virtual NodeFactory& doGetNodeFactory() = 0;
+
+ // virtual interface - these functions all have default implementations without support for pending changes
+ protected:
+ // change handling
+ virtual void doCollectChanges(Node const& _aNode, configuration::NodeChanges& rChanges) const;
+
+ // commit protocol
+ virtual std::auto_ptr<SubtreeChange> doPreCommitChanges(configuration::Tree * tree, std::vector< rtl::Reference<configuration::ElementTree> >& _rRemovedElements);
+ virtual void doFailedCommit(configuration::Tree * tree, SubtreeChange& rChanges);
+ virtual void doFinishCommit(configuration::Tree * tree, SubtreeChange& rChanges);
+ virtual void doRevertCommit(configuration::Tree * tree, SubtreeChange& rChanges);
+
+ // notification protocol
+ virtual configuration::ValueChangeImpl* doAdjustToValueChange(GroupNode const& _aGroupNode, rtl::OUString const& aName, ValueChange const& rExternalChange);
+
+ // common attributes
+ virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const = 0;
+
+ // group member access
+ virtual configuration::ValueMemberNode doGetValueMember(GroupNode const& _aNode, rtl::OUString const& _aName, bool _bForUpdate) const = 0;
+
+ // set element access
+ virtual void doInsertElement(SetNode const& _aNode, rtl::OUString const& aName, configuration::SetEntry const& aNewEntry) = 0;
+ virtual void doRemoveElement(SetNode const& _aNode, rtl::OUString const& aName) = 0;
+ };
+
+ inline node::Attributes ViewStrategy::getAttributes(Node const& _aNode) const
+ { return doAdjustAttributes(getNodeAttributes(_aNode)); }
+
+ inline bool ViewStrategy::hasChanges(Node const& _aNode) const
+ { return doHasChanges(_aNode); }
+
+ inline NodeFactory& ViewStrategy::getNodeFactory()
+ { return doGetNodeFactory(); }
+
+//-----------------------------------------------------------------------------
+ }
+//-----------------------------------------------------------------------------
+}
+
+#endif // CONFIGMGR_CONFIGNODEBEHAVIOR_HXX_
diff --git a/configmgr/source/xml/basicparser.cxx b/configmgr/source/xml/basicparser.cxx
new file mode 100644
index 000000000000..4f7455679688
--- /dev/null
+++ b/configmgr/source/xml/basicparser.cxx
@@ -0,0 +1,536 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: basicparser.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "basicparser.hxx"
+#include <com/sun/star/xml/sax/SAXException.hpp>
+#include "valuetypeconverter.hxx"
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace sax = ::com::sun::star::xml::sax;
+// -----------------------------------------------------------------------------
+
+namespace
+{
+ static inline
+ uno::Reference< script::XTypeConverter > createTCV(uno::Reference< uno::XComponentContext > const & _xContext)
+ {
+ OSL_ENSURE(_xContext.is(),"Cannot create Parser without a Context");
+
+ static const rtl::OUString k_sTCVService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter"));
+
+ uno::Reference< lang::XMultiComponentFactory > xSvcFactory = _xContext->getServiceManager();
+ return uno::Reference< script::XTypeConverter >::query(xSvcFactory->createInstanceWithContext(k_sTCVService,_xContext));
+ }
+}
+// -----------------------------------------------------------------------------
+
+struct BasicParser::ValueData : ValueConverter
+{
+ rtl::OUString content;
+ rtl::OUString locale;
+ bool isLocalized;
+
+ ValueData(uno::Type const& _aType, uno::Reference< script::XTypeConverter > const & _xTCV)
+ : ValueConverter(_aType, _xTCV)
+ , content()
+ , locale()
+ , isLocalized(false)
+ {
+ }
+
+ uno::Any convertToAny() const
+ {
+ return ValueConverter::convertToAny(this->content);
+ }
+
+ rtl::OUString toString() const
+ {
+ return this->content;
+ }
+
+ uno::Sequence<rtl::OUString> toStringList() const
+ {
+ return ValueConverter::splitStringList(this->content);
+ }
+
+ void setLocalized(rtl::OUString const & _aLocale)
+ {
+ isLocalized = true;
+ locale = _aLocale;
+ }
+};
+// -----------------------------------------------------------------------------
+
+BasicParser::BasicParser(uno::Reference< uno::XComponentContext > const & _xContext)
+: m_xTypeConverter( createTCV(_xContext) )
+, m_xLocator(NULL)
+, m_aDataParser(Logger(_xContext))
+, m_aNodes()
+, m_aValueType()
+, m_pValueData(NULL)
+, m_nSkipLevels(0)
+, m_bEmpty(true)
+, m_bInProperty(false)
+{
+ if (!m_xTypeConverter.is())
+ throw uno::RuntimeException();
+
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+}
+// -----------------------------------------------------------------------------
+
+BasicParser::~BasicParser()
+{
+ delete m_pValueData;
+}
+// -----------------------------------------------------------------------------
+
+#if OSL_DEBUG_LEVEL > 0
+void BasicParser::dbgUpdateLocation()
+{
+#ifndef DBG_UTIL
+ rtl::OUString dbgPublicId, dbgSystemId;
+ sal_Int32 dbgLineNo, dbgColumnNo;
+#endif // OSL_DEBUG_LEVEL
+
+ if (m_xLocator.is())
+ {
+ dbgPublicId = m_xLocator->getPublicId();
+ dbgSystemId = m_xLocator->getSystemId();
+ dbgLineNo = m_xLocator->getLineNumber();
+ dbgColumnNo = m_xLocator->getColumnNumber();
+ }
+ else
+ {
+ dbgPublicId = dbgSystemId = rtl::OUString::createFromAscii("<<<unknown>>>");
+ dbgLineNo = dbgColumnNo = -1;
+ }
+}
+#endif
+// -----------------------------------------------------------------------------
+void SAL_CALL BasicParser::startDocument( )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ m_aDataParser.reset();
+ m_aValueType = uno::Type();
+ m_bInProperty = false;
+ m_nSkipLevels = 0;
+
+ delete m_pValueData, m_pValueData = NULL;
+
+ while (!m_aNodes.empty()) m_aNodes.pop();
+
+ m_bEmpty = true;
+
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicParser::endDocument( ) throw (sax::SAXException, uno::RuntimeException)
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ if (!m_aNodes.empty() || isSkipping() || isInValueData())
+ raiseParseException( "Configuration XML Parser - Invalid XML: Unexpected end of document" );
+
+ m_xLocator.clear();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicParser::characters( const rtl::OUString& aChars )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ if (isInValueData())
+ {
+ m_pValueData->content += aChars;
+ }
+#ifdef CONFIG_XMLPARSER_VALIDATE_WHITESPACE
+ else
+ OSL_ENSURE( isSkipping() || aChars.trim().getLength() == 0, "Unexpected text content in configuration XML");
+#endif
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicParser::ignorableWhitespace( const rtl::OUString& aWhitespaces )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+ if (isInValueData())
+ {
+ OSL_ENSURE(false, "Configuration XML: Unexpected ignorable (!) whitespace instruction in value data");
+ if (!m_pValueData->isNull())
+ m_pValueData->content += aWhitespaces;
+ }
+#ifdef CONFIG_XMLPARSER_VALIDATE_WHITESPACE
+ else
+ OSL_ENSURE( aChars.trim().getLength() == 0, "Unexpected non-space content in ignorable whitespace");
+#endif
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicParser::processingInstruction( const rtl::OUString& /*aTarget*/, const rtl::OUString& /*aData*/ )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+ OSL_ENSURE(false, "Unexpected processing instruction in Configuration XML");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL BasicParser::setDocumentLocator( const uno::Reference< sax::XLocator >& xLocator )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ m_xLocator = xLocator;
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& /*xAttribs*/ )
+{
+ { (void)aInfo; }
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ OSL_ENSURE( !isSkipping(), "While skipping, call startSkipping() instead of startNode()");
+ OSL_ENSURE( aInfo.type != ElementType::property, "For properties, call startProperty() instead of startNode()");
+
+ if (isInProperty())
+ raiseParseException( "Configuration XML Parser - Invalid Data: Cannot have a node nested in a property" );
+
+ m_aNodes.push(aInfo);
+ m_bEmpty = (aInfo.flags != 0) || (aInfo.op > Operation::modify);
+
+ OSL_POSTCOND( isInNode(), "Could not start a node ");
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::endNode( )
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ OSL_ENSURE( !isSkipping(), "While skipping, honor wasSkipping() instead of calling endNode()");
+ OSL_ENSURE( !isInProperty(), "For properties, call endProperty() instead of endNode()" );
+
+ ensureInNode();
+
+ m_aNodes.pop();
+ m_bEmpty = false;
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::ensureInNode( )
+{
+ if (!isInNode())
+ raiseParseException("Unexpected endElement without matching startElement");
+}
+// -----------------------------------------------------------------------------
+
+bool BasicParser::isInNode( )
+{
+ return ! m_aNodes.empty();
+}
+// -----------------------------------------------------------------------------
+
+bool BasicParser::isEmptyNode( )
+{
+ return m_bEmpty;
+}
+// -----------------------------------------------------------------------------
+
+ElementInfo const & BasicParser::getActiveNodeInfo( )
+{
+ ensureInNode();
+
+ return m_aNodes.top();
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ OSL_ENSURE( !isSkipping(), "While skipping, call startSkipping() instead of startProperty()");
+ OSL_ENSURE( aInfo.type == ElementType::property, "For non-property nodes, call startNode() instead of startProperty()");
+
+ if (isInProperty())
+ raiseParseException( "Configuration XML Parser - Invalid Data: Properties may not nest" );
+
+ try
+ {
+ m_aValueType = getDataParser().getPropertyValueType(xAttribs);
+ }
+ catch (ElementParser::BadValueType & error)
+ {
+ raiseParseException(error.message());
+ }
+
+ m_bInProperty = true;
+
+ m_aNodes.push(aInfo);
+ m_bEmpty = true;
+
+ OSL_POSTCOND( isInProperty(), "Could not get data to start a property" );
+ OSL_POSTCOND( isInUnhandledProperty(), "Could not mark property as unhandled");
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::endProperty( )
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ OSL_ENSURE( !isSkipping(), "While skipping, honor wasSkipping() instead of calling endProperty()");
+ OSL_ENSURE( isInProperty(), "For non-property nodes, call endNode() instead of endProperty()" );
+
+ ensureInNode();
+
+ m_aNodes.pop();
+ m_bEmpty = false;
+
+ m_aValueType = uno::Type();
+ m_bInProperty = false;
+
+ OSL_POSTCOND( !isInProperty(), "Could not get mark end of property" );
+}
+// -----------------------------------------------------------------------------
+
+uno::Type BasicParser::getActivePropertyType()
+{
+ return m_aValueType;
+}
+// -----------------------------------------------------------------------------
+
+bool BasicParser::isInProperty()
+{
+ return m_bInProperty;
+}
+// -----------------------------------------------------------------------------
+
+bool BasicParser::isInUnhandledProperty()
+{
+ return m_bEmpty && m_bInProperty;
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::startValueData(const uno::Reference< sax::XAttributeList >& xAttribs)
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ if (!isInProperty())
+ raiseParseException( "Configuration XML Parser - Invalid Data: A value may occur only within a property" );
+
+ if (m_aValueType.getTypeClass() == uno::TypeClass_ANY)
+ raiseParseException( "Configuration XML Parser - Invalid Data: Cannot have values for properties of type 'Any'" );
+
+ if (isInValueData())
+ raiseParseException( "Configuration XML Parser - Invalid Data: Unexpected element while parsing value data" );
+
+ m_pValueData = new ValueData(m_aValueType, m_xTypeConverter);
+
+ m_pValueData->setIsNull( getDataParser().isNull(xAttribs) );
+
+ m_pValueData->setSeparator( getDataParser().getSeparator(xAttribs) );
+
+ OSL_ENSURE( !m_pValueData->hasSeparator() ||
+ !m_pValueData->isTypeSet() ||
+ m_pValueData->isList(),
+ "Warning: Spurious oor:separator on value that is not a list");
+ OSL_ENSURE( !m_pValueData->hasSeparator() ||
+ !m_pValueData->isNull(),
+ "Warning: Spurious oor:separator on value that is not a list");
+
+ rtl::OUString aLocale;
+ if ( getDataParser().getLanguage(xAttribs,aLocale) )
+ m_pValueData->setLocalized( aLocale );
+}
+// -----------------------------------------------------------------------------
+
+bool BasicParser::isInValueData()
+{
+ return m_pValueData != NULL;
+}
+// -----------------------------------------------------------------------------
+
+bool BasicParser::isValueDataLocalized()
+{
+ OSL_ENSURE(isInValueData(), "There is no value data that could be localized");
+
+ return m_pValueData && m_pValueData->isLocalized;
+}
+// -----------------------------------------------------------------------------
+
+rtl::OUString BasicParser::getValueDataLocale()
+{
+ OSL_ENSURE(isValueDataLocalized(), "There is no value data or it is not localized");
+
+ return m_pValueData->locale;
+}
+// -----------------------------------------------------------------------------
+
+uno::Any BasicParser::getCurrentValue()
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ OSL_ASSERT( isInValueData() );
+
+ uno::Any aResult;
+
+ if (m_pValueData->isTypeSet())
+ try
+ {
+ aResult = m_pValueData->convertToAny();
+ }
+ catch (script::CannotConvertException & e)
+ {
+ this->raiseParseException(uno::makeAny(e),"Configuration XML Parser - Invalid Data: Cannot convert value to type of property" );
+ }
+ else if (m_pValueData->isNull())
+ {
+ // nothing to do
+ }
+ else if (m_pValueData->hasSeparator() || m_pValueData->isList())
+ {
+ aResult <<= m_pValueData->toStringList();
+ }
+ else
+ {
+ aResult <<= m_pValueData->toString();
+ }
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+
+/// end collecting data for a value
+void BasicParser::endValueData()
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ OSL_ASSERT( isInValueData() );
+
+ delete m_pValueData, m_pValueData = NULL;
+ m_bEmpty = false;
+
+ OSL_POSTCOND( !isInValueData(), "Could not end value data tag" );
+ OSL_POSTCOND( !isInUnhandledProperty(), "Could not mark property as handled" );
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::startSkipping( const rtl::OUString& aName, const uno::Reference< sax::XAttributeList >& /*xAttribs*/ )
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ m_aNodes.push( ElementInfo(aName) );
+ ++m_nSkipLevels;
+}
+// -----------------------------------------------------------------------------
+
+bool BasicParser::wasSkipping( const rtl::OUString& aName )
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ if (m_nSkipLevels == 0) return false;
+
+ if (m_aNodes.empty())
+ raiseParseException( "Configuration XML Parser - Invalid XML: Unexpected end of element (while skipping data)" );
+
+ if (aName != m_aNodes.top().name)
+ raiseParseException( "Configuration XML Parser - Invalid XML: End tag does not match start tag (while skipping data)" );
+
+ --m_nSkipLevels;
+ m_aNodes.pop();
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+bool BasicParser::isSkipping( )
+{
+ return m_nSkipLevels != 0;
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::raiseParseException( uno::Any const & _aTargetException, sal_Char const * _pMsg )
+ SAL_THROW((sax::SAXException, uno::RuntimeException))
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ if (_pMsg == 0) _pMsg = "Configuration XML Parser: Invalid Data: ";
+
+ rtl::OUString sMessage = rtl::OUString::createFromAscii(_pMsg);
+
+ uno::Exception aEx;
+ if (_aTargetException >>= aEx)
+ sMessage += aEx.Message;
+
+ getLogger().error(sMessage,"parse","configuration::xml::BasicParser");
+ throw sax::SAXException( sMessage, *this, _aTargetException );
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::raiseParseException( sal_Char const * _pMsg )
+ SAL_THROW((sax::SAXException, uno::RuntimeException))
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ if (_pMsg == 0) _pMsg = "Configuration XML Parser: Invalid XML";
+
+ rtl::OUString const sMessage = rtl::OUString::createFromAscii(_pMsg);
+
+ getLogger().error(sMessage,"parse","configuration::xml::BasicParser");
+ throw sax::SAXException( sMessage, *this, uno::Any() );
+}
+// -----------------------------------------------------------------------------
+
+void BasicParser::raiseParseException( rtl::OUString const & sMessage )
+ SAL_THROW((sax::SAXException, uno::RuntimeException))
+{
+ OSL_DEBUG_ONLY( dbgUpdateLocation() );
+
+ if (sMessage.getLength() == 0) raiseParseException(NULL);
+
+ getLogger().error(sMessage,"parse","configuration::xml::BasicParser");
+ throw sax::SAXException( sMessage, *this, uno::Any() );
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/xml/basicparser.hxx b/configmgr/source/xml/basicparser.hxx
new file mode 100644
index 000000000000..eaf40cf07c18
--- /dev/null
+++ b/configmgr/source/xml/basicparser.hxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: basicparser.hxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_BASICPARSER_HXX
+#define CONFIGMGR_XML_BASICPARSER_HXX
+
+#include "elementparser.hxx"
+#include "utility.hxx"
+#include "stack.hxx"
+#ifndef CONFIGMGR_LOGGER_HXX_
+#include "logger.hxx"
+#endif
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+namespace com { namespace sun { namespace star { namespace script {
+ class XTypeConverter;
+} } } }
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ namespace sax = ::com::sun::star::xml::sax;
+// -----------------------------------------------------------------------------
+
+ class BasicParser
+ : public cppu::WeakImplHelper1<sax::XDocumentHandler>
+ {
+ struct ValueData;
+
+ uno::Reference< com::sun::star::script::XTypeConverter >
+ m_xTypeConverter;
+ uno::Reference< sax::XLocator > m_xLocator;
+ ElementParser m_aDataParser;
+ Stack< ElementInfo > m_aNodes;
+ uno::Type m_aValueType;
+ ValueData * m_pValueData;
+ sal_uInt16 m_nSkipLevels;
+ bool m_bEmpty;
+ bool m_bInProperty;
+
+#if OSL_DEBUG_LEVEL > 0
+#ifdef DBG_UTIL
+ rtl::OUString dbgPublicId, dbgSystemId;
+ sal_Int32 dbgLineNo, dbgColumnNo;
+#endif // DBG_UTIL
+ void dbgUpdateLocation();
+#endif // OSL_DEBUG_LEVEL
+
+ public:
+ explicit BasicParser(uno::Reference< uno::XComponentContext > const & _xContext);
+ virtual ~BasicParser();
+
+ // XDocumentHandler
+ public:
+ virtual void SAL_CALL
+ startDocument( )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endDocument( ) throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ characters( const rtl::OUString& aChars )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ ignorableWhitespace( const rtl::OUString& aWhitespaces )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setDocumentLocator( const uno::Reference< sax::XLocator >& xLocator )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ protected:
+ ElementParser const & getDataParser() const { return m_aDataParser; }
+
+ Logger const & getLogger() { return m_aDataParser.logger(); }
+
+ /// start an node
+ void startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// are we in the content of a node ?
+ bool isInNode();
+ /// are we in the content of node for which no content was started yet ?
+ bool isEmptyNode();
+ /// make sure we are in the content of a node ?
+ void ensureInNode();
+ /// get the info about of the node currently being processed
+ ElementInfo const & getActiveNodeInfo();
+ /// end a node
+ void endNode();
+
+ /// start a property
+ void startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// are we in the content of a property node ?
+ bool isInProperty();
+ /// are we in the content of a property node (and there has been no value for that property) ?
+ bool isInUnhandledProperty();
+ /// get the data type of the active property ?
+ uno::Type getActivePropertyType();
+ /// end a property
+ void endProperty();
+
+ /// start collecting data for a value - returns the locale of the value (property must have been started)
+ void startValueData(const uno::Reference< sax::XAttributeList >& xAttribs);
+ /// are we in the content of a property node ?
+ bool isInValueData();
+ /// check if the current value data has a locale set
+ bool isValueDataLocalized();
+ /// get the locale of the current value data, if localized
+ rtl::OUString getValueDataLocale();
+ /// return the collected value
+ uno::Any getCurrentValue();
+ /// end collecting data for a value
+ void endValueData();
+
+ /// start a node to be skipped
+ void startSkipping( const rtl::OUString& aTag, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// are we inside a skipped node ?
+ bool isSkipping( );
+ /// ending a node: was this skipped ?
+ bool wasSkipping( const rtl::OUString& aTag );
+
+ protected:
+ void raiseParseException( uno::Any const & _aTargetException, sal_Char const * _pMsg = NULL)
+ SAL_THROW((sax::SAXException, uno::RuntimeException));
+ void raiseParseException( sal_Char const * _pMsg )
+ SAL_THROW((sax::SAXException, uno::RuntimeException));
+ void raiseParseException( rtl::OUString const & aMsg )
+ SAL_THROW((sax::SAXException, uno::RuntimeException));
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/xml/elementformatter.cxx b/configmgr/source/xml/elementformatter.cxx
new file mode 100644
index 000000000000..fb883f9d28d8
--- /dev/null
+++ b/configmgr/source/xml/elementformatter.cxx
@@ -0,0 +1,324 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementformatter.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "elementformatter.hxx"
+#include "xmlstrings.hxx"
+#include "typeconverter.hxx"
+
+#include <comphelper/attributelist.hxx>
+
+#include <rtl/ustrbuf.hxx>
+
+#include <com/sun/star/configuration/backend/SchemaAttribute.hpp>
+#include <com/sun/star/configuration/backend/NodeAttribute.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace sax = ::com::sun::star::xml::sax;
+// -----------------------------------------------------------------------------
+
+ElementFormatter::ElementFormatter()
+: m_aElementType(ElementType::unknown)
+, m_xAttributes()
+{
+}
+// -----------------------------------------------------------------------------
+
+ElementFormatter::~ElementFormatter()
+{
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::reset()
+{
+ m_aElementType = ElementType::unknown;
+ m_xAttributes.clear();
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addAttribute(rtl::OUString const & _anAttributeName, rtl::OUString const & _aValue)
+{
+ OSL_PRECOND(m_xAttributes.is(),"Trying to add an attribute to a non-existing list");
+
+ m_xAttributes->AddAttribute(_anAttributeName,
+ XML_ATTRTYPE_CDATA,
+ _aValue);
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addAttribute(rtl::OUString const & _anAttributeName, bool _bValue)
+{
+ OSL_PRECOND(m_xAttributes.is(),"Trying to add an attribute to a non-existing list");
+
+ m_xAttributes->AddAttribute(_anAttributeName,
+ XML_ATTRTYPE_CDATA,
+ _bValue ? ATTR_VALUE_TRUE : ATTR_VALUE_FALSE);
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addNamespaces()
+{
+ static rtl::OUString const sNamespaceDecl( RTL_CONSTASCII_USTRINGPARAM("xmlns:") );
+
+ addAttribute( sNamespaceDecl.concat(NS_PREFIX_OOR), static_cast<rtl::OUString const &>(NS_URI_OOR));
+ addAttribute( sNamespaceDecl.concat(NS_PREFIX_XS ), static_cast<rtl::OUString const &>(NS_URI_XS ));
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::prepareElement(ElementInfo const& _aInfo)
+{
+ if (!m_xAttributes.is())
+ {
+ m_xAttributes.set( new ::comphelper::AttributeList() );
+ addNamespaces();
+ }
+ else
+ m_xAttributes->Clear();
+
+ m_aElementType = _aInfo.type;
+
+ addName(_aInfo.name);
+ addNodeFlags(_aInfo.flags);
+ addOperation(_aInfo.op);
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::prepareSimpleElement(ElementType::Enum _eType)
+{
+ if (!m_xAttributes.is())
+ {
+ m_xAttributes.set( new ::comphelper::AttributeList() );
+ addNamespaces();
+ }
+ else
+ m_xAttributes->Clear();
+
+ m_aElementType = _eType;
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addName(rtl::OUString const & _aName)
+{
+ if (_aName.getLength())
+ {
+ switch( m_aElementType )
+ {
+ case ElementType::schema:
+ case ElementType::layer:
+ {
+ sal_Int32 nIndex = _aName.lastIndexOf('.');
+
+ rtl::OUString aNodeName = _aName.copy(nIndex + 1);
+ addAttribute(ATTR_NAME, aNodeName);
+
+ OSL_ENSURE(nIndex > 0,"Found component root element without a package part in its name");
+ if (nIndex > 0)
+ {
+ rtl::OUString aPackage = _aName.copy(0, nIndex);
+ addAttribute(ATTR_PACKAGE, aPackage);
+ }
+ }
+ break;
+
+ default:
+ addAttribute(ATTR_NAME, _aName);
+ break;
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+inline
+void ElementFormatter::maybeAddFlag(sal_Int16 _eFlags, sal_Int16 _eSelect, rtl::OUString const & _anAttributeName, bool _bValue)
+{
+ if (_eFlags & _eSelect) addAttribute(_anAttributeName,_bValue);
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addNodeFlags(sal_Int16 _eFlags)
+{
+ maybeAddFlag(_eFlags,com::sun::star::configuration::backend::SchemaAttribute::REQUIRED, ATTR_FLAG_NULLABLE, false);
+ maybeAddFlag(_eFlags,com::sun::star::configuration::backend::SchemaAttribute::LOCALIZED, ATTR_FLAG_LOCALIZED);
+ maybeAddFlag(_eFlags,com::sun::star::configuration::backend::SchemaAttribute::EXTENSIBLE, ATTR_FLAG_EXTENSIBLE);
+
+ maybeAddFlag(_eFlags,com::sun::star::configuration::backend::NodeAttribute::FINALIZED, ATTR_FLAG_FINALIZED);
+ maybeAddFlag(_eFlags,com::sun::star::configuration::backend::NodeAttribute::MANDATORY, ATTR_FLAG_MANDATORY);
+ maybeAddFlag(_eFlags,com::sun::star::configuration::backend::NodeAttribute::READONLY, ATTR_FLAG_READONLY);
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addOperation(Operation::Enum _eOp)
+{
+ switch (_eOp)
+ {
+ case Operation::none: break;
+ case Operation::modify: break ; //addAttribute(ATTR_OPERATION, static_cast<rtl::OUString const &>(OPERATION_MODIFY)); break;
+ case Operation::clear: OSL_ENSURE(false,"'clear' operation is not yet supported"); break ;
+ //addAttribute(ATTR_OPERATION, static_cast<rtl::OUString const &>(OPERATION_CLEAR)); break;
+ case Operation::replace: addAttribute(ATTR_OPERATION, static_cast<rtl::OUString const &>(OPERATION_REPLACE)); break;
+ case Operation::fuse: addAttribute(ATTR_OPERATION, static_cast<rtl::OUString const &>(OPERATION_FUSE)); break;
+ case Operation::remove: addAttribute(ATTR_OPERATION, static_cast<rtl::OUString const &>(OPERATION_REMOVE)); break;
+
+ case Operation::unknown:
+ OSL_ENSURE(false, "ElementFormatter: Trying to add attribute for 'unknown' operation");
+ break;
+ default:
+ OSL_ENSURE(false, "ElementFormatter: Trying to add attribute for invalid operation");
+ break;
+ }
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addInstanceType(rtl::OUString const & /*_aElementType*/, rtl::OUString const & /*_aElementTypeModule*/)
+{
+}
+// -----------------------------------------------------------------------------
+
+static ::rtl::OUString toXmlTypeName(const uno::TypeClass& _rTypeClass)
+{
+ ::rtl::OUString aRet;
+ switch(_rTypeClass)
+ {
+ case uno::TypeClass_BOOLEAN: aRet = VALUETYPE_BOOLEAN; break;
+ case uno::TypeClass_SHORT: aRet = VALUETYPE_SHORT; break;
+ case uno::TypeClass_LONG: aRet = VALUETYPE_INT; break;
+ case uno::TypeClass_HYPER: aRet = VALUETYPE_LONG; break;
+ case uno::TypeClass_DOUBLE: aRet = VALUETYPE_DOUBLE; break;
+ case uno::TypeClass_STRING: aRet = VALUETYPE_STRING; break;
+ case uno::TypeClass_SEQUENCE: aRet = VALUETYPE_BINARY; break;
+ case uno::TypeClass_ANY: aRet = VALUETYPE_ANY; break;
+ default:
+ OSL_ENSURE(false,"Cannot get type name: unknown typeclass");
+ break;
+ }
+ return aRet;
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addPropertyValueType(uno::Type const& _aType)
+{
+ if (_aType == uno::Type()) return;
+
+ bool bList = false;
+ uno::Type aSimpleType = getBasicType(_aType, bList);
+ uno::TypeClass aSimpleTypeClass = aSimpleType.getTypeClass();
+ rtl::OUString aSimpleTypeName = toXmlTypeName(aSimpleTypeClass);
+
+ rtl::OUString sNsPrefix = (bList || aSimpleTypeClass == uno::TypeClass_ANY) ?
+ rtl::OUString( NS_PREFIX_OOR ) : rtl::OUString( NS_PREFIX_XS );
+
+ rtl::OUStringBuffer aTypeNameBuf(sNsPrefix);
+
+ if (sNsPrefix.getLength())
+ aTypeNameBuf. append(k_NS_SEPARATOR);
+
+ aTypeNameBuf. append(aSimpleTypeName);
+
+ if (bList)
+ aTypeNameBuf. append(VALUETYPE_LIST_SUFFIX);
+
+ addAttribute( ATTR_VALUETYPE, aTypeNameBuf.makeStringAndClear());
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addLanguage(rtl::OUString const & _sLanguage)
+{
+ OSL_ENSURE(_sLanguage.getLength(), "ElementFormatter: Trying to add empty language attribute");
+ addAttribute(EXT_ATTR_LANGUAGE, _sLanguage);
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addIsNull(bool _bIsNull)
+{
+ addAttribute( EXT_ATTR_NULL, _bIsNull);
+}
+// -----------------------------------------------------------------------------
+
+void ElementFormatter::addSeparator(rtl::OUString const& _sSeparator)
+{
+ addAttribute( ATTR_VALUESEPARATOR, _sSeparator);
+}
+// -----------------------------------------------------------------------------
+
+rtl::OUString ElementFormatter::getElementTag() const
+{
+ switch (m_aElementType)
+ {
+ case ElementType::schema: return rtl::OUString( TAG_SCHEMA );
+ case ElementType::layer: return rtl::OUString( TAG_LAYER );
+
+ case ElementType::component: return rtl::OUString( TAG_COMPONENT );
+ case ElementType::templates: return rtl::OUString( TAG_TEMPLATES );
+
+ case ElementType::property: return rtl::OUString( TAG_PROP );
+ case ElementType::node: return rtl::OUString( TAG_NODE );
+ case ElementType::group: return rtl::OUString( TAG_GROUP );
+ case ElementType::set: return rtl::OUString( TAG_SET );
+
+ case ElementType::import: return rtl::OUString( TAG_IMPORT );
+ case ElementType::instance: return rtl::OUString( TAG_INSTANCE );
+ case ElementType::item_type: return rtl::OUString( TAG_ITEMTYPE );
+ case ElementType::value: return rtl::OUString( TAG_VALUE );
+ case ElementType::uses: return rtl::OUString( TAG_USES );
+
+ case ElementType::unknown:
+ OSL_ENSURE(false, "ElementFormatter: Trying to get Tag for 'unknown' element type");
+ break;
+ case ElementType::other:
+ OSL_ENSURE(false, "ElementFormatter: Trying to get Tag for 'other' element type");
+ break;
+ default:
+ OSL_ENSURE(false, "ElementFormatter: Trying to get Tag for invalid element type");
+ break;
+ }
+ return rtl::OUString();
+}
+// -----------------------------------------------------------------------------
+
+uno::Reference< sax::XAttributeList > ElementFormatter::getElementAttributes() const
+{
+ return m_xAttributes.get();
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+} // namespace
+} // namespace
+
diff --git a/configmgr/source/xml/elementformatter.hxx b/configmgr/source/xml/elementformatter.hxx
new file mode 100644
index 000000000000..0e7d92489c93
--- /dev/null
+++ b/configmgr/source/xml/elementformatter.hxx
@@ -0,0 +1,118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementformatter.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_ELEMENTFORMATTER_HXX
+#define CONFIGMGR_XML_ELEMENTFORMATTER_HXX
+
+#include "elementinfo.hxx"
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+
+#include <rtl/ref.hxx>
+
+namespace comphelper {
+ class AttributeList;
+}
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace sax = ::com::sun::star::xml::sax;
+
+// -----------------------------------------------------------------------------
+ class ElementFormatter
+ {
+ public:
+ ElementFormatter();
+ ~ElementFormatter();
+
+ /// reset the formatter for a new document
+ void reset();
+
+ /// resets the formatter for a new element type
+ void prepareElement(ElementInfo const& _aInfo);
+
+ /// resets the formatter for a new element type
+ void prepareSimpleElement(ElementType::Enum _eType);
+
+ /// sets the instantiated type of a set item,
+ void addInstanceType(rtl::OUString const & _aElementType, rtl::OUString const & _aElementTypeModule);
+
+ /// retrieve element type and associated module name of a set,
+ void addPropertyValueType(uno::Type const& _aType);
+
+ /// add a language for the current element
+ void addLanguage(rtl::OUString const & _sLanguage);
+
+ /// adds a value attribute to the attribute list
+ void addIsNull(bool _bIsNull = true);
+
+ /// adds a value attribute to the attribute list
+ void addSeparator(rtl::OUString const& _sSeparator);
+
+ /// retrieve the tag to use for the current element
+ rtl::OUString getElementTag() const;
+
+ /// retrieve the attributes to use for the current element
+ uno::Reference< sax::XAttributeList > getElementAttributes() const;
+
+ /// retrieve the attributes to use for an element with associated component
+ private:
+ void addNamespaces();
+ /// sets an attributes for a node
+ void addName(rtl::OUString const & _aName);
+ /// sets attributes for nodes from the flags
+ void addNodeFlags(sal_Int16 _eFlags);
+ /// sets attributes for nodes from the flags
+ void addOperation(Operation::Enum _eOp);
+ /// sets attributes for nodes from the flags
+ void maybeAddFlag(sal_Int16 _eFlags, sal_Int16 _eSelect,
+ rtl::OUString const & _anAttributeName, bool _bValue = true);
+
+ /// sets attributes for nodes
+ void addAttribute(rtl::OUString const & _anAttributeName, rtl::OUString const & _aValue);
+ void addAttribute(rtl::OUString const & _anAttributeName, bool _bValue);
+
+ private:
+ ElementType::Enum m_aElementType;
+ rtl::Reference< ::comphelper::AttributeList> m_xAttributes;
+ };
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/xml/elementinfo.hxx b/configmgr/source/xml/elementinfo.hxx
new file mode 100644
index 000000000000..6c22ca360c01
--- /dev/null
+++ b/configmgr/source/xml/elementinfo.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementinfo.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */
+
+#ifndef CONFIGMGR_XML_ELEMENTINFO_HXX
+#define CONFIGMGR_XML_ELEMENTINFO_HXX
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace ElementType
+ {
+ enum Enum
+ {
+ unknown,
+
+ schema,
+ layer,
+
+ component,
+ templates,
+
+ property,
+ node,
+ group,
+ set,
+
+ import,
+ instance,
+ item_type,
+ value,
+ uses,
+
+ other
+ };
+ }
+// -----------------------------------------------------------------------------
+ namespace Operation
+ {
+ enum Enum
+ {
+ none,
+
+ modify,
+ clear,
+
+ replace,
+ fuse,
+ remove,
+
+ unknown
+ };
+ }
+// -----------------------------------------------------------------------------
+ struct ElementInfo
+ {
+ explicit
+ ElementInfo(ElementType::Enum _type = ElementType::unknown)
+ : name()
+ , type(_type)
+ , op(Operation::none)
+ , flags()
+ {}
+
+ explicit
+ ElementInfo(rtl::OUString const & _name, ElementType::Enum _type = ElementType::unknown)
+ : name(_name)
+ , type(_type)
+ , op(Operation::none)
+ , flags()
+ {}
+
+
+ rtl::OUString name;
+ ElementType::Enum type;
+ Operation::Enum op;
+ sal_Int16 flags;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/xml/elementparser.cxx b/configmgr/source/xml/elementparser.cxx
new file mode 100644
index 000000000000..663294a0b97c
--- /dev/null
+++ b/configmgr/source/xml/elementparser.cxx
@@ -0,0 +1,585 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementparser.cxx,v $
+ * $Revision: 1.16 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "elementparser.hxx"
+#include "xmlstrings.hxx"
+#include "typeconverter.hxx"
+
+#include <com/sun/star/configuration/backend/SchemaAttribute.hpp>
+#include <com/sun/star/configuration/backend/NodeAttribute.hpp>
+
+#include <rtl/ustrbuf.hxx>
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace sax = ::com::sun::star::xml::sax;
+// -----------------------------------------------------------------------------
+
+static
+inline
+sal_Int16 impl_getIndexByName(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString const& aAttributeName)
+{
+ OSL_PRECOND( xAttribs.is(), "ERROR: NULL Attribute list");
+
+ sal_Int16 nIndex = xAttribs->getLength();
+
+ while (--nIndex >= 0)
+ {
+ if (xAttribs->getNameByIndex(nIndex).equals(aAttributeName))
+ break;
+ }
+ // nIndex == -1 if not found
+
+ return nIndex;
+}
+// -----------------------------------------------------------------------------
+static
+inline
+bool impl_maybeGetAttribute(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString const& aAttributeName, /* OUT */ rtl::OUString& rAttributeValue)
+{
+ OSL_PRECOND( xAttribs.is(), "ERROR: NULL Attribute list");
+
+ rtl::OUString aValue = xAttribs->getValueByName(aAttributeName);
+ if( aValue.getLength()!=0)
+ {
+ rAttributeValue = aValue;
+ return true;
+ }
+ return false;
+}
+// -----------------------------------------------------------------------------
+
+/// retrieve the (almost) complete information for an element
+ElementInfo ElementParser::parseElementInfo(rtl::OUString const& _sTag, uno::Reference< sax::XAttributeList > const& _xAttribs) const
+{
+ ElementType::Enum aType = this->getNodeType(_sTag,_xAttribs);
+
+ ElementInfo aInfo( this->getName(_sTag,_xAttribs,aType), aType );
+
+ aInfo.op = this->getOperation(_xAttribs,aType);
+ aInfo.flags = this->getNodeFlags(_xAttribs,aType);
+
+ return aInfo;
+}
+// -----------------------------------------------------------------------------
+
+ElementType::Enum ElementParser::getNodeType(rtl::OUString const& _sElementName, uno::Reference< sax::XAttributeList > const& _xAttribs) const
+{
+ { (void)_xAttribs; }
+ OSL_PRECOND( _xAttribs.is(), "ERROR: NULL Attribute list");
+
+ // todo: make this use a table, if necessary
+ ElementType::Enum eResult = ElementType::unknown;
+ if (_sElementName.equals(TAG_VALUE))
+ eResult = ElementType::value;
+
+ else if (_sElementName.equals(TAG_PROP))
+ eResult = ElementType::property;
+
+ else if (_sElementName.equals(TAG_NODE))
+ eResult = ElementType::node;
+
+ else if (_sElementName.equals(TAG_GROUP))
+ eResult = ElementType::group;
+
+ else if (_sElementName.equals(TAG_SET))
+ eResult = ElementType::set;
+
+ else if (_sElementName.equals(TAG_INSTANCE))
+ eResult = ElementType::instance;
+
+ else if (_sElementName.equals(TAG_ITEMTYPE))
+ eResult = ElementType::item_type;
+
+ else if (_sElementName.equals(TAG_IMPORT))
+ eResult = ElementType::import;
+
+ else if (_sElementName.equals(TAG_LAYER))
+ eResult = ElementType::layer;
+
+ else if (_sElementName.equals(TAG_SCHEMA))
+ eResult = ElementType::schema;
+
+ else if (_sElementName.equals(TAG_COMPONENT))
+ eResult = ElementType::component;
+
+ else if (_sElementName.equals(TAG_TEMPLATES))
+ eResult = ElementType::templates;
+
+ else if (_sElementName.equals(TAG_USES))
+ eResult = ElementType::uses;
+
+ // #109668# maintain support for old tag on load
+ else if (_sElementName.equals(DEPRECATED_TAG_LAYER))
+ {
+ logger().warning("Layer starts with invalid root tag \"oor:node\". Use \"oor:component-data\" instead.",
+ "getNodeType()","configmgr::xml::ElementParser");
+ eResult = ElementType::layer;
+ }
+
+ else
+ eResult = ElementType::other;
+
+ return eResult;
+}
+// -----------------------------------------------------------------------------
+
+/// takes the node name from either an attribute or the element name
+rtl::OUString ElementParser::getName(rtl::OUString const& _sElementName, uno::Reference< sax::XAttributeList > const& _xAttribs, ElementType::Enum _eType) const
+{
+ rtl::OUString aName;
+ rtl::OUString aPackage;
+
+ bool bNameFound = this->maybeGetAttribute(_xAttribs, ATTR_NAME, aName);
+ bool bPackage = false;
+
+ switch (_eType)
+ {
+ case ElementType::schema:
+ bPackage = this->maybeGetAttribute(_xAttribs,ATTR_PACKAGE,aPackage);
+ OSL_ENSURE(bPackage, "configmgr::xml::ElementParser: Found schema without package.");
+ break;
+
+ case ElementType::layer:
+ bPackage = this->maybeGetAttribute(_xAttribs,ATTR_PACKAGE,aPackage);
+
+ if (!bPackage) // for compatibility we still support 'oor:context'
+ {
+ bPackage = this->maybeGetAttribute(_xAttribs,ATTR_CONTEXT,aPackage);
+
+ if (bPackage)
+ {
+ // TODO: log this
+ OSL_TRACE("configmgr::xml::ElementParser: Found obsolete layer attribute "
+ "oor:context=\"%s\" in component \"%s\".\n",
+ rtl::OUStringToOString(aPackage,RTL_TEXTENCODING_ASCII_US).getStr(),
+ rtl::OUStringToOString(aName,RTL_TEXTENCODING_ASCII_US).getStr());
+ }
+ }
+
+ OSL_ENSURE(bPackage, "configmgr::xml::ElementParser: Found layer without package.");
+ break;
+
+ case ElementType::node:
+ case ElementType::set:
+ case ElementType::group:
+ case ElementType::instance:
+ case ElementType::property:
+ break;
+
+ // these have no name to speak of
+ case ElementType::value:
+ case ElementType::item_type:
+ case ElementType::import:
+ case ElementType::uses:
+ case ElementType::templates:
+ case ElementType::component:
+ OSL_ENSURE(!bNameFound, "Configuration Parser: Unexpected name attribute is ignored\n");
+ return _sElementName;
+
+ // for unknown prefer name to
+ case ElementType::unknown:
+ if (!bNameFound) return _sElementName;
+
+ bPackage = this->maybeGetAttribute(_xAttribs,ATTR_PACKAGE,aPackage);
+ break;
+
+ default:
+ if (!bNameFound) return _sElementName;
+ break;
+ }
+
+ OSL_ENSURE(aName.getLength(),"Found empty name tag on element");
+
+ if (bPackage)
+ {
+ static const sal_Unicode chPackageSep = '.';
+
+ aName = aPackage.concat(rtl::OUString(&chPackageSep,1)).concat(aName);
+ }
+ else
+ {
+ OSL_ENSURE(!this->maybeGetAttribute(_xAttribs,ATTR_PACKAGE,aPackage),
+ "configmgr::xml::ElementParser: Found unexpected 'oor:package' on inner or unknown node." );
+ }
+
+ return aName;
+}
+// -----------------------------------------------------------------------------
+
+Operation::Enum ElementParser::getOperation(uno::Reference< sax::XAttributeList > const& xAttribs,ElementType::Enum _eType) const
+{
+ rtl::OUString sOpName;
+ if ((_eType != ElementType::property) && (_eType !=ElementType::node))
+ {
+ return Operation::none;
+ }
+
+ if ( !this->maybeGetAttribute(xAttribs,ATTR_OPERATION, sOpName) )
+ return Operation::none;
+
+ if (sOpName.equals(OPERATION_MODIFY))
+ return Operation::modify;
+
+ else if (sOpName.equals(OPERATION_REPLACE))
+ return Operation::replace;
+ else if (sOpName.equals(OPERATION_FUSE))
+ return Operation::fuse;
+
+ else if (sOpName.equals(OPERATION_REMOVE))
+ return Operation::remove;
+#if 0
+ else if (sOpName.equals(OPERATION_CLEAR))
+ return Operation::clear;
+#endif
+ else
+ return Operation::unknown;
+}
+// -----------------------------------------------------------------------------
+
+
+/// retrieve the locale stored in the attribute list
+bool ElementParser::getLanguage(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString& _rsLanguage) const
+{
+ return this->maybeGetAttribute(xAttribs, EXT_ATTR_LANGUAGE, _rsLanguage);
+}
+// -----------------------------------------------------------------------------
+
+/// reads attributes for nodes from the attribute list
+sal_Int16 ElementParser::getNodeFlags(uno::Reference< sax::XAttributeList > const& xAttribs,ElementType::Enum _eType) const
+{
+ namespace NodeAttribute = ::com::sun::star::configuration::backend::NodeAttribute;
+ namespace SchemaAttribute = ::com::sun::star::configuration::backend::SchemaAttribute;
+
+ bool bValue;
+
+ sal_Int16 aResult = 0;
+
+ switch(_eType)
+ {
+ case ElementType::property :
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_NULLABLE, bValue) && ! bValue)
+ aResult |= SchemaAttribute::REQUIRED;
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_LOCALIZED, bValue) && bValue)
+ aResult |= SchemaAttribute::LOCALIZED;
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_READONLY, bValue) && bValue)
+ aResult |= NodeAttribute::READONLY;
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_FINALIZED, bValue) && bValue)
+ aResult |= NodeAttribute::FINALIZED;
+ break;
+
+ case ElementType::node:
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_FINALIZED, bValue) && bValue)
+ aResult |= NodeAttribute::FINALIZED;
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_MANDATORY, bValue) && bValue)
+ aResult |= NodeAttribute::MANDATORY;
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_READONLY, bValue) && bValue)
+ aResult |= NodeAttribute::READONLY;
+ break;
+
+ case ElementType::group:
+ case ElementType::set:
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_EXTENSIBLE, bValue) && bValue)
+ aResult |= SchemaAttribute::EXTENSIBLE;
+ break;
+
+ case ElementType::layer:
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_READONLY, bValue) && bValue)
+ aResult |= NodeAttribute::READONLY;
+ if (this->maybeGetAttribute(xAttribs, ATTR_FLAG_FINALIZED, bValue) && bValue)
+ aResult |= NodeAttribute::FINALIZED;
+ break;
+
+ default:
+ break;
+
+ }
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+static
+void badValueType(Logger const & logger, sal_Char const * _pMsg, rtl::OUString const & _sType)
+{
+ rtl::OUStringBuffer sMessageBuf;
+ sMessageBuf.appendAscii( "Configuration XML parser: Bad value type attribute: " );
+ if (_pMsg) sMessageBuf.appendAscii(_pMsg);
+
+ const sal_Unicode kQuote = '"';
+ sMessageBuf.append(kQuote).append(_sType).append(kQuote);
+
+ rtl::OUString const sMessage = sMessageBuf.makeStringAndClear();
+ logger.error(sMessage);
+ throw ElementParser::BadValueType(sMessage);
+}
+// -----------------------------------------------------------------------------
+static
+inline
+sal_Bool matchNsPrefix(rtl::OUString const & _sString, rtl::OUString const & _sPrefix)
+{
+ return _sString.match(_sPrefix) &&
+ _sString.getStr()[_sPrefix.getLength()] == k_NS_SEPARATOR;
+}
+// -----------------------------------------------------------------------------
+static
+inline
+sal_Bool matchSuffix(rtl::OUString const & _sString, rtl::OUString const & _sSuffix)
+{
+ sal_Int32 nSuffixStart = _sString.getLength() - _sSuffix.getLength();
+ if (nSuffixStart < 0)
+ return false;
+
+ return _sString.match(_sSuffix,nSuffixStart);
+}
+// -----------------------------------------------------------------------------
+static
+inline
+rtl::OUString stripNsPrefix(rtl::OUString const & _sString, rtl::OUString const & _sPrefix)
+{
+ OSL_ASSERT( matchNsPrefix(_sString,_sPrefix) );
+
+ return _sString.copy(_sPrefix.getLength() + 1);
+}
+// -----------------------------------------------------------------------------
+static
+inline
+rtl::OUString stripSuffix(rtl::OUString const & _sString, rtl::OUString const & _sSuffix)
+{
+ OSL_ASSERT( matchSuffix(_sString,_sSuffix) );
+
+ sal_Int32 nSuffixStart = _sString.getLength() - _sSuffix.getLength();
+
+ return _sString.copy(0,nSuffixStart);
+}
+// -----------------------------------------------------------------------------
+static
+inline
+rtl::OUString stripTypeName(Logger const & logger, rtl::OUString const & _sString, rtl::OUString const & _sPrefix)
+{
+ if ( matchNsPrefix(_sString,_sPrefix))
+ return stripNsPrefix(_sString, _sPrefix);
+
+ badValueType(logger, "Missing expected namespace prefix on type name: ", _sString);
+
+ return _sString;
+}
+// -----------------------------------------------------------------------------
+static
+uno::Type xmlToScalarType(const rtl::OUString& _rType)
+{
+ uno::Type aRet;
+
+ if (_rType.equalsIgnoreAsciiCaseAscii(VALUETYPE_BOOLEAN))
+ aRet = ::getBooleanCppuType();
+
+ else if(_rType.equalsIgnoreAsciiCaseAscii(VALUETYPE_SHORT))
+ aRet = ::getCppuType(static_cast<sal_Int16 const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCaseAscii(VALUETYPE_INT))
+ aRet = ::getCppuType(static_cast<sal_Int32 const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCaseAscii(VALUETYPE_LONG))
+ aRet = ::getCppuType(static_cast<sal_Int64 const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCaseAscii(VALUETYPE_DOUBLE))
+ aRet = ::getCppuType(static_cast< double const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCaseAscii(VALUETYPE_STRING))
+ aRet = ::getCppuType(static_cast<rtl::OUString const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCaseAscii(VALUETYPE_BINARY))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int8> const*>(0));
+
+ else if(_rType.equalsIgnoreAsciiCaseAscii(VALUETYPE_ANY))
+ aRet = ::getCppuType(static_cast<uno::Any const*>(0));
+
+ else
+ OSL_ENSURE(false,"Cannot parse: Unknown value type");
+
+ return aRet;
+}
+// -----------------------------------------------------------------------------
+uno::Type xmlToListType(const rtl::OUString& _aElementType)
+{
+ uno::Type aRet;
+
+ if (_aElementType.equalsIgnoreAsciiCaseAscii(VALUETYPE_BOOLEAN))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Bool> const*>(0));
+
+ else if(_aElementType.equalsIgnoreAsciiCaseAscii(VALUETYPE_SHORT))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int16> const*>(0));
+
+ else if(_aElementType.equalsIgnoreAsciiCaseAscii(VALUETYPE_INT))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int32> const*>(0));
+
+ else if(_aElementType.equalsIgnoreAsciiCaseAscii(VALUETYPE_LONG))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int64> const*>(0));
+
+ else if(_aElementType.equalsIgnoreAsciiCaseAscii(VALUETYPE_DOUBLE))
+ aRet = ::getCppuType(static_cast<uno::Sequence<double> const*>(0));
+
+ else if(_aElementType.equalsIgnoreAsciiCaseAscii(VALUETYPE_STRING))
+ aRet = ::getCppuType(static_cast<uno::Sequence<rtl::OUString> const*>(0));
+
+ else if(_aElementType.equalsIgnoreAsciiCaseAscii(VALUETYPE_BINARY))
+ aRet = ::getCppuType(static_cast<uno::Sequence<uno::Sequence<sal_Int8> > const*>(0));
+
+ else
+ OSL_ENSURE(false,"Cannot parse: Unknown list value type");
+
+ return aRet;
+}
+// -----------------------------------------------------------------------------
+/// retrieve data type of a property,
+uno::Type ElementParser::getPropertyValueType(uno::Reference< sax::XAttributeList > const& xAttribs) const
+{
+ rtl::OUString sTypeName;
+ if (!this->maybeGetAttribute(xAttribs, ATTR_VALUETYPE, sTypeName))
+ return uno::Type(); // => VOID
+
+ uno::Type aType;
+
+ // valuetype names are either 'xs:<type>' or 'oor:<type>' or 'oor:<type>-list'
+ if (matchSuffix(sTypeName,VALUETYPE_LIST_SUFFIX))
+ {
+ rtl::OUString sBasicName = stripTypeName( mLogger, stripSuffix(sTypeName,VALUETYPE_LIST_SUFFIX), NS_PREFIX_OOR );
+
+ aType = xmlToListType(sBasicName);
+ }
+ else
+ {
+ rtl::OUString sPrefix = matchNsPrefix(sTypeName,NS_PREFIX_OOR) ? rtl::OUString( NS_PREFIX_OOR ) : rtl::OUString( NS_PREFIX_XS );
+
+ rtl::OUString sBasicName = stripTypeName( mLogger, sTypeName, sPrefix );
+
+ aType = xmlToScalarType(sBasicName);
+ }
+
+ if (aType == uno::Type())
+ badValueType(mLogger,"Unknown type name: ", sTypeName);
+
+ return aType;
+}
+// -----------------------------------------------------------------------------
+
+/// retrieve element type and associated module name of a set,
+bool ElementParser::getSetElementType(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString& aElementType, rtl::OUString& aElementTypeModule) const
+{
+ if (!this->maybeGetAttribute(xAttribs, ATTR_ITEMTYPE, aElementType))
+ return false;
+
+ maybeGetAttribute(xAttribs, ATTR_ITEMTYPECOMPONENT, aElementTypeModule);
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+/// retrieve instance type and associated module name of a set,
+bool ElementParser::getInstanceType(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString& aElementType, rtl::OUString& aElementTypeModule) const
+{
+ if (!this->maybeGetAttribute(xAttribs, ATTR_ITEMTYPE, aElementType))
+ return false;
+
+ maybeGetAttribute(xAttribs, ATTR_ITEMTYPECOMPONENT, aElementTypeModule);
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+/// retrieve the component for an import or uses element,
+bool ElementParser::getImportComponent(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString& _rsComponent) const
+{
+ return this->maybeGetAttribute(xAttribs, ATTR_COMPONENT, _rsComponent);
+}
+// -----------------------------------------------------------------------------
+
+/// reads attributes for values from the attribute list
+bool ElementParser::isNull(uno::Reference< sax::XAttributeList > const& _xAttribs) const
+{
+ bool bNull;
+ return maybeGetAttribute(_xAttribs, EXT_ATTR_NULL, bNull) && bNull;
+}
+// -----------------------------------------------------------------------------
+
+/// reads attributes for values from the attribute list
+rtl::OUString ElementParser::getSeparator(uno::Reference< sax::XAttributeList > const& _xAttribs) const
+{
+ rtl::OUString aSeparator;
+ maybeGetAttribute(_xAttribs, ATTR_VALUESEPARATOR, aSeparator);
+ return aSeparator;
+}
+// -----------------------------------------------------------------------------
+
+// low-level internal methods
+/// checks for presence of a boolean attribute and assigns its value if it exists (and is a bool)
+bool ElementParser::maybeGetAttribute(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString const& aAttributeName, bool& rAttributeValue) const
+{
+ rtl::OUString sAttribute;
+
+ if ( !this->maybeGetAttribute(xAttribs, aAttributeName, sAttribute) )
+ {
+ return false;
+ }
+
+ else if (sAttribute.equals(ATTR_VALUE_TRUE))
+ rAttributeValue = true; // will return true
+
+ else if (sAttribute.equals(ATTR_VALUE_FALSE))
+ rAttributeValue = false; // will return true
+
+ else
+ {
+ OSL_ENSURE(sAttribute.getLength() == 0, "Invalid text found in boolean attribute");
+ return false;
+ }
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+/// checks for presence of an attribute and assigns its value if it exists
+bool ElementParser::maybeGetAttribute(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString const& aAttributeName, rtl::OUString& rAttributeValue) const
+{
+ return xAttribs.is() && impl_maybeGetAttribute(xAttribs, aAttributeName, rAttributeValue);
+}
+
+// -----------------------------------------------------------------------------
+} // namespace
+} // namespace
+
diff --git a/configmgr/source/xml/elementparser.hxx b/configmgr/source/xml/elementparser.hxx
new file mode 100644
index 000000000000..78d5797bc6bf
--- /dev/null
+++ b/configmgr/source/xml/elementparser.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: elementparser.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_ELEMENTPARSER_HXX
+#define CONFIGMGR_XML_ELEMENTPARSER_HXX
+
+#include "elementinfo.hxx"
+#include "logger.hxx"
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace sax = ::com::sun::star::xml::sax;
+
+// -----------------------------------------------------------------------------
+ class ElementParser
+ {
+ Logger mLogger;
+ public:
+ class BadValueType
+ {
+ rtl::OUString mMessage;
+ public:
+ BadValueType(rtl::OUString const & aMessage) : mMessage(aMessage) {}
+
+ rtl::OUString message() const { return mMessage.getStr(); }
+ };
+ public:
+ explicit
+ ElementParser(Logger const & xLogger)
+ : mLogger(xLogger)
+ {}
+
+ Logger const & logger() const { return mLogger; }
+
+ /// reset the parser for a new document
+ void reset()
+ {}
+
+ /// retrieve the (almost) complete information for an element
+ ElementInfo parseElementInfo(rtl::OUString const& _sTag, uno::Reference< sax::XAttributeList > const& _xAttribs) const;
+
+ /// retrieve the node name for an element
+ ElementType::Enum getNodeType(rtl::OUString const& _sTag, uno::Reference< sax::XAttributeList > const& xAttribs) const;
+
+ /// retrieve the node name for an element
+ rtl::OUString getName(rtl::OUString const& _sTag, uno::Reference< sax::XAttributeList > const& xAttribs, ElementType::Enum eType = ElementType::unknown) const;
+
+ /// query whether the node has an operation
+ Operation::Enum getOperation(uno::Reference< sax::XAttributeList > const& xAttribs, ElementType::Enum _eType) const;
+
+ /// retrieve the language (if any) stored in the attribute list
+ bool getLanguage(uno::Reference< sax::XAttributeList > const& xAttribs, rtl::OUString & _rsLanguage) const;
+
+ /// reads attributes for nodes from the attribute list
+ sal_Int16 getNodeFlags(uno::Reference< sax::XAttributeList > const& xAttribs, ElementType::Enum _eType) const;
+
+ /// retrieve element type and associated module name of a set,
+ bool getSetElementType(uno::Reference< sax::XAttributeList > const& _xAttribs, rtl::OUString& _rsElementType, rtl::OUString& _rsElementTypeModule) const;
+
+ /// retrieve the instance type and associated module name of a instance,
+ bool getInstanceType(uno::Reference< sax::XAttributeList > const& _xAttribs, rtl::OUString& _rsElementType, rtl::OUString& _rsElementTypeModule) const;
+
+ /// retrieve the component for an import or uses element,
+ bool getImportComponent(uno::Reference< sax::XAttributeList > const& _xAttribs, rtl::OUString& _rsComponent) const;
+
+ /// retrieve element type and associated module name of a set,
+ uno::Type getPropertyValueType(uno::Reference< sax::XAttributeList > const& _xAttribs) const;
+ // throw( BadValueType )
+
+ /// reads a value attribute from the attribute list
+ bool isNull(uno::Reference< sax::XAttributeList > const& _xAttribs) const;
+
+ /// reads a value attribute from the attribute list
+ rtl::OUString getSeparator(uno::Reference< sax::XAttributeList > const& _xAttribs) const;
+
+ // low-level internal methods
+
+ /// checks for presence of a boolean attribute and assigns its value if it exists (and is a bool)
+ bool maybeGetAttribute(uno::Reference< sax::XAttributeList > const& _xAttribs, rtl::OUString const& _aAttributeName, bool& _rbAttributeValue) const;
+
+ /// checks for presence of an attribute and assigns its value if it exists
+ bool maybeGetAttribute(uno::Reference< sax::XAttributeList > const& _xAttribs, rtl::OUString const& _aAttributeName, rtl::OUString& _rsAttributeValue) const;
+ };
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
+#endif
+
diff --git a/configmgr/source/xml/layerparser.cxx b/configmgr/source/xml/layerparser.cxx
new file mode 100644
index 000000000000..db87f4ffe3e4
--- /dev/null
+++ b/configmgr/source/xml/layerparser.cxx
@@ -0,0 +1,371 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerparser.cxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "com/sun/star/configuration/backend/NodeAttribute.hpp"
+#include "layerparser.hxx"
+
+// -----------------------------------------------------------------------------
+#include "wrapexception.hxx"
+
+#define WRAP_PARSE_EXCEPTIONS() \
+ PASS_EXCEPTION(sax::SAXException) \
+ PASS_EXCEPTION(uno::RuntimeException) \
+ WRAP_CONFIGDATA_EXCEPTIONS( raiseParseException ) \
+ WRAP_OTHER_EXCEPTIONS( raiseParseException )
+
+#define WRAP_PARSE_EXCEPTIONS_MSG( msg ) \
+ PASS_EXCEPTION(sax::SAXException) \
+ PASS_EXCEPTION(uno::RuntimeException) \
+ WRAP_CONFIGDATA_EXCEPTIONS1( raiseParseException, msg ) \
+ WRAP_OTHER_EXCEPTIONS1( raiseParseException, msg )
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace sax = ::com::sun::star::xml::sax;
+// -----------------------------------------------------------------------------
+
+LayerParser::LayerParser(uno::Reference< uno::XComponentContext > const & _xContext, uno::Reference< backenduno::XLayerHandler > const & _xHandler)
+: BasicParser(_xContext)
+, m_xHandler(_xHandler)
+, m_bRemoved(false)
+, m_bNewProp(false)
+{
+ if (!m_xHandler.is())
+ {
+ rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM("Cannot create LayerParser: Unexpected NULL Handler"));
+ throw uno::RuntimeException(sMessage, NULL);
+ }
+}
+// -----------------------------------------------------------------------------
+
+LayerParser::~LayerParser()
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerParser::startDocument( )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ BasicParser::startDocument();
+
+ try
+ {
+ OSL_ENSURE(isEmptyNode(), "BasicParser does not mark new document as empty");
+
+ m_xHandler->startLayer();
+ m_bRemoved = false;
+ m_bNewProp = false;
+ }
+ WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Starting layer")
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerParser::endDocument( ) throw (sax::SAXException, uno::RuntimeException)
+{
+ if (isEmptyNode()) OSL_TRACE("Configuration Parser: XML layer document ended without any data");
+
+ BasicParser::endDocument();
+
+ try
+ {
+ m_xHandler->endLayer();
+ }
+ WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Ending layer")
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerParser::startElement( const rtl::OUString& aName, const uno::Reference< sax::XAttributeList >& xAttribs )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ if ( this->isSkipping() )
+ {
+ this->startSkipping( aName, xAttribs );
+ return;
+ }
+
+ ElementInfo aInfo = getDataParser().parseElementInfo(aName,xAttribs);
+
+ try
+ {
+ switch (aInfo.type)
+ {
+ case ElementType::group: case ElementType::set:
+ OSL_ENSURE( false, "Layer XML parser - Unexpected: found group/set element (should be 'node')\n");
+ // fall thru
+ case ElementType::layer:
+ case ElementType::node:
+ this->startNode(aInfo,xAttribs);
+ OSL_ASSERT( this->isInNode() && !this->isInProperty() );
+ break;
+
+ case ElementType::property:
+ this->startProperty(aInfo,xAttribs);
+ OSL_ASSERT( this->isInUnhandledProperty() );
+ break;
+
+ case ElementType::value:
+ this->startValueData(xAttribs);
+ OSL_ASSERT( this->isInValueData() );
+ break;
+
+ default: // skip unknown elements
+ OSL_ENSURE( aInfo.type >= ElementType::other, "Layer XML parser - Unexpected: found schema element in layer data\n");
+ OSL_ENSURE( aInfo.type < ElementType::other, "Layer XML parser - Warning: ignoring unknown element tag\n");
+ this->startSkipping( aName, xAttribs );
+ return;
+ }
+ }
+ WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Starting Element")
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL LayerParser::endElement( const rtl::OUString& aName )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ if ( this->wasSkipping(aName) )
+ return;
+
+ try
+ {
+ if ( this->isInValueData())
+ this->endValueData();
+
+ else if (this->isInProperty())
+ this->endProperty();
+
+ else if (this->isInNode())
+ this->endNode();
+
+ else {
+ this->raiseParseException("Layer parser: Invalid XML: endElement without matching startElement");
+ }
+ }
+ WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Ending Element")
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+void LayerParser::startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ this->checkNotRemoved();
+
+ BasicParser::startNode(aInfo,xAttribs);
+
+ switch (aInfo.op)
+ {
+ case Operation::none:
+ case Operation::modify:
+ m_xHandler->overrideNode(aInfo.name,aInfo.flags,false);
+ break;
+
+ case Operation::clear:
+ m_xHandler->overrideNode(aInfo.name,aInfo.flags,true);
+ break;
+
+ case Operation::replace:
+ case Operation::fuse:
+ {
+ backenduno::TemplateIdentifier aTemplate;
+ sal_Int16 flags = aInfo.flags;
+ if (aInfo.op == Operation::fuse) {
+ flags |=
+ com::sun::star::configuration::backend::NodeAttribute::FUSE;
+ }
+ if (getDataParser().getInstanceType(xAttribs,aTemplate.Name,aTemplate.Component))
+ m_xHandler->addOrReplaceNodeFromTemplate(aInfo.name,aTemplate,flags);
+ else
+ m_xHandler->addOrReplaceNode(aInfo.name,flags);
+ }
+ break;
+
+ case Operation::remove:
+ m_xHandler->dropNode(aInfo.name);
+ m_bRemoved = true;
+ break;
+
+ default: OSL_ASSERT(false);
+ case Operation::unknown:
+ this->raiseParseException("Layer parser: Invalid Data: unknown operation");
+ }
+}
+// -----------------------------------------------------------------------------
+
+void LayerParser::endNode()
+{
+ if (!this->isInRemoved())
+ m_xHandler->endNode();
+ else
+ m_bRemoved = false;
+
+ BasicParser::endNode();
+}
+// -----------------------------------------------------------------------------
+
+void LayerParser::startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ this->checkNotRemoved();
+
+ BasicParser::startProperty(aInfo,xAttribs);
+
+ switch (aInfo.op)
+ {
+ case Operation::none:
+ case Operation::modify:
+ m_xHandler->overrideProperty(aInfo.name,aInfo.flags,getActivePropertyType(),false);
+ OSL_ASSERT(!m_bNewProp);
+ break;
+
+ case Operation::clear:
+ m_xHandler->overrideProperty(aInfo.name,aInfo.flags,getActivePropertyType(),true);
+ OSL_ASSERT(!m_bNewProp);
+ break;
+
+ case Operation::replace:
+ // defer to later
+ m_bNewProp = true;
+ break;
+
+ case Operation::fuse:
+ this->raiseParseException("Layer parser: Invalid Data: operation 'fuse' is not permitted for properties");
+
+ case Operation::remove:
+ this->raiseParseException("Layer parser: Invalid Data: operation 'remove' is not permitted for properties");
+
+ default: OSL_ASSERT(false);
+ case Operation::unknown:
+ this->raiseParseException("Layer parser: Invalid Data: unknown operation");
+ }
+ OSL_POSTCOND(this->isInUnhandledProperty(),"Error: Property not reckognized as unhandled");
+}
+// -----------------------------------------------------------------------------
+
+void LayerParser::addOrReplaceCurrentProperty(const uno::Any& aValue)
+{
+ const ElementInfo& currentInfo = getActiveNodeInfo() ;
+
+ OSL_ASSERT(currentInfo.op == Operation::replace) ;
+
+ if (aValue.hasValue())
+ {
+ m_xHandler->addPropertyWithValue(currentInfo.name,
+ currentInfo.flags, aValue) ;
+ }
+ else
+ {
+ m_xHandler->addProperty(currentInfo.name, currentInfo.flags,
+ getActivePropertyType()) ;
+ }
+}
+// -----------------------------------------------------------------------------
+
+void LayerParser::endProperty()
+{
+ OSL_ASSERT(!this->isInRemoved());
+
+ if (m_bNewProp)
+ {
+ OSL_ASSERT(getActiveNodeInfo().op == Operation::replace);
+ if (this->isInUnhandledProperty())
+ {
+ // No value tag is treated as NULL
+ addOrReplaceCurrentProperty( uno::Any() ) ;
+ }
+ m_bNewProp = false;
+ }
+ else
+ {
+ OSL_ASSERT(getActiveNodeInfo().op != Operation::replace);
+ m_xHandler->endProperty();
+ }
+
+ BasicParser::endProperty();
+}
+// -----------------------------------------------------------------------------
+
+void LayerParser::startValueData(const uno::Reference< sax::XAttributeList >& xAttribs)
+{
+ this->checkNotRemoved();
+
+ BasicParser::startValueData(xAttribs);
+}
+// -----------------------------------------------------------------------------
+
+void LayerParser::endValueData()
+{
+ uno::Any aValue = this->getCurrentValue();
+
+ if (m_bNewProp)
+ {
+ if (this->isValueDataLocalized())
+ getLogger().warning("Language attribute ignored for value of added property.",
+ "endValueData()","configuration::xml::SchemaParser");
+
+ addOrReplaceCurrentProperty(aValue) ;
+ }
+ else if (this->isValueDataLocalized())
+ {
+ rtl::OUString aLocale = this->getValueDataLocale();
+
+ m_xHandler->setPropertyValueForLocale(aValue,aLocale);
+ }
+ else
+ {
+ m_xHandler->setPropertyValue(aValue);
+ }
+
+ BasicParser::endValueData();
+
+ OSL_POSTCOND(!this->isInUnhandledProperty(),"Error: Property not reckognized as unhandled");
+}
+// -----------------------------------------------------------------------------
+
+void LayerParser::checkNotRemoved()
+{
+ if (m_bRemoved)
+ raiseParseException("Layer parser: Invalid Data: Data inside removed node.");
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/xml/layerparser.hxx b/configmgr/source/xml/layerparser.hxx
new file mode 100644
index 000000000000..3916c3e869db
--- /dev/null
+++ b/configmgr/source/xml/layerparser.hxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerparser.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_LAYERPARSER_HXX
+#define CONFIGMGR_XML_LAYERPARSER_HXX
+
+#include "basicparser.hxx"
+
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ namespace sax = ::com::sun::star::xml::sax;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+
+// -----------------------------------------------------------------------------
+
+
+ class LayerParser : public BasicParser
+ {
+ public:
+ LayerParser(uno::Reference< uno::XComponentContext > const & _xContext, uno::Reference< backenduno::XLayerHandler > const & _xHandler);
+ virtual ~LayerParser();
+
+ // XDocumentHandler
+ public:
+ virtual void SAL_CALL
+ startDocument( )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endDocument( ) throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ startElement( const rtl::OUString& aName, const uno::Reference< sax::XAttributeList >& xAttribs )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endElement( const rtl::OUString& aName )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ private:
+ /// start an node
+ void startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// end a node
+ void endNode();
+
+ /// start a property
+ void startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// end a property
+ void endProperty();
+
+ /// start collecting data for a value - returns the locale of the value (property must have been started)
+ void startValueData(const uno::Reference< sax::XAttributeList >& xAttribs);
+ /// end collecting data for a value - returns the collected value
+ void endValueData();
+
+ /**
+ Forces the addition or replacement of a property.
+ As it is possible to "replace" an existing property,
+ even though this amounts to a modify, this method
+ first tries to add a new property and failing that,
+ to replace the value of an existing one.
+
+ @param aValue value to be set for the property
+ */
+ void addOrReplaceCurrentProperty(const uno::Any& aValue) ;
+
+ bool isInRemoved() const { return m_bRemoved; }
+ void checkNotRemoved();
+ private:
+ uno::Reference< backenduno::XLayerHandler > m_xHandler;
+ bool m_bRemoved;
+ bool m_bNewProp;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/xml/layerwriter.cxx b/configmgr/source/xml/layerwriter.cxx
new file mode 100644
index 000000000000..409be06660d0
--- /dev/null
+++ b/configmgr/source/xml/layerwriter.cxx
@@ -0,0 +1,544 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerwriter.cxx,v $
+ * $Revision: 1.15 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "layerwriter.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include "valueformatter.hxx"
+#include <com/sun/star/beans/IllegalTypeException.hpp>
+#include <com/sun/star/configuration/backend/BackendAccessException.hpp>
+#include <com/sun/star/configuration/backend/ConnectionLostException.hpp>
+#include <com/sun/star/configuration/backend/NodeAttribute.hpp>
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace xml
+ {
+ // -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace io = ::com::sun::star::io;
+ namespace sax = ::com::sun::star::xml::sax;
+ // -----------------------------------------------------------------------------
+
+ uno::Reference< uno::XInterface > SAL_CALL instantiateLayerWriter
+ ( uno::Reference< uno::XComponentContext > const& xContext )
+ {
+ return * new LayerWriter(xContext);
+ }
+ // -----------------------------------------------------------------------------
+
+ namespace
+ {
+ static inline
+ uno::Reference< script::XTypeConverter > createTCV(uno::Reference< lang::XMultiServiceFactory > const & _xSvcFactory)
+ {
+ OSL_ENSURE(_xSvcFactory.is(),"Cannot create Write Formatter without a ServiceManager");
+
+ static const rtl::OUString k_sTCVService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter"));
+
+ return uno::Reference< script::XTypeConverter >::query(_xSvcFactory->createInstance(k_sTCVService));
+ }
+ // -----------------------------------------------------------------------------
+ static
+ void translateSAXException( sax::SAXException & aSAXException,
+ backenduno::XLayerHandler * context)
+ {
+ rtl::OUString sMessage = aSAXException.Message;
+
+ uno::Any const & aWrappedException = aSAXException.WrappedException;
+ if (aWrappedException.hasValue())
+ {
+ if (aWrappedException.getValueTypeClass() != uno::TypeClass_EXCEPTION)
+ OSL_ENSURE(false, "ERROR: WrappedException is not an exception");
+
+ else if (sMessage.getLength() == 0)
+ sMessage = static_cast<uno::Exception const *>(aWrappedException.getValue())->Message;
+
+ // assume that a SAXException with WrappedException indicates a storage access error
+ throw backenduno::BackendAccessException(sMessage,context,aWrappedException);
+ }
+ else
+ {
+ // assume that a SAXException without WrappedException indicates non-well-formed data
+ throw backenduno::MalformedDataException(sMessage,context,uno::makeAny(aSAXException));
+ }
+ }
+ // -----------------------------------------------------------------------------
+ static inline uno::Type getIOExceptionType()
+ {
+ io::IOException const * const ioexception = 0;
+ return ::getCppuType(ioexception);
+ }
+ static inline uno::Type getNotConnectedExceptionType()
+ {
+ io::NotConnectedException const * const ncexception = 0;
+ return ::getCppuType(ncexception);
+ }
+ static
+ void translateIOException(uno::Any const & anIOException,
+ backenduno::XLayerHandler * context)
+ {
+ OSL_ASSERT(anIOException.isExtractableTo(getIOExceptionType()));
+ io::IOException const * pException = static_cast<io::IOException const *>(anIOException.getValue());
+ rtl::OUString sMessage = pException->Message;
+
+ if (anIOException.isExtractableTo(getNotConnectedExceptionType()))
+ {
+ throw backenduno::ConnectionLostException(sMessage,context,anIOException);
+ }
+ else
+ {
+ throw backenduno::BackendAccessException(sMessage,context,anIOException);
+ }
+ }
+ // -----------------------------------------------------------------------------
+ }
+ // -----------------------------------------------------------------------------
+
+ LayerWriter::LayerWriter(uno::Reference< uno::XComponentContext > const & _xContext)
+ : WriterService< ::com::sun::star::configuration::backend::XLayerHandler >(_xContext)
+ , m_xTCV( createTCV( WriterService< ::com::sun::star::configuration::backend::XLayerHandler >::getServiceFactory() ) )
+ , m_bInProperty(false)
+ , m_bStartedDocument(false)
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ LayerWriter::~LayerWriter()
+ {
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ m_aFormatter.reset();
+ m_bInProperty = false;
+ m_bStartedDocument = false;
+
+ checkInElement(false);
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ checkInElement(false);
+ try
+ {
+ if (!m_bStartedDocument)
+ {
+ uno::Reference< io::XOutputStream > aStream = this->getOutputStream( );
+ aStream->closeOutput();
+ }
+ else
+ {
+ getWriteHandler()->endDocument();
+ m_aFormatter.reset();
+ m_bStartedDocument = false;
+ }
+ }
+ catch (sax::SAXException & xe) { translateSAXException(xe,this); }
+ catch (io::NotConnectedException & ioe) { translateIOException(uno::makeAny(ioe),this); }
+ catch (io::BufferSizeExceededException & ioe) { translateIOException(uno::makeAny(ioe),this); }
+ catch (io::IOException & ioe) { translateIOException(uno::makeAny(ioe),this); }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ try
+ {
+ if (!m_bStartedDocument)
+ {
+ getWriteHandler()->startDocument();
+ m_bStartedDocument = true;
+ }
+ ElementInfo aInfo(aName, this->isInElement() ? ElementType::node : ElementType::layer);
+ aInfo.flags = aAttributes;
+ aInfo.op = bClear ? Operation::clear : Operation::modify;
+
+ m_aFormatter.prepareElement(aInfo);
+
+ this->startNode();
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::prepareAddOrReplaceElement(
+ rtl::OUString const & name, sal_Int16 attributes)
+ {
+ ElementInfo info(name, ElementType::node);
+ info.flags = attributes &
+ ~com::sun::star::configuration::backend::NodeAttribute::FUSE;
+ info.op =
+ (attributes &
+ com::sun::star::configuration::backend::NodeAttribute::FUSE)
+ == 0
+ ? Operation::replace : Operation::fuse;
+ m_aFormatter.prepareElement(info);
+ }
+
+ void SAL_CALL LayerWriter::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ checkInElement(true);
+
+ try
+ {
+ prepareAddOrReplaceElement(aName, aAttributes);
+
+ this->startNode();
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ checkInElement(true);
+
+ try
+ {
+ prepareAddOrReplaceElement(aName, aAttributes);
+ m_aFormatter.addInstanceType(aTemplate.Name,aTemplate.Component);
+
+ this->startNode();
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ checkInElement(true);
+ try
+ {
+ this->endElement();
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ checkInElement(true);
+
+ try
+ {
+ ElementInfo aInfo(aName, ElementType::node);
+ aInfo.flags = 0;
+ aInfo.op = Operation::remove;
+
+ m_aFormatter.prepareElement(aInfo);
+
+ this->startNode();
+ this->endElement();
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ checkInElement(true);
+
+ try
+ {
+ ElementInfo aInfo(aName, ElementType::property);
+ aInfo.flags = aAttributes;
+ aInfo.op = Operation::replace;
+
+ m_aFormatter.prepareElement(aInfo);
+
+ this->startProp(aType, true);
+ this->writeValue(uno::Any());
+ this->endElement();
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ checkInElement(true);
+
+ try
+ {
+ ElementInfo aInfo(aName, ElementType::property);
+ aInfo.flags = aAttributes;
+ aInfo.op = Operation::replace;
+
+ m_aFormatter.prepareElement(aInfo);
+
+ this->startProp(aValue.getValueType(), true);
+ this->writeValue(aValue);
+ this->endElement();
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ checkInElement(true);
+
+ try
+ {
+ ElementInfo aInfo(aName, ElementType::property);
+ aInfo.flags = aAttributes;
+ aInfo.op = bClear ? Operation::modify : Operation::modify;
+
+ m_aFormatter.prepareElement(aInfo);
+
+ this->startProp(aType, aType.getTypeClass() != uno::TypeClass_VOID);
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ try
+ {
+ checkInElement(true,true);
+ this->endElement();
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ try
+ {
+ checkInElement(true,true);
+ this->writeValue(aValue);
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void SAL_CALL LayerWriter::setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException)
+ {
+ try
+ {
+ checkInElement(true,true);
+ this->writeValue(aValue,aLocale);
+ }
+ catch (sax::SAXException & xe)
+ {
+ translateSAXException(xe,this);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::raiseMalformedDataException(sal_Char const * pMsg)
+ {
+ OSL_ASSERT(pMsg);
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+
+ throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::raiseIllegalTypeException(sal_Char const * pMsg)
+ {
+ OSL_ASSERT(pMsg);
+ rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
+
+ com::sun::star::beans::IllegalTypeException e( sMsg, *this );
+ throw backenduno::MalformedDataException( sMsg, *this, uno::makeAny(e) );
+ }
+ // -----------------------------------------------------------------------------
+
+ bool LayerWriter::isInElement() const
+ {
+ return !m_aTagStack.empty();
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::checkInElement(bool bInElement, bool bInProperty)
+ {
+ if (bInElement != this->isInElement())
+ {
+ sal_Char const * pMsg = bInElement ?
+ "LayerWriter: Illegal Data: Operation requires a started node" :
+ "LayerWriter: Illegal Data: There is a started node already" ;
+ raiseMalformedDataException(pMsg);
+ }
+
+ if (bInProperty != m_bInProperty)
+ {
+ sal_Char const * pMsg = bInProperty ?
+ "LayerWriter: Illegal Data: Operation requires a started property" :
+ "LayerWriter: Illegal Data: There is a started property already" ;
+ raiseMalformedDataException(pMsg);
+ }
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::startNode()
+ {
+ rtl::OUString sTag = m_aFormatter.getElementTag();
+ getWriteHandler()->startElement(sTag,m_aFormatter.getElementAttributes());
+ getWriteHandler()->ignorableWhitespace(rtl::OUString());
+ m_aTagStack.push(sTag);
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::startProp(uno::Type const & _aType, bool bNeedType)
+ {
+ if (bNeedType && _aType == uno::Type())
+ raiseIllegalTypeException("LayerWriter: Illegal Data: Cannot add VOID property");
+
+ m_aFormatter.addPropertyValueType(_aType);
+
+ startNode();
+
+ m_aPropertyType = _aType;
+ m_bInProperty = true;
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::endElement()
+ {
+ OSL_ASSERT(!m_aTagStack.empty()); // checks done elsewhere
+
+ getWriteHandler()->endElement(m_aTagStack.top());
+ getWriteHandler()->ignorableWhitespace(rtl::OUString());
+
+ m_aTagStack.pop();
+ m_bInProperty = false;
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::writeValue(uno::Any const & _aValue)
+ {
+ m_aFormatter.prepareSimpleElement( ElementType::value );
+ outputValue(_aValue);
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::writeValue(uno::Any const & _aValue, rtl::OUString const & _aLocale)
+ {
+ m_aFormatter.prepareSimpleElement( ElementType::value );
+ m_aFormatter.addLanguage(_aLocale);
+ outputValue(_aValue);
+ }
+ // -----------------------------------------------------------------------------
+
+ void LayerWriter::outputValue(uno::Any const & _aValue)
+ {
+ ValueFormatter aValueFormatter(_aValue);
+
+ aValueFormatter.addValueAttributes(m_aFormatter);
+
+ rtl::OUString sTag = m_aFormatter.getElementTag();
+ rtl::OUString sContent = aValueFormatter.getContent( this->m_xTCV );
+
+ uno::Reference< sax::XDocumentHandler > xOut = getWriteHandler();
+ xOut->startElement(sTag, m_aFormatter.getElementAttributes());
+
+ if (sContent.getLength()) xOut->characters(sContent);
+
+ xOut->endElement(sTag);
+ xOut->ignorableWhitespace(rtl::OUString());
+ }
+ // -----------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------
+ // -----------------------------------------------------------------------------
+ } // namespace
+
+ // -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/xml/layerwriter.hxx b/configmgr/source/xml/layerwriter.hxx
new file mode 100644
index 000000000000..3917d3e60af1
--- /dev/null
+++ b/configmgr/source/xml/layerwriter.hxx
@@ -0,0 +1,169 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: layerwriter.hxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+************************************************************************/
+
+#ifndef CONFIGMGR_XML_LAYERWRITER_HXX
+#define CONFIGMGR_XML_LAYERWRITER_HXX
+
+#include "writersvc.hxx"
+#include "elementformatter.hxx"
+#include "stack.hxx"
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+
+namespace com { namespace sun { namespace star { namespace script {
+ class XTypeConverter;
+} } } }
+
+namespace configmgr
+{
+ // -----------------------------------------------------------------------------
+ namespace xml
+ {
+ // -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ namespace sax = ::com::sun::star::xml::sax;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+
+ // -----------------------------------------------------------------------------
+
+
+ class LayerWriter : public WriterService< ::com::sun::star::configuration::backend::XLayerHandler >
+ {
+ public:
+ explicit
+ LayerWriter(uno::Reference< uno::XComponentContext > const & _xContext);
+ virtual ~LayerWriter();
+
+ // XLayerHandler
+ public:
+ virtual void SAL_CALL
+ startLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endLayer( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endNode( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ dropNode( const rtl::OUString& aName )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endProperty( )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValue( const uno::Any& aValue )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ virtual void SAL_CALL
+ setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString& aLocale )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ uno::RuntimeException);
+
+ private:
+ bool isInElement() const;
+ void checkInElement(bool bInElement, bool bInProperty = false);
+
+ void startNode();
+ void startProp(uno::Type const & _aType, bool bNeedType);
+
+ void endElement();
+
+ void writeValue(uno::Any const & _aValue);
+ void writeValue(uno::Any const & _aValue, rtl::OUString const & _aLocale);
+
+ void outputValue(uno::Any const & _aValue);
+
+ void raiseMalformedDataException(sal_Char const * pMsg);
+ void raiseIllegalTypeException(sal_Char const * pMsg);
+
+ void prepareAddOrReplaceElement(
+ rtl::OUString const & name, sal_Int16 attributes);
+
+ private:
+ uno::Reference< com::sun::star::script::XTypeConverter > m_xTCV;
+ Stack< rtl::OUString > m_aTagStack;
+ ElementFormatter m_aFormatter;
+ uno::Type m_aPropertyType;
+ bool m_bInProperty;
+ bool m_bStartedDocument;
+ };
+ // -----------------------------------------------------------------------------
+ } // namespace xml
+ // -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/xml/makefile.mk b/configmgr/source/xml/makefile.mk
new file mode 100644
index 000000000000..61d3ac65572f
--- /dev/null
+++ b/configmgr/source/xml/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.27 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJINC=$(PRJ)$/source
+PRJNAME=configmgr
+TARGET=xml
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+
+.IF "$(OS)"=="SOLARIS" && "$(COM)"!="GCC"
+CFLAGSCXX+=-instances=static
+.ENDIF
+
+# --- Files ---
+
+
+SLOFILES=\
+ $(SLO)$/matchlocale.obj \
+ $(SLO)$/typeconverter.obj \
+ $(SLO)$/simpletypehelper.obj \
+ $(SLO)$/valueconverter.obj \
+ $(SLO)$/elementparser.obj \
+ $(SLO)$/elementformatter.obj \
+ $(SLO)$/basicparser.obj \
+ $(SLO)$/layerparser.obj \
+ $(SLO)$/schemaparser.obj \
+ $(SLO)$/parsersvc.obj \
+ $(SLO)$/writersvc.obj \
+ $(SLO)$/layerwriter.obj \
+ $(SLO)$/valueformatter.obj \
+ $(SLO)$/xmlstrings.obj \
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/source/xml/matchlocale.cxx b/configmgr/source/xml/matchlocale.cxx
new file mode 100644
index 000000000000..b0cf48092bb6
--- /dev/null
+++ b/configmgr/source/xml/matchlocale.cxx
@@ -0,0 +1,387 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: matchlocale.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "matchlocale.hxx"
+
+#include <rtl/ustrbuf.hxx>
+
+#include <algorithm>
+#include <iterator>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace localehelper
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+#define ARRAYSIZE( arr ) (sizeof(arr) / sizeof 0[arr] )
+// -----------------------------------------------------------------------------
+ struct StaticLocale
+ {
+ char const * aLanguage;
+ char const * aCountry;
+ };
+
+ char const * const c_sAnyLanguage = "*"; // exported !
+ char const * const c_sDefLanguage = "x-default"; // exported !
+
+ char const * const c_sNoCountry = "";
+
+ char const * const c_sLanguageEnglish = "en";
+ char const * const c_sCountryUS = "US";
+
+ StaticLocale const c_aFallbackLocales[] =
+ {
+ { c_sLanguageEnglish, c_sCountryUS }, // english [cannot make 'en' better than 'en-US' :-(]
+ { c_sAnyLanguage, c_sNoCountry } // just take the first you find
+ };
+ std::vector< com::sun::star::lang::Locale >::size_type const c_nFallbackLocales = ARRAYSIZE(c_aFallbackLocales);
+
+// -----------------------------------------------------------------------------
+ bool isAnyLanguage(rtl::OUString const & _sLanguage)
+ {
+ return !!_sLanguage.equalsAscii(c_sAnyLanguage);
+ }
+
+// -----------------------------------------------------------------------------
+ bool isDefaultLanguage(rtl::OUString const & _sLanguage)
+ {
+ return !!_sLanguage.equalsAscii(c_sDefLanguage);
+ }
+
+// -----------------------------------------------------------------------------
+ rtl::OUString getAnyLanguage()
+ {
+ return rtl::OUString::createFromAscii( c_sAnyLanguage );
+ }
+
+// -----------------------------------------------------------------------------
+ rtl::OUString getDefaultLanguage()
+ {
+ return rtl::OUString::createFromAscii( c_sDefLanguage );
+ }
+
+// -----------------------------------------------------------------------------
+ com::sun::star::lang::Locale getAnyLocale()
+ {
+ return com::sun::star::lang::Locale( getAnyLanguage(), rtl::OUString(), rtl::OUString() );
+ }
+
+// -----------------------------------------------------------------------------
+ com::sun::star::lang::Locale getDefaultLocale()
+ {
+ return com::sun::star::lang::Locale( getDefaultLanguage(), rtl::OUString(), rtl::OUString() );
+ }
+
+// -----------------------------------------------------------------------------
+ static inline sal_Int32 countrySeparatorPos(rtl::OUString const& aLocaleName_)
+ {
+ sal_Int32 pos = aLocaleName_.indexOf('-');
+ if (pos == 1) // allow for x-LL or i-LL
+ pos = aLocaleName_.indexOf('-',pos+1);
+
+ if (pos < 0)
+ pos = aLocaleName_.indexOf('_');
+
+ return pos;
+ }
+ // -------------------------------------------------------------------------
+ static inline sal_Int32 countryLength(rtl::OUString const& aLocaleName_, sal_Int32 nCountryPos)
+ {
+ sal_Int32 pos1 = aLocaleName_.indexOf('.',nCountryPos);
+ sal_Int32 pos2 = aLocaleName_.indexOf('_',nCountryPos);
+
+ if (pos1 < 0) pos1 = aLocaleName_.getLength();
+
+ if (pos2 < 0 || pos1 < pos2)
+ return pos1 - nCountryPos;
+
+ else
+ return pos2 - nCountryPos;
+ }
+ // -------------------------------------------------------------------------
+ static inline void splitLocaleString(rtl::OUString const& aLocaleName_, rtl::OUString& rLanguage_, rtl::OUString& rCountry_)
+ {
+ sal_Int32 nCountryPos = countrySeparatorPos(aLocaleName_);
+ if (nCountryPos >= 0)
+ {
+ rLanguage_ = aLocaleName_.copy(0,nCountryPos).toAsciiLowerCase();
+
+ ++nCountryPos; // advance past separator
+ sal_Int32 nCountryLength = countryLength(aLocaleName_, nCountryPos);
+
+ rCountry_ = aLocaleName_.copy(nCountryPos,nCountryLength).toAsciiUpperCase();
+ }
+ else
+ {
+ rLanguage_ = aLocaleName_.toAsciiLowerCase();
+ rCountry_ = rtl::OUString();
+ }
+ }
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// conversion helpers
+com::sun::star::lang::Locale makeLocale(rtl::OUString const& sLocaleName_)
+{
+ com::sun::star::lang::Locale aResult;
+ splitLocaleString(sLocaleName_, aResult.Language, aResult.Country);
+ return aResult;
+}
+rtl::OUString makeIsoLocale(com::sun::star::lang::Locale const& aUnoLocale_)
+{
+ rtl::OUStringBuffer aResult(aUnoLocale_.Language.toAsciiLowerCase());
+ if (aUnoLocale_.Country.getLength())
+ {
+ aResult.append( sal_Unicode('-') ).append(aUnoLocale_.Country.toAsciiUpperCase());
+ }
+ return aResult.makeStringAndClear();
+}
+static
+com::sun::star::lang::Locale makeLocale(StaticLocale const& aConstLocale_)
+{
+ com::sun::star::lang::Locale aResult;
+ aResult.Language = rtl::OUString::createFromAscii(aConstLocale_.aLanguage);
+ aResult.Country = rtl::OUString::createFromAscii(aConstLocale_.aCountry);
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+template <class T>
+inline
+void addLocaleSeq_impl(T const* first, T const* last, std::vector< com::sun::star::lang::Locale >& rSeq)
+{
+ com::sun::star::lang::Locale (* const xlate)(T const&) = &makeLocale;
+
+ std::transform(first, last, std::back_inserter(rSeq), xlate);
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+template <class T>
+inline
+std::vector< com::sun::star::lang::Locale > makeLocaleSeq_impl(uno::Sequence< T > const& aLocales_)
+{
+ sal_Int32 const nLocaleCount = aLocales_.getLength();
+
+ T const* pLocaleBegin = aLocales_.getConstArray();
+
+ std::vector< com::sun::star::lang::Locale > aResult;
+ aResult.reserve( nLocaleCount + c_nFallbackLocales ); // make room for fallback stuff as well
+
+ addLocaleSeq_impl(pLocaleBegin, pLocaleBegin + nLocaleCount, aResult);
+
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+
+void addFallbackLocales(std::vector< com::sun::star::lang::Locale >& aTargetList_)
+{
+ addLocaleSeq_impl(c_aFallbackLocales, c_aFallbackLocales + c_nFallbackLocales, aTargetList_);
+}
+// -----------------------------------------------------------------------------
+
+std::vector< com::sun::star::lang::Locale > makeLocaleSequence(uno::Sequence<rtl::OUString> const& sLocaleNames_)
+{
+ return makeLocaleSeq_impl(sLocaleNames_);
+}
+// -----------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString> makeIsoSequence(std::vector< com::sun::star::lang::Locale > const& aLocales_)
+{
+ std::vector< com::sun::star::lang::Locale >::size_type const nLocaleCount = aLocales_.size();
+ sal_Int32 const nSeqSize = sal_Int32(nLocaleCount);
+ OSL_ASSERT( nSeqSize >= 0 && sal_uInt32(nSeqSize) == nLocaleCount );
+
+ uno::Sequence<rtl::OUString> aResult(nSeqSize);
+ std::transform(aLocales_.begin(), aLocales_.end(), aResult.getArray(), &makeIsoLocale);
+
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+bool designatesAllLocales(com::sun::star::lang::Locale const& aLocale_)
+{
+ return aLocale_.Language.equalsAscii(c_sAnyLanguage);
+}
+bool designatesAllLocales(std::vector< com::sun::star::lang::Locale > const& aLocales_)
+{
+ return aLocales_.size() <= 1 &&
+ (aLocales_.size() == 0 || designatesAllLocales(aLocales_));
+}
+// -----------------------------------------------------------------------------
+
+MatchQuality match(com::sun::star::lang::Locale const& aLocale_, com::sun::star::lang::Locale const& aTarget_)
+{
+ // check language
+ if (!aLocale_.Language.equals(aTarget_.Language))
+ {
+ // can we accept any language
+ if (aTarget_.Language.equalsAscii(c_sAnyLanguage))
+ return MATCH_LANGUAGE;
+
+ return MISMATCH;
+ }
+
+ // check for exact match
+ else if (aLocale_.Country.equals(aTarget_.Country))
+ return MATCH_LOCALE;
+
+ // check for plain language
+ else if (aLocale_.Country.getLength() == 0)
+ return MATCH_LANGUAGE_PLAIN;
+
+ // so we are left with the wrong country
+ else
+ return MATCH_LANGUAGE;
+}
+
+// -----------------------------------------------------------------------------
+
+/// check the given position and quality, if they are an improvement
+bool MatchResult::improve(std::vector< com::sun::star::lang::Locale >::size_type nPos_, MatchQuality eQuality_)
+{
+ // is this a match at all ?
+ if (eQuality_ == MISMATCH)
+ return false;
+
+ // is the position worse ?
+ if (nPos_ > m_nPos )
+ return false;
+
+ // is this just a non-positive quality change ?
+ if (nPos_ == m_nPos && eQuality_ <= m_eQuality)
+ return false;
+
+ // Improvement found
+ m_nPos = nPos_;
+ m_eQuality = eQuality_;
+
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+bool isMatch(com::sun::star::lang::Locale const& aLocale_, std::vector< com::sun::star::lang::Locale > const& aTarget_, MatchQuality eRequiredQuality_)
+{
+ std::vector< com::sun::star::lang::Locale >::size_type const nEnd = aTarget_.size();
+
+ for (std::vector< com::sun::star::lang::Locale >::size_type nPos = 0; nPos < nEnd; ++nPos)
+ {
+ MatchQuality eQuality = match(aLocale_, aTarget_[nPos]);
+ if (eQuality >= eRequiredQuality_)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+// -----------------------------------------------------------------------------
+
+static
+inline
+std::vector< com::sun::star::lang::Locale >::size_type getSearchLimitPosition(MatchResult const& aPrevMatch_,std::vector< com::sun::star::lang::Locale > const& aTarget_)
+{
+ std::vector< com::sun::star::lang::Locale >::size_type nSize = aTarget_.size();
+
+ if (aPrevMatch_.isMatch())
+ {
+ std::vector< com::sun::star::lang::Locale >::size_type nMatchPos = aPrevMatch_.position();
+
+ OSL_ENSURE(nMatchPos < nSize,"localehelper::getSearchLimitPosition: ERROR - previous position is out-of-bounds");
+
+ if (nMatchPos < nSize)
+ {
+ return nMatchPos + 1;
+ }
+ }
+ return nSize;
+}
+// -----------------------------------------------------------------------------
+
+bool improveMatch(MatchResult& rMatch_, com::sun::star::lang::Locale const& aLocale_, std::vector< com::sun::star::lang::Locale > const& aTarget_)
+{
+ std::vector< com::sun::star::lang::Locale >::size_type const nEnd = getSearchLimitPosition(rMatch_,aTarget_);
+
+ for (std::vector< com::sun::star::lang::Locale >::size_type nPos = 0; nPos < nEnd; ++nPos)
+ {
+ if (rMatch_.improve(nPos, match(aLocale_, aTarget_[nPos])))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+// -----------------------------------------------------------------------------
+
+
+// -----------------------------------------------------------------------------
+// class FindBestLocale
+// -----------------------------------------------------------------------------
+
+inline
+void FindBestLocale::implSetTarget(std::vector< com::sun::star::lang::Locale > const& aTarget_)
+{
+ m_aTarget = aTarget_;
+ addFallbackLocales(m_aTarget);
+}
+// -----------------------------------------------------------------------------
+
+FindBestLocale::FindBestLocale(com::sun::star::lang::Locale const& aTarget_)
+{
+ std::vector< com::sun::star::lang::Locale > aSeq(1,aTarget_);
+ implSetTarget( aSeq );
+}
+// -----------------------------------------------------------------------------
+
+bool FindBestLocale::accept(com::sun::star::lang::Locale const& aLocale_)
+{
+ return improveMatch(m_aResult, aLocale_, m_aTarget);
+}
+// -----------------------------------------------------------------------------
+
+void FindBestLocale::reset(bool bNeedLocale_)
+{
+ if (bNeedLocale_)
+ m_aResult.reset();
+
+ else // mark as best match already (no improvement possible)
+ m_aResult = m_aResult.best();
+}
+// -----------------------------------------------------------------------------
+
+ } // namespace locale helper
+// -----------------------------------------------------------------------------
+
+} // namespace
+
+
diff --git a/configmgr/source/xml/parsersvc.cxx b/configmgr/source/xml/parsersvc.cxx
new file mode 100644
index 000000000000..8f835b1725e2
--- /dev/null
+++ b/configmgr/source/xml/parsersvc.cxx
@@ -0,0 +1,385 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: parsersvc.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "parsersvc.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include "schemaparser.hxx"
+#include "layerparser.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <com/sun/star/configuration/backend/XSchema.hpp>
+#include <com/sun/star/configuration/backend/XLayer.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/configuration/backend/MalformedDataException.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace io = ::com::sun::star::io;
+ namespace sax = ::com::sun::star::xml::sax;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+struct ParserServiceTraits;
+// -----------------------------------------------------------------------------
+static inline void clear(rtl::OUString & _rs) { _rs = rtl::OUString(); }
+
+// -----------------------------------------------------------------------------
+template <class BackendInterface>
+ParserService<BackendInterface>::ParserService(uno::Reference< uno::XComponentContext > const & _xContext)
+: m_xContext(_xContext)
+, m_aInputSource()
+{
+ if (!m_xContext.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration Parser: NULL Context"));
+ throw uno::RuntimeException(sMessage,NULL);
+ }
+}
+// -----------------------------------------------------------------------------
+
+// XInitialization
+template <class BackendInterface>
+void SAL_CALL
+ ParserService<BackendInterface>::initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException)
+{
+ switch(aArguments.getLength())
+ {
+ case 0:
+ break;
+
+ case 1:
+ if (aArguments[0] >>= m_aInputSource)
+ break;
+
+ if (aArguments[0] >>= m_aInputSource.aInputStream)
+ break;
+
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Cannot use argument to initialize a Configuration Parser"
+ "- InputSource or XInputStream expected"));
+ throw lang::IllegalArgumentException(sMessage,*this,1);
+ }
+ default:
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Too many arguments to initialize a Configuration Parser"));
+ throw lang::IllegalArgumentException(sMessage,*this,0);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+inline
+ServiceInfoHelper ParserService<BackendInterface>::getServiceInfo()
+{
+ return ParserServiceTraits<BackendInterface>::getServiceInfo();
+}
+// -----------------------------------------------------------------------------
+
+// XServiceInfo
+template <class BackendInterface>
+::rtl::OUString SAL_CALL
+ ParserService<BackendInterface>::getImplementationName( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getImplementationName();
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+sal_Bool SAL_CALL
+ ParserService<BackendInterface>::supportsService( const ::rtl::OUString& ServiceName )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().supportsService( ServiceName );
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ ParserService<BackendInterface>::getSupportedServiceNames( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getSupportedServiceNames( );
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+void SAL_CALL
+ ParserService<BackendInterface>::setInputStream( const uno::Reference< io::XInputStream >& aStream )
+ throw (uno::RuntimeException)
+{
+ clear( m_aInputSource.sEncoding );
+ clear( m_aInputSource.sSystemId );
+ // clear( m_aInputSource.sPublicId );
+ m_aInputSource.aInputStream = aStream;
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+uno::Reference< io::XInputStream > SAL_CALL
+ ParserService<BackendInterface>::getInputStream( )
+ throw (uno::RuntimeException)
+{
+ return m_aInputSource.aInputStream;
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+void ParserService<BackendInterface>::parse(uno::Reference< sax::XDocumentHandler > const & _xHandler)
+// throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ OSL_PRECOND( _xHandler.is(), "ParserService: No SAX handler to parse to");
+
+ rtl::OUString const k_sSaxParserService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser"));
+
+ uno::Reference< lang::XMultiComponentFactory > xServiceFactory = m_xContext->getServiceManager();
+
+ uno::Reference< sax::XParser > xParser = uno::Reference< sax::XParser >::query( xServiceFactory->createInstanceWithContext(k_sSaxParserService,m_xContext) );
+
+ if (!xParser.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration Parser: Cannot create SAX Parser"));
+ throw uno::RuntimeException(sMessage,*this);
+ }
+
+ try
+ {
+ xParser->setDocumentHandler(_xHandler);
+
+ sax::InputSource aInputSourceCopy = m_aInputSource;
+ //Set the sax input stream to null, an input stream can only be parsed once
+ m_aInputSource.aInputStream = NULL;
+ xParser->parseStream( aInputSourceCopy );
+ }
+ catch (sax::SAXException & e)
+ {
+ uno::Any aWrapped = e.WrappedException.hasValue() ? e.WrappedException : uno::makeAny( e );
+ rtl::OUString sSAXMessage = e.Message;
+
+ // Expatwrap SAX service doubly wraps its errors ??
+ sax::SAXException eInner;
+ if (aWrapped >>= eInner)
+ {
+ if (eInner.WrappedException.hasValue()) aWrapped = eInner.WrappedException;
+
+ rtl::OUStringBuffer sMsgBuf(eInner.Message);
+ sMsgBuf.appendAscii("- {Parser Error: ").append(sSAXMessage).appendAscii(" }.");
+ sSAXMessage = sMsgBuf.makeStringAndClear();
+ }
+
+ static backenduno::MalformedDataException const * const forDataError = 0;
+ static lang::WrappedTargetException const * const forWrappedError = 0;
+ if (aWrapped.isExtractableTo(getCppuType(forDataError)) ||
+ aWrapped.isExtractableTo(getCppuType(forWrappedError)))
+ {
+ cppu::throwException(aWrapped);
+
+ OSL_ASSERT(!"not reached");
+ }
+
+ rtl::OUStringBuffer sMessageBuf;
+ sMessageBuf.appendAscii("Configuration Parser: a ").append( aWrapped.getValueTypeName() );
+ sMessageBuf.appendAscii(" occurred while parsing: ");
+ sMessageBuf.append(sSAXMessage);
+
+ throw lang::WrappedTargetException(sMessageBuf.makeStringAndClear(),*this,aWrapped);
+ }
+}
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+sal_Char const * const aSchemaParserServices[] =
+{
+ "com.sun.star.configuration.backend.xml.SchemaParser",
+ 0
+};
+const ServiceImplementationInfo aSchemaParserSI =
+{
+ "com.sun.star.comp.configuration.backend.xml.SchemaParser",
+ aSchemaParserServices,
+ 0
+};
+// -----------------------------------------------------------------------------
+sal_Char const * const aLayerParserServices[] =
+{
+ "com.sun.star.configuration.backend.xml.LayerParser",
+ 0
+};
+const ServiceImplementationInfo aLayerParserSI =
+{
+ "com.sun.star.comp.configuration.backend.xml.LayerParser",
+ aLayerParserServices,
+ 0
+};
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+template <>
+struct ParserServiceTraits< backenduno::XSchema >
+{
+ static ServiceImplementationInfo const * getServiceInfo()
+ { return & aSchemaParserSI; }
+};
+// -----------------------------------------------------------------------------
+template <>
+struct ParserServiceTraits< backenduno::XLayer >
+{
+ static ServiceImplementationInfo const * getServiceInfo()
+ { return & aLayerParserSI; }
+};
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+class SchemaParserService : public ParserService< backenduno::XSchema >
+{
+public:
+ SchemaParserService(uno::Reference< uno::XComponentContext > const & _xContext)
+ : ParserService< backenduno::XSchema >(_xContext)
+ {
+ }
+
+ virtual void SAL_CALL readSchema( uno::Reference< backenduno::XSchemaHandler > const & aHandler )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ lang::NullPointerException, uno::RuntimeException);
+
+ virtual void SAL_CALL readComponent( uno::Reference< backenduno::XSchemaHandler > const & aHandler )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ lang::NullPointerException, uno::RuntimeException);
+
+ virtual void SAL_CALL readTemplates( uno::Reference< backenduno::XSchemaHandler > const & aHandler )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ lang::NullPointerException, uno::RuntimeException);
+};
+// -----------------------------------------------------------------------------
+
+class LayerParserService : public ParserService< backenduno::XLayer >
+{
+public:
+ LayerParserService(uno::Reference< uno::XComponentContext > const & _xContext)
+ : ParserService< backenduno::XLayer >(_xContext)
+ {
+ }
+
+ virtual void SAL_CALL readData( uno::Reference< backenduno::XLayerHandler > const & aHandler )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ lang::NullPointerException, uno::RuntimeException);
+};
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL instantiateSchemaParser( uno::Reference< uno::XComponentContext > const& xContext )
+{
+ return * new SchemaParserService(xContext);
+}
+uno::Reference< uno::XInterface > SAL_CALL instantiateLayerParser( uno::Reference< uno::XComponentContext > const& xContext )
+{
+ return * new LayerParserService(xContext);
+}
+// -----------------------------------------------------------------------------
+const ServiceRegistrationInfo* getSchemaParserServiceInfo()
+{ return getRegistrationInfo(& aSchemaParserSI); }
+const ServiceRegistrationInfo* getLayerParserServiceInfo()
+{ return getRegistrationInfo(& aLayerParserSI); }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+static rtl::OUString nullHandlerMessage(char const * where)
+{
+ OSL_ASSERT(where);
+ rtl::OUString msg = rtl::OUString::createFromAscii(where);
+ return msg.concat(rtl::OUString::createFromAscii(": Error - NULL handler passed."));
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL SchemaParserService::readSchema( uno::Reference< backenduno::XSchemaHandler > const & aHandler )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ lang::NullPointerException, uno::RuntimeException)
+{
+ if (!aHandler.is())
+ throw lang::NullPointerException(nullHandlerMessage("SchemaParserService::readSchema"),*this);
+
+ uno::Reference< sax::XDocumentHandler > xHandler = new SchemaParser(this->getContext(),aHandler, SchemaParser::selectAll);
+ this->parse( xHandler );
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL SchemaParserService::readComponent( uno::Reference< backenduno::XSchemaHandler > const & aHandler )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ lang::NullPointerException, uno::RuntimeException)
+{
+ if (!aHandler.is())
+ throw lang::NullPointerException(nullHandlerMessage("SchemaParserService::readComponent"),*this);
+
+ uno::Reference< sax::XDocumentHandler > xHandler = new SchemaParser(this->getContext(),aHandler, SchemaParser::selectComponent);
+ this->parse( xHandler );
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL SchemaParserService::readTemplates( uno::Reference< backenduno::XSchemaHandler > const & aHandler )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ lang::NullPointerException, uno::RuntimeException)
+{
+ if (!aHandler.is())
+ throw lang::NullPointerException(nullHandlerMessage("SchemaParserService::readTemplates"),*this);
+
+ uno::Reference< sax::XDocumentHandler > xHandler = new SchemaParser(this->getContext(),aHandler, SchemaParser::selectTemplates);
+ this->parse( xHandler );
+}
+// -----------------------------------------------------------------------------
+void SAL_CALL LayerParserService::readData( uno::Reference< backenduno::XLayerHandler > const & aHandler )
+ throw (backenduno::MalformedDataException, lang::WrappedTargetException,
+ lang::NullPointerException, uno::RuntimeException)
+{
+ if (!aHandler.is())
+ throw lang::NullPointerException(nullHandlerMessage("LayerParserService::readData"),*this);
+
+ uno::Reference< sax::XDocumentHandler > xHandler = new LayerParser(this->getContext(),aHandler);
+ this->parse( xHandler );
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/xml/parsersvc.hxx b/configmgr/source/xml/parsersvc.hxx
new file mode 100644
index 000000000000..cd0cf30b329e
--- /dev/null
+++ b/configmgr/source/xml/parsersvc.hxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: parsersvc.hxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_PARSERSVC_HXX
+#define CONFIGMGR_XML_PARSERSVC_HXX
+
+#include "serviceinfohelper.hxx"
+#include <cppuhelper/implbase4.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace io = ::com::sun::star::io;
+ namespace sax = ::com::sun::star::xml::sax;
+// -----------------------------------------------------------------------------
+
+ template <class BackendInterface>
+ class ParserService : public ::cppu::WeakImplHelper4<
+ lang::XInitialization,
+ lang::XServiceInfo,
+ io::XActiveDataSink,
+ BackendInterface
+ >
+ {
+ public:
+ explicit
+ ParserService(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& ServiceName )
+ throw (uno::RuntimeException);
+
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException);
+
+ // XActiveDataSink
+ virtual void SAL_CALL
+ setInputStream( const uno::Reference< io::XInputStream >& aStream )
+ throw (uno::RuntimeException);
+
+ virtual uno::Reference< io::XInputStream > SAL_CALL
+ getInputStream( )
+ throw (uno::RuntimeException);
+
+ protected:
+ uno::Reference< uno::XComponentContext > getContext() const
+ { return m_xContext; }
+
+ void parse(uno::Reference< sax::XDocumentHandler > const & _xHandler);
+ // throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException);
+
+ private:
+ uno::Reference< uno::XComponentContext > m_xContext;
+ sax::InputSource m_aInputSource;
+
+ static ServiceInfoHelper getServiceInfo();
+ };
+
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/xml/schemaparser.cxx b/configmgr/source/xml/schemaparser.cxx
new file mode 100644
index 000000000000..1fd1cea90bb7
--- /dev/null
+++ b/configmgr/source/xml/schemaparser.cxx
@@ -0,0 +1,409 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: schemaparser.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "schemaparser.hxx"
+
+// -----------------------------------------------------------------------------
+#include "wrapexception.hxx"
+
+#define WRAP_PARSE_EXCEPTIONS() \
+ PASS_EXCEPTION(sax::SAXException) \
+ PASS_EXCEPTION(uno::RuntimeException) \
+ WRAP_CONFIGDATA_EXCEPTIONS( raiseParseException ) \
+ WRAP_OTHER_EXCEPTIONS( raiseParseException )
+
+#define WRAP_PARSE_EXCEPTIONS_MSG( msg ) \
+ PASS_EXCEPTION(sax::SAXException) \
+ PASS_EXCEPTION(uno::RuntimeException) \
+ WRAP_CONFIGDATA_EXCEPTIONS1( raiseParseException, msg ) \
+ WRAP_OTHER_EXCEPTIONS1( raiseParseException, msg )
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace sax = ::com::sun::star::xml::sax;
+// -----------------------------------------------------------------------------
+
+SchemaParser::SchemaParser(uno::Reference< uno::XComponentContext > const & _xContext, uno::Reference< backenduno::XSchemaHandler > const & _xHandler, Select _selector)
+: BasicParser(_xContext)
+, m_xHandler(_xHandler)
+, m_sComponent()
+, m_selector(_selector)
+, m_selected(selectNone)
+{
+ if (!m_xHandler.is())
+ {
+ rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM("Cannot create SchemaParser: Unexpected NULL Handler"));
+ throw uno::RuntimeException(sMessage, *this);
+ }
+ OSL_ENSURE(m_selector != selectNone, "Warning: Schema handler will handle no part of the schema");
+}
+// -----------------------------------------------------------------------------
+
+SchemaParser::~SchemaParser()
+{
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaParser::startDocument( )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ BasicParser::startDocument();
+
+ OSL_ENSURE(isEmptyNode(), "BasicParser does not mark new document as empty");
+
+ m_sComponent = rtl::OUString();
+ m_selected = selectNone;
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaParser::endDocument( ) throw (sax::SAXException, uno::RuntimeException)
+{
+ if (isSelected())
+ raiseParseException("Schema XML Parser: Invalid XML: Document ends while section is open");
+
+ if (isEmptyNode()) OSL_TRACE("Configuration Parser: XML schema document ended without any data");
+
+ BasicParser::endDocument();
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaParser::startElement( const rtl::OUString& aName, const uno::Reference< sax::XAttributeList >& xAttribs )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ if ( this->isSkipping() )
+ {
+ this->startSkipping( aName, xAttribs );
+ return;
+ }
+
+ ElementInfo aInfo = getDataParser().parseElementInfo(aName,xAttribs);
+
+ try
+ {
+ switch (aInfo.type)
+ {
+ case ElementType::schema:
+ this->startSchema(aInfo,xAttribs);
+ break;
+
+ case ElementType::component:
+ this->startSection(selectComponent, aInfo, xAttribs);
+ break;
+
+ case ElementType::templates:
+ this->startSection(selectTemplates, aInfo, xAttribs);
+ break;
+
+ case ElementType::import:
+ this->handleImport(aInfo,xAttribs);
+ this->startSkipping( aName, xAttribs );
+ break;
+
+ case ElementType::uses:
+ this->startSkipping( aName, xAttribs );
+ break;
+
+ case ElementType::instance:
+ this->handleInstance(aInfo,xAttribs);
+ this->startSkipping( aName, xAttribs );
+ break;
+
+ case ElementType::item_type:
+ this->handleItemType(aInfo,xAttribs);
+ this->startSkipping( aName, xAttribs );
+ break;
+
+ case ElementType::layer:
+ case ElementType::node:
+ raiseParseException( "Schema XML parser - Invalid data: found unspecified 'node' element.\n");
+ // fall thru
+ case ElementType::group: case ElementType::set:
+ this->startNode(aInfo,xAttribs);
+ OSL_ASSERT( this->isInNode() );
+ break;
+
+ case ElementType::property:
+ this->startProperty(aInfo,xAttribs);
+ OSL_ASSERT( this->isInUnhandledProperty() );
+ break;
+
+ case ElementType::value:
+ this->startValueData(xAttribs);
+ OSL_ASSERT( this->isInValueData() );
+ break;
+
+ default: // skip unknown elements
+ OSL_ENSURE( aInfo.type <= ElementType::other, "Schema XML parser - Error: invalid element type value\n");
+ OSL_ENSURE( aInfo.type >= ElementType::other, "Schema XML parser - Unexpected: found layer element in schema data\n");
+ // accept (and skip) unknown (ElementType::other) tags in schema to allow documentation and constraints to pass without assertion
+ //OSL_ENSURE( aInfo.type < ElementType::other, "Schema XML parser - Warning: ignoring unknown element tag\n");
+
+ this->startSkipping( aName, xAttribs );
+ OSL_ASSERT( this->isSkipping() );
+ return;
+ }
+ }
+ WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Starting Element")
+
+ OSL_ENSURE(aInfo.op == Operation::none || this->isSkipping(),
+ "Schema Parser: The 'op' attribute is not supported in a schema");
+}
+// -----------------------------------------------------------------------------
+
+void SAL_CALL SchemaParser::endElement( const rtl::OUString& aName )
+ throw (sax::SAXException, uno::RuntimeException)
+{
+ if ( this->wasSkipping(aName) )
+ return;
+
+ try
+ {
+ if ( this->isInValueData())
+ this->endValueData();
+
+ else if (this->isInProperty())
+ this->endProperty();
+
+ else if (this->isInNode())
+ this->endNode();
+
+ else if (this->isSelected())
+ this->endSection();
+
+ else
+ this->endSchema();
+ }
+ WRAP_PARSE_EXCEPTIONS_MSG("LayerParser - Ending Element")
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+void SchemaParser::startSchema( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& /*xAttribs*/ )
+{
+ m_sComponent = aInfo.name;
+ m_xHandler->startSchema();
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::endSchema( )
+{
+ m_xHandler->endSchema();
+ m_sComponent = rtl::OUString();
+}
+// -----------------------------------------------------------------------------
+
+bool SchemaParser::select(Select _select)
+{
+ if (isSelected())
+ raiseParseException("Schema XML parser - Invalid data: found start of section while a section is still open.\n");
+
+ m_selected = static_cast<Select>(m_selector & _select);
+
+ return m_selected != 0;
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::startSection( Select _select, ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ if (this->select(_select))
+ {
+ if (_select == selectComponent)
+ {
+ m_xHandler->startComponent(m_sComponent);
+ }
+ }
+ else
+ startSkipping(aInfo.name,xAttribs);
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::endSection( )
+{
+ if (m_selected == selectComponent)
+ {
+ m_xHandler->endComponent();
+ }
+ m_selected = selectNone;
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::handleImport( ElementInfo const & /*aInfo*/, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ rtl::OUString aComponent;
+ if (getDataParser().getImportComponent(xAttribs,aComponent))
+ m_xHandler->importComponent(aComponent);
+
+ else
+ raiseParseException("Schema XML parser - Invalid data: Missing component attribute for import directive.\n");
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::handleInstance( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ backenduno::TemplateIdentifier aTemplate;
+ if (getDataParser().getInstanceType(xAttribs, aTemplate.Name, aTemplate.Component))
+ m_xHandler->addInstance(aInfo.name, aTemplate);
+
+ else
+ raiseParseException("Schema XML parser - Invalid data: Missing type information for instantiation directive.\n");
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::handleItemType( ElementInfo const & /*aInfo*/, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ backenduno::TemplateIdentifier aTemplate;
+ if (getDataParser().getInstanceType(xAttribs, aTemplate.Name, aTemplate.Component))
+ m_xHandler->addItemType(aTemplate);
+
+ else
+ raiseParseException("Schema XML parser - Invalid data: Missing type information for instantiation directive.\n");
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ bool bStartTemplate = ( !isInNode() && m_selected == selectTemplates );
+
+ BasicParser::startNode(aInfo,xAttribs);
+
+ OSL_ASSERT(aInfo.type == ElementType::set || aInfo.type == ElementType::group);
+
+ if (aInfo.type == ElementType::group)
+ {
+ if (bStartTemplate)
+ m_xHandler->startGroupTemplate( backenduno::TemplateIdentifier(aInfo.name,m_sComponent), aInfo.flags );
+
+ else
+ m_xHandler->startGroup( aInfo.name, aInfo.flags );
+ }
+ else
+ {
+ backenduno::TemplateIdentifier aItemType;
+
+ if (!getDataParser().getSetElementType(xAttribs, aItemType.Name, aItemType.Component))
+ raiseParseException("Schema XML parser - Invalid data: Missing item-type information for set node.\n");
+
+ if (bStartTemplate)
+ m_xHandler->startSetTemplate( backenduno::TemplateIdentifier(aInfo.name,m_sComponent), aInfo.flags, aItemType );
+
+ else
+ m_xHandler->startSet( aInfo.name, aInfo.flags, aItemType );
+ }
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::endNode()
+{
+ BasicParser::endNode();
+
+ bool bEndedTemplate = ( !isInNode() && m_selected == selectTemplates );
+
+ if (bEndedTemplate)
+ m_xHandler->endTemplate();
+
+ else
+ m_xHandler->endNode();
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs )
+{
+ BasicParser::startProperty(aInfo,xAttribs);
+
+ OSL_ENSURE( isInUnhandledProperty(), "Property not recognizable as unhandled");
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::endProperty()
+{
+ if (isInUnhandledProperty())
+ {
+ ElementInfo const & aInfo = this->getActiveNodeInfo();
+
+ m_xHandler->addProperty(aInfo.name,
+ aInfo.flags,
+ getActivePropertyType());
+ }
+
+ BasicParser::endProperty();
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::startValueData(const uno::Reference< sax::XAttributeList >& xAttribs)
+{
+ OSL_ENSURE( this->isInUnhandledProperty(),"Schema XML parser - multiple values in property are not permitted in the schema.\n");
+
+ BasicParser::startValueData(xAttribs);
+
+ if (this->isValueDataLocalized())
+ getLogger().warning("Language attributes on values are ignored in the schema.",
+ "endValueData()","configuration::xml::SchemaParser");
+}
+// -----------------------------------------------------------------------------
+
+void SchemaParser::endValueData()
+{
+ uno::Any aValue = this->getCurrentValue();
+
+ ElementInfo const & aInfo = this->getActiveNodeInfo();
+
+ if (aValue.hasValue())
+ {
+ m_xHandler->addPropertyWithDefault(aInfo.name,aInfo.flags,aValue);
+ }
+ else
+ {
+ getLogger().warning("Found deprecated explicit NIL value in schema data.",
+ "endValueData()","configuration::xml::SchemaParser");
+ m_xHandler->addProperty(aInfo.name,aInfo.flags,getActivePropertyType());
+ }
+
+ BasicParser::endValueData();
+
+ OSL_ENSURE( !isInUnhandledProperty(), "Property not recognizable as handled");
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/xml/schemaparser.hxx b/configmgr/source/xml/schemaparser.hxx
new file mode 100644
index 000000000000..782eba72afa2
--- /dev/null
+++ b/configmgr/source/xml/schemaparser.hxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: schemaparser.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_SCHEMAPARSER_HXX
+#define CONFIGMGR_XML_SCHEMAPARSER_HXX
+
+#include "basicparser.hxx"
+
+#include <com/sun/star/configuration/backend/XSchemaHandler.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+ namespace sax = ::com::sun::star::xml::sax;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+
+// -----------------------------------------------------------------------------
+
+
+ class SchemaParser : public BasicParser
+ {
+ public:
+ enum Select {
+ selectNone = 0,
+ selectComponent = 0x01,
+ selectTemplates = 0x02,
+ selectAll = 0x03
+ };
+
+ public:
+ SchemaParser(uno::Reference< uno::XComponentContext > const & _xContext, uno::Reference< backenduno::XSchemaHandler > const & _xHandler, Select _selector);
+ virtual ~SchemaParser();
+
+ // XDocumentHandler
+ public:
+ virtual void SAL_CALL
+ startDocument( )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endDocument( ) throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ startElement( const rtl::OUString& aName, const uno::Reference< sax::XAttributeList >& xAttribs )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ virtual void SAL_CALL
+ endElement( const rtl::OUString& aName )
+ throw (sax::SAXException, uno::RuntimeException);
+
+ private:
+ /// start the schema
+ void startSchema( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// end the schema
+ void endSchema();
+
+ /// start a section (components or templates)
+ void startSection( Select _select, ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// end the current section
+ void endSection();
+
+ /// handle a import directive element
+ void handleImport( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+
+ /// start an node
+ void startNode( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// end a node
+ void endNode();
+
+ /// start a property
+ void startProperty( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// end a property
+ void endProperty();
+
+ /// start collecting data for a value - returns the locale of the value (property must have been started)
+ void startValueData(const uno::Reference< sax::XAttributeList >& xAttribs);
+ /// end collecting data for a value - returns the collected value
+ void endValueData();
+
+ /// handle a instance ref element
+ void handleInstance( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+ /// handle a item-type declaration element
+ void handleItemType( ElementInfo const & aInfo, const uno::Reference< sax::XAttributeList >& xAttribs );
+
+ bool isSelected() const { return m_selected != selectNone; }
+ bool select(Select _select);
+ private:
+ uno::Reference< backenduno::XSchemaHandler > m_xHandler;
+ rtl::OUString m_sComponent;
+ Select m_selector;
+ Select m_selected;
+ };
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/xml/simpletypehelper.cxx b/configmgr/source/xml/simpletypehelper.cxx
new file mode 100644
index 000000000000..60785393d420
--- /dev/null
+++ b/configmgr/source/xml/simpletypehelper.cxx
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: simpletypehelper.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "simpletypehelper.hxx"
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+namespace configmgr
+{
+ namespace uno = com::sun::star::uno;
+ namespace SimpleTypeHelper
+ {
+
+ uno::Type getBooleanType() { return ::getBooleanCppuType(); }
+
+ uno::Type getShortType() { return ::getCppuType(static_cast<sal_Int16 const*>(0)); }
+ uno::Type getIntType() { return ::getCppuType(static_cast<sal_Int32 const*>(0)); }
+ uno::Type getLongType() { return ::getCppuType(static_cast<sal_Int64 const*>(0)); }
+
+ uno::Type getDoubleType() { return ::getCppuType(static_cast<double const*>(0)); }
+
+ uno::Type getStringType() { return ::getCppuType(static_cast<rtl::OUString const*>(0)); }
+
+ uno::Type getBinaryType() { return ::getCppuType(static_cast<uno::Sequence<sal_Int8> const*>(0)); }
+ uno::Type getAnyType() { return ::getCppuType(static_cast<uno::Any const*>(0)); }
+ }
+}
diff --git a/configmgr/source/xml/typeconverter.cxx b/configmgr/source/xml/typeconverter.cxx
new file mode 100644
index 000000000000..0f292db78de2
--- /dev/null
+++ b/configmgr/source/xml/typeconverter.cxx
@@ -0,0 +1,354 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: typeconverter.cxx,v $
+ * $Revision: 1.25 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include "typeconverter.hxx"
+#include "utility.hxx"
+#include "simpletypehelper.hxx"
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/FailReason.hpp>
+#include <com/sun/star/uno/Type.hxx>
+#include <strdecl.hxx>
+#include <typelib/typedescription.hxx>
+
+
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+
+namespace uno = ::com::sun::star::uno;
+namespace script = ::com::sun::star::script;
+namespace lang = ::com::sun::star::lang;
+
+namespace configmgr
+{
+
+//--------------------------------------------------------------------------------------------------
+ rtl::OUString toString(const uno::Reference< script::XTypeConverter >& xTypeConverter, const uno::Any& rValue)
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+ {
+ rtl::OUString aRes;
+ uno::TypeClass aDestinationClass = rValue.getValueType().getTypeClass();
+
+ switch (aDestinationClass)
+ {
+ case uno::TypeClass_BOOLEAN:
+ case uno::TypeClass_CHAR:
+ case uno::TypeClass_BYTE:
+ case uno::TypeClass_SHORT:
+ case uno::TypeClass_LONG:
+ case uno::TypeClass_HYPER:
+ case uno::TypeClass_FLOAT:
+ case uno::TypeClass_DOUBLE:
+ if (!xTypeConverter.is())
+ {
+ throw script::CannotConvertException(
+ ::rtl::OUString::createFromAscii("Missing Converter Service!"),
+ uno::Reference< uno::XInterface > (),
+ aDestinationClass,
+ script::FailReason::UNKNOWN, 0
+ );
+ }
+ xTypeConverter->convertToSimpleType(rValue, uno::TypeClass_STRING) >>= aRes;
+ break;
+
+ case ::uno::TypeClass_STRING:
+ rValue >>= aRes;
+ break;
+
+ default:
+ throw script::CannotConvertException(
+ ::rtl::OUString::createFromAscii("Unsupported type: ") + rValue.getValueType().getTypeName(),
+ uno::Reference< uno::XInterface > (),
+ aDestinationClass,
+ script::FailReason::TYPE_NOT_SUPPORTED, 0
+ );
+
+ }
+ return aRes;
+ }
+
+ uno::Any toAny(const uno::Reference< script::XTypeConverter >& xTypeConverter, const ::rtl::OUString& _rValue,const uno::TypeClass& _rTypeClass)
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+ {
+ uno::Any aRes;
+
+ if (uno::TypeClass_STRING == _rTypeClass)
+ {
+ aRes <<= _rValue;
+ }
+ else if (!xTypeConverter.is())
+ {
+ throw script::CannotConvertException(
+ ::rtl::OUString::createFromAscii("Missing Converter Service!"),
+ uno::Reference< uno::XInterface > (),
+ _rTypeClass,
+ script::FailReason::UNKNOWN, 0
+ );
+ }
+ else try
+ {
+ aRes = xTypeConverter->convertToSimpleType(uno::makeAny(_rValue), _rTypeClass);
+ }
+ catch (script::CannotConvertException& )
+ {
+ // ok, next try with trim()
+ ::rtl::OUString const sTrimmed = _rValue.trim();
+ if (sTrimmed.getLength() != 0)
+ {
+ try
+ {
+ aRes = xTypeConverter->convertToSimpleType(uno::makeAny(sTrimmed), _rTypeClass);
+
+ OSL_ENSURE(aRes.hasValue(),"Converted non-empty string to NULL\n");
+ }
+ catch (script::CannotConvertException&)
+ {
+ OSL_ASSERT(!aRes.hasValue());
+ }
+ catch (uno::Exception&)
+ {
+ OSL_ENSURE(false,"Unexpected exception from XTypeConverter::convertToSimpleType()\n");
+ OSL_ASSERT(!aRes.hasValue());
+ }
+
+ if (!aRes.hasValue()) throw;
+ }
+ }
+ catch (lang::IllegalArgumentException& iae)
+ {
+ OSL_ENSURE(sal_False, "Illegal argument for typeconverter. Maybe invalid typeclass ?");
+ throw script::CannotConvertException(
+ ::rtl::OUString::createFromAscii("Invalid Converter Argument:") + iae.Message,
+ uno::Reference< uno::XInterface > (),
+ _rTypeClass,
+ script::FailReason::UNKNOWN, 0
+ );
+ }
+ catch (uno::Exception& e)
+ {
+ OSL_ENSURE(false,"Unexpected exception from XTypeConverter::convertToSimpleType()\n");
+ throw script::CannotConvertException(
+ ::rtl::OUString::createFromAscii("Unexpected TypeConverter Failure:") + e.Message,
+ uno::Reference< uno::XInterface > (),
+ _rTypeClass,
+ script::FailReason::UNKNOWN, 0
+ );
+ }
+ return aRes;
+ }
+
+ ::rtl::OUString toTypeName(const uno::TypeClass& _rTypeClass)
+ {
+ ::rtl::OUString aRet;
+ switch(_rTypeClass)
+ {
+ case uno::TypeClass_BOOLEAN: aRet = TYPE_BOOLEAN; break;
+ case uno::TypeClass_SHORT: aRet = TYPE_SHORT; break;
+ case uno::TypeClass_LONG: aRet = TYPE_INT; break;
+ case uno::TypeClass_HYPER: aRet = TYPE_LONG; break;
+ case uno::TypeClass_DOUBLE: aRet = TYPE_DOUBLE; break;
+ case uno::TypeClass_STRING: aRet = TYPE_STRING; break;
+ case uno::TypeClass_SEQUENCE: aRet = TYPE_BINARY; break;
+ case uno::TypeClass_ANY: aRet = TYPE_ANY; break;
+ default:
+ {
+ ::rtl::OString aStr("Wrong typeclass! ");
+ aStr += ::rtl::OString::valueOf((sal_Int32)_rTypeClass);
+ OSL_ENSURE(0,aStr.getStr());
+ }
+ }
+ return aRet;
+ }
+
+// *************************************************************************
+ uno::Type toType(const ::rtl::OUString& _rType)
+ {
+ uno::Type aRet;
+
+ if (_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("boolean"))) aRet = SimpleTypeHelper::getBooleanType();
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("short"))) aRet = SimpleTypeHelper::getShortType();
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("int"))) aRet = SimpleTypeHelper::getIntType();
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("integer"))) aRet = SimpleTypeHelper::getIntType();
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("long"))) aRet = SimpleTypeHelper::getLongType();
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("double"))) aRet = SimpleTypeHelper::getDoubleType();
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("string"))) aRet = SimpleTypeHelper::getStringType();
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("binary"))) aRet = SimpleTypeHelper::getBinaryType();
+// else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("sequence"))) aRet = uno::TypeClass_SEQUENCE;
+
+ else if(_rType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("any"))) aRet = SimpleTypeHelper::getAnyType();
+ else
+ {
+ ::rtl::OString aStr("Unknown type! ");
+ aStr += rtl::OUStringToOString(_rType,RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(0,aStr.getStr());
+ }
+
+ return aRet;
+ }
+ uno::Type toListType(const ::rtl::OUString& _rsElementType)
+ {
+ uno::Type aRet;
+
+ if (_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("boolean")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Bool> const*>(0));
+
+ else if(_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("short")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int16> const*>(0));
+
+ else if(_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("int")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int32> const*>(0));
+ else if(_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("integer")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int32> const*>(0));
+
+ else if(_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("long")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<sal_Int64> const*>(0));
+
+ else if(_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("double")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<double> const*>(0));
+
+ else if(_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("string")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<rtl::OUString> const*>(0));
+
+ else if(_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("binary")))
+ aRet = ::getCppuType(static_cast<uno::Sequence<uno::Sequence<sal_Int8> > const*>(0));
+
+// else if(_rsElementType.equalsIgnoreAsciiCase(::rtl::OUString::createFromAscii("sequence"))) aRet = uno::TypeClass_SEQUENCE;
+ else
+ {
+ ::rtl::OString aStr("Unknown type! ");
+ aStr += rtl::OUStringToOString(_rsElementType,RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(0,aStr.getStr());
+ }
+
+ return aRet;
+ }
+
+ uno::Type getSequenceElementType(uno::Type const& rSequenceType)
+ {
+ OSL_ENSURE(rSequenceType.getTypeClass() == uno::TypeClass_SEQUENCE,
+ "getSequenceElementType() must be called with a sequence type");
+
+ if (!(rSequenceType.getTypeClass() == uno::TypeClass_SEQUENCE))
+ return uno::Type();
+
+ uno::TypeDescription aTD(rSequenceType);
+ typelib_IndirectTypeDescription* pSequenceTD =
+ reinterpret_cast< typelib_IndirectTypeDescription* >(aTD.get());
+
+ OSL_ASSERT(pSequenceTD);
+ OSL_ASSERT(pSequenceTD->pType);
+
+ if ( pSequenceTD && pSequenceTD->pType )
+ {
+ return uno::Type(pSequenceTD->pType);
+ } //if
+
+ return uno::Type();
+ }
+ uno::Type getBasicType(uno::Type const& rType, bool& bSequence)
+ {
+ bSequence = rType.getTypeClass() == uno::TypeClass_SEQUENCE &&
+ rType != SimpleTypeHelper::getBinaryType();
+
+ if (!bSequence)
+ return rType;
+
+ return getSequenceElementType(rType);
+ }
+
+
+ // template names
+// *************************************************************************
+ ::rtl::OUString toTemplateName(const uno::Type& _rType)
+ {
+ bool bList;
+ uno::Type aBaseType = getBasicType(_rType,bList);
+ return toTemplateName(aBaseType.getTypeClass(), bList);
+ }
+
+ ::rtl::OUString toTemplateName(const uno::TypeClass& _rBasicType, bool bList)
+ {
+ return toTemplateName(toTypeName(_rBasicType), bList);
+ }
+
+// *************************************************************************
+ uno::Type parseTemplateName(::rtl::OUString const& sTypeName)
+ {
+ uno::Type aRet;
+
+ ::rtl::OUString sBasicTypeName;
+ bool bList;
+ if (parseTemplateName(sTypeName, sBasicTypeName,bList))
+ aRet = toType(sBasicTypeName,bList);
+ // else leave as void
+
+ return aRet;
+ }
+
+// *************************************************************************
+ ::rtl::OUString toTemplateName(const ::rtl::OUString& _rBasicTypeName, bool bList)
+ {
+ ::rtl::OUString sName = TEMPLATE_MODULE_NATIVE_PREFIX + _rBasicTypeName;
+ if (bList)
+ sName += TEMPLATE_LIST_SUFFIX;
+
+
+ return sName;
+ }
+
+ bool parseTemplateName(::rtl::OUString const& sTypeName, ::rtl::OUString& _rBasicName, bool& bList)
+ {
+ ::rtl::OUString const sSuffix( TEMPLATE_LIST_SUFFIX );
+
+ sal_Int32 nIndex = sTypeName.lastIndexOf(sSuffix);
+ if (nIndex >= 0 && nIndex + sSuffix.getLength() == sTypeName.getLength())
+ {
+ bList = true;
+ _rBasicName = sTypeName.copy(0,nIndex);
+ }
+ else
+ {
+ bList = false;
+ _rBasicName = sTypeName;
+ }
+ // erase the default prefix 'cfg:'
+ if (_rBasicName.indexOf(TEMPLATE_MODULE_NATIVE_PREFIX) == 0)
+ _rBasicName = _rBasicName.copy(TEMPLATE_MODULE_NATIVE_PREFIX.m_nLen);
+
+ return true;
+
+ }
+// *************************************************************************
+
+} // namespace configmgr
diff --git a/configmgr/source/xml/valueconverter.cxx b/configmgr/source/xml/valueconverter.cxx
new file mode 100644
index 000000000000..116d70d1852c
--- /dev/null
+++ b/configmgr/source/xml/valueconverter.cxx
@@ -0,0 +1,504 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valueconverter.cxx,v $
+ * $Revision: 1.23 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "valuetypeconverter.hxx"
+#include "typeconverter.hxx"
+
+inline sal_Bool rtl_ascii_isWhitespace( sal_Unicode ch )
+{
+ return ch <= 0x20 && ch;
+}
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+static
+void throwConversionError(sal_Char const* pErrorMsg) SAL_THROW((script::CannotConvertException))
+{
+ OSL_ENSURE(false, pErrorMsg);
+
+ script::CannotConvertException error;
+ error.Message = rtl::OUString::createFromAscii(pErrorMsg);
+ throw error;
+}
+// -----------------------------------------------------------------------------
+template <class Char>
+inline
+bool charInRange(Char ch, char from, char to) throw()
+{
+ return Char(from) <= ch && ch <= Char(to);
+}
+
+// -----------------------------------------------------------------------------
+static
+inline
+unsigned makeHexNibble(unsigned char ch) SAL_THROW((script::CannotConvertException))
+{
+ unsigned nRet = 0;
+
+ if (charInRange(ch, '0', '9')) nRet = ch - unsigned('0');
+
+ else if (charInRange(ch, 'a', 'f')) nRet = ch - unsigned('a' - 10u);
+
+ else if (charInRange(ch, 'A', 'F')) nRet = ch - unsigned('A' - 10u);
+
+ else throwConversionError("Invalid Hex Character in binary value");
+
+ return nRet;
+}
+
+// -----------------------------------------------------------------------------
+static
+inline
+unsigned readHexNibble(sal_Unicode ch) SAL_THROW((script::CannotConvertException))
+{
+ if (!charInRange(ch, 0, 127)) throwConversionError("Non-Ascii Character in binary value");
+
+ return makeHexNibble(static_cast<unsigned char>(ch));
+}
+
+// -----------------------------------------------------------------------------
+static
+inline
+unsigned int readHexByte(sal_Unicode const*& pStr) SAL_THROW((script::CannotConvertException))
+{
+ register unsigned int nHigh = readHexNibble(*pStr++);
+ register unsigned int nLow = readHexNibble(*pStr++);
+ return (nHigh << 4) | nLow;
+}
+
+// -----------------------------------------------------------------------------
+static
+void parseHexBinary(rtl::OUString const& aHexString_, uno::Sequence<sal_Int8>& rBinarySeq_)
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+{
+ // PRE: aBinaryString with HexCode
+ // POST: rBinarySeq with the to Hex converted String
+
+ sal_uInt32 nCount = aHexString_.getLength();
+ sal_Unicode const * pHex = aHexString_.getStr();
+
+ if (nCount % 2) throwConversionError("Hex string has odd number of characters");
+ nCount /= 2;
+
+ rBinarySeq_.realloc(nCount);
+ sal_Int8 * pBinary = rBinarySeq_.getArray();
+
+ while (nCount--)
+ {
+ *pBinary++ = static_cast<sal_Int8>(readHexByte(pHex));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+uno::Sequence<sal_Int8> ValueConverter::parseBinary(rtl::OUString const& aBinaryString_) const
+ SAL_THROW((script::CannotConvertException, com::sun::star::uno::RuntimeException))
+{
+ uno::Sequence<sal_Int8> aResultSeq;
+
+ parseHexBinary(aBinaryString_,aResultSeq);
+
+ return aResultSeq;
+}
+
+// -----------------------------------------------------------------------------
+static inline
+uno::Type getBinaryType()
+{
+ uno::Sequence<sal_Int8> const * const for_binary = 0;
+ return ::getCppuType(for_binary);
+}
+
+// -----------------------------------------------------------------------------
+bool ValueConverter::isList() const
+{
+ return m_aType.getTypeClass() == uno::TypeClass_SEQUENCE &&
+ m_aType != getBinaryType();
+}
+
+// -----------------------------------------------------------------------------
+uno::Any ValueConverter::convertToAny(rtl::OUString const& aContent) const
+ SAL_THROW((script::CannotConvertException, com::sun::star::uno::RuntimeException))
+{
+ uno::Any aValue;
+
+ if (this->isNull())
+ {
+ OSL_ENSURE(aContent.trim().getLength() == 0, "ValueConverter: Non-empty Null Value - ignoring content");
+ OSL_ASSERT(!aValue.hasValue());
+ }
+
+ else if (this->isList())
+ {
+ std::vector< rtl::OUString > aContentList;
+ splitListData(aContent, aContentList);
+ convertListToAny(aContentList, aValue);
+ }
+
+ else
+ {
+ convertScalarToAny(aContent, aValue);
+ }
+
+ return aValue;
+}
+
+// -----------------------------------------------------------------------------
+bool ValueConverter::convertScalarToAny(rtl::OUString const& aContent, uno::Any& rValue) const
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(!this->isNull(),"ValueConverter::convertScalarToAny - check for NULL before calling");
+ OSL_ENSURE(m_aType.getTypeClass() != uno::TypeClass_ANY,"'Any' values must be NULL");
+
+ // check for Binary
+ if (m_aType == getBinaryType())
+ {
+ com::sun::star::uno::Sequence<sal_Int8> aBinarySeq = parseBinary(aContent);
+ rValue <<= aBinarySeq;
+ }
+
+ else
+ {
+ rValue = toAny(m_xTypeConverter, aContent, m_aType.getTypeClass());
+ }
+
+ return !! rValue.hasValue();
+}
+
+// -----------------------------------------------------------------------------
+template <class T>
+bool convertListToSequence(std::vector< rtl::OUString > const& aStringList, uno::Sequence< T >& rSequence, uno::TypeClass aElementTypeClass, ValueConverter const& rConverter)
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+{
+ OSL_ASSERT(aElementTypeClass == ::getCppuType(static_cast<T const*>(0)).getTypeClass());
+
+ rSequence.realloc(aStringList.size());
+
+ sal_uInt32 nPos = 0;
+
+ for(std::vector< rtl::OUString >::const_iterator it = aStringList.begin();
+ it != aStringList.end();
+ ++it)
+ {
+ uno::Any aValueAny = toAny(rConverter.getTypeConverter(), *it, aElementTypeClass);
+
+ if (aValueAny >>= rSequence[nPos])
+ ++nPos;
+
+ else if (!aValueAny.hasValue())
+ OSL_ENSURE(false,"UNEXPECTED: Found NULL value in List - ignoring value !");
+
+ else
+ OSL_ENSURE(false,"ERROR: Cannot extract converted value into List - skipping value !");
+ }
+
+ bool bOK = (nPos == aStringList.size());
+
+ if (!bOK)
+ {
+ OSL_ASSERT(nPos < aStringList.size());
+ rSequence.realloc(nPos);
+ }
+ return bOK;
+}
+
+// -----------------------------------------------------------------------------
+// special conversion for string sequence
+
+static
+inline
+void stringListToSequence(uno::Sequence< rtl::OUString > & rSequence, std::vector< rtl::OUString > const & aStringList)
+{
+ rSequence .realloc( aStringList.size() );
+
+ std::copy( aStringList.begin(), aStringList.end(), rSequence.getArray() );
+}
+// -----------------------------------------------------------------------------
+
+static
+inline
+std::vector< rtl::OUString > sequenceToStringList(uno::Sequence< rtl::OUString > const & aSequence)
+{
+ rtl::OUString const * const pBegin = aSequence.getConstArray();
+ rtl::OUString const * const pEnd = pBegin + aSequence.getLength();
+
+ return std::vector< rtl::OUString >(pBegin,pEnd);
+}
+// -----------------------------------------------------------------------------
+
+uno::Sequence< rtl::OUString > ValueConverter::splitStringList(rtl::OUString const& aContent) const
+{
+ std::vector< rtl::OUString > aList;
+ splitListData(aContent, aList);
+
+ uno::Sequence< rtl::OUString > aResult;
+ stringListToSequence(aResult,aList);
+
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+
+uno::Any ValueConverter::convertListToAny(uno::Sequence< rtl::OUString > const& aContentList) const
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+{
+ uno::Any aResult;
+ std::vector< rtl::OUString > const aStringList = sequenceToStringList(aContentList);
+ convertListToAny(aStringList,aResult);
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+// special overload for binary sequence
+
+// template<> // use an explicit specialization
+bool convertListToSequence(std::vector< rtl::OUString > const& aStringList, uno::Sequence< uno::Sequence<sal_Int8> >& rSequence, uno::TypeClass aElementTypeClass, ValueConverter const& rParser )
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+{
+ { (void)aElementTypeClass; }
+ OSL_ASSERT(aElementTypeClass == uno::TypeClass_SEQUENCE);
+
+ rSequence.realloc(aStringList.size());
+
+ sal_uInt32 nPos = 0;
+
+ for(std::vector< rtl::OUString >::const_iterator it = aStringList.begin();
+ it != aStringList.end();
+ ++it)
+ {
+ rSequence[nPos++] = rParser.parseBinary(*it);
+ }
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+// special overload for string sequence
+
+// template<> // use an explicit specialization
+bool convertListToSequence(std::vector< rtl::OUString > const& aStringList, uno::Sequence< rtl::OUString >& rSequence, uno::TypeClass aElementTypeClass, ValueConverter const& /*rParser*/ )
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+{
+ { (void)aElementTypeClass; }
+ OSL_ASSERT(aElementTypeClass == uno::TypeClass_STRING);
+
+ stringListToSequence(rSequence, aStringList);
+
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+#define MAYBE_EXTRACT_SEQUENCE( type ) \
+ if (aElementType == ::getCppuType( (type const *)0)) \
+ { \
+ com::sun::star::uno::Sequence< type > aSequence; \
+ convertListToSequence(aContentList,aSequence,aElementTypeClass, *this); \
+ rValue <<= aSequence; \
+ }
+
+bool ValueConverter::convertListToAny(std::vector< rtl::OUString > const& aContentList, uno::Any& rValue) const
+ SAL_THROW((script::CannotConvertException , com::sun::star::uno::RuntimeException))
+{
+ OSL_PRECOND(!this->isNull(),"ValueConverter::convertListToAny - check for NULL before calling");
+ OSL_ENSURE(m_aType.getTypeClass() == uno::TypeClass_SEQUENCE,"'Any' not allowed for lists");
+
+ uno::Type aElementType = getSequenceElementType(m_aType);
+ uno::TypeClass aElementTypeClass = aElementType.getTypeClass();
+
+ OSL_ENSURE(aElementTypeClass != uno::TypeClass_ANY,"'Any' not allowed for list elements");
+
+ MAYBE_EXTRACT_SEQUENCE( rtl::OUString )
+ else
+ MAYBE_EXTRACT_SEQUENCE( sal_Bool )
+ else
+ MAYBE_EXTRACT_SEQUENCE( sal_Int16 )
+ else
+ MAYBE_EXTRACT_SEQUENCE( sal_Int32 )
+ else
+ MAYBE_EXTRACT_SEQUENCE( sal_Int64 )
+ else
+ MAYBE_EXTRACT_SEQUENCE( double )
+ else
+ MAYBE_EXTRACT_SEQUENCE( com::sun::star::uno::Sequence<sal_Int8> )
+ else
+ {
+ OSL_ENSURE(false, "Unknown element type in list");
+ throwConversionError("Invalid value-type found in list value");
+ }
+
+ return !! rValue.hasValue();
+}
+#undef MAYBE_EXTRACT_SEQUENCE
+
+// -----------------------------------------------------------------------------
+namespace
+{
+ sal_Int32 const NO_MORE_TOKENS = -1;
+ struct OTokenizeByWhitespace
+ {
+
+ static inline bool isWhitespace(sal_Unicode ch)
+ {
+ // note: for definition of whitescape see also
+ // canUseWhitespace(rtl::OUString const&)
+ // in xmlformater.cxx
+ // -----------------------------------------------------------------------------
+ return rtl_ascii_isWhitespace(ch) ? true : false;
+ }
+
+ sal_Int32 findFirstTokenStart(rtl::OUString const& sText) const SAL_THROW(())
+ {
+ return findNextTokenStart(sText,0);
+ }
+
+ sal_Int32 findNextTokenStart(rtl::OUString const& sText, sal_Int32 nPrevTokenEnd) const SAL_THROW(())
+ {
+ sal_Int32 const nEnd = sText.getLength();
+ sal_Int32 nPos = nPrevTokenEnd;
+
+ OSL_PRECOND( nPos == 0 || (0 < nPos && nPos < nEnd && isWhitespace(sText[nPos])) || nPos == nEnd,
+ "Invalid nPrevTokenEnd");
+
+ while (nPos < nEnd && isWhitespace(sText[nPos]))
+ {
+ ++nPos;
+ }
+
+ if (nPos < nEnd)
+ return nPos;
+ else
+ return NO_MORE_TOKENS;
+ }
+
+ sal_Int32 findTokenEnd(rtl::OUString const& sText, sal_Int32 nTokenStart) const SAL_THROW(())
+ {
+ sal_Int32 const nEnd = sText.getLength();
+ sal_Int32 nPos = nTokenStart;
+
+ OSL_PRECOND( 0 <= nPos && nPos < nEnd && !isWhitespace(sText[nPos]),
+ "Invalid nTokenStart");
+
+ while (nPos < nEnd && !isWhitespace(sText[nPos]))
+ {
+ ++nPos;
+ }
+
+ return nPos;
+ }
+ };
+// -----------------------------------------------------------------------------
+ struct OTokenizeBySeparator
+ {
+ rtl::OUString const sSeparator;
+ OTokenizeBySeparator(rtl::OUString const& _sSeparator) SAL_THROW(())
+ : sSeparator(_sSeparator)
+ {
+ OSL_PRECOND(sSeparator.trim().getLength() > 0, "Invalid empty separator string");
+ }
+
+ sal_Int32 findFirstTokenStart(rtl::OUString const& /*sText*/) const SAL_THROW(())
+ {
+ return 0;
+ }
+ sal_Int32 findNextTokenStart(rtl::OUString const& sText, sal_Int32 nPrevTokenEnd) const SAL_THROW(())
+ {
+ sal_Int32 const nEnd = sText.getLength();
+ sal_Int32 nPos = nPrevTokenEnd;
+ OSL_PRECOND( nPos == nEnd || (0 <= nPos && nPos < nEnd && sText.indexOf(sSeparator, nPos) == nPos),
+ "Invalid nPrevTokenEnd");
+
+ if (nPos < nEnd)
+ return nPos + sSeparator.getLength();
+ else
+ return NO_MORE_TOKENS;
+ }
+ sal_Int32 findTokenEnd(rtl::OUString const& sText, sal_Int32 nTokenStart) const SAL_THROW(())
+ {
+ sal_Int32 const nEnd = sText.getLength();
+ OSL_PRECOND( 0 <= nTokenStart && nTokenStart <= nEnd ,
+ "Invalid nTokenStart");
+
+ sal_Int32 nPos = sText.indexOf(sSeparator,nTokenStart);
+
+ if (nPos >= 0)
+ return nPos;
+ else
+ return nEnd;
+ }
+ };
+// -----------------------------------------------------------------------------
+ template <class Tokenizer>
+ void tokenizeListData(Tokenizer const& aTokenizer, rtl::OUString const& aContent, std::vector< rtl::OUString >& rContentList)
+ SAL_THROW(())
+ {
+ sal_Int32 nTokenPos = aTokenizer.findFirstTokenStart(aContent);
+
+ while(nTokenPos != NO_MORE_TOKENS)
+ {
+ sal_Int32 nTokenEnd = aTokenizer.findTokenEnd(aContent, nTokenPos);
+
+ // this is what the tokenizer must provide
+ OSL_ASSERT(0 <= nTokenPos && nTokenPos <= nTokenEnd && nTokenEnd <= aContent.getLength());
+
+ rContentList.push_back( aContent.copy(nTokenPos, nTokenEnd-nTokenPos) );
+
+ nTokenPos= aTokenizer.findNextTokenStart(aContent, nTokenEnd);
+ }
+ }
+// -----------------------------------------------------------------------------
+}
+// -----------------------------------------------------------------------------
+void ValueConverter::splitListData(rtl::OUString const& aContent, std::vector< rtl::OUString >& rContentList) const
+ SAL_THROW(())
+{
+ rtl::OUString sSeparator = m_sSeparator;
+
+ bool bSeparateByWhitespace = (sSeparator.trim().getLength() == 0);
+
+ if (bSeparateByWhitespace)
+ {
+ OSL_ENSURE( sSeparator.getLength()==0 || sSeparator.equalsAscii(" "),
+ "Unexpected whitespace-only separator");
+
+ tokenizeListData( OTokenizeByWhitespace(), aContent, rContentList );
+ }
+ else
+ {
+ OSL_ENSURE( sSeparator.trim()==sSeparator,
+ "Unexpected whitespace in separator");
+
+ tokenizeListData( OTokenizeBySeparator(sSeparator), aContent, rContentList );
+ }
+}
+// -----------------------------------------------------------------------------
+
+} // namespace
diff --git a/configmgr/source/xml/valueformatter.cxx b/configmgr/source/xml/valueformatter.cxx
new file mode 100644
index 000000000000..213f668e6f90
--- /dev/null
+++ b/configmgr/source/xml/valueformatter.cxx
@@ -0,0 +1,498 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valueformatter.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "valueformatter.hxx"
+#include "elementformatter.hxx"
+#include "xmlstrings.hxx"
+#include "typeconverter.hxx"
+#include "simpletypehelper.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#ifndef INCLUDED_ALGORITHM
+#include <algorithm>
+#define INCLUDED_ALGORITHM
+#endif
+
+namespace configmgr
+{
+ namespace uno = com::sun::star::uno;
+
+ namespace xml
+ {
+
+//==========================================================================
+//= Helper
+//==========================================================================
+
+// -----------------------------------------------------------------------------
+namespace
+{
+// -----------------------------------------------------------------------------
+
+static
+inline
+bool isWhitespaceCharacter( sal_Unicode ch )
+{
+ return ch <= 0x20 && ch;
+}
+// -----------------------------------------------------------------------------
+
+static
+inline
+bool isWhitespaceString(rtl::OUString const & aStr)
+{
+ sal_Unicode const * const pBegin = aStr.getStr();
+ sal_Unicode const * const pEnd = pBegin + aStr.getLength();
+
+ // BACK: true, if any whitespace in string or string is empty
+ if (pBegin == pEnd)
+ return true;
+
+ sal_Unicode const * const pSpace = std::find_if(pBegin,pEnd,isWhitespaceCharacter);
+
+ return pSpace != pEnd;
+}
+// -----------------------------------------------------------------------------
+
+static
+bool hasWhitespaceString( uno::Sequence< rtl::OUString > const & aSeq)
+{
+ // BACK: true, if whitespace Separator is ok, (no whitespace in Strings, no empty strings)
+ rtl::OUString const * const pBegin = aSeq.getConstArray();
+ rtl::OUString const * const pEnd = pBegin + aSeq.getLength();
+
+ rtl::OUString const * const pSpace = std::find_if(pBegin,pEnd,isWhitespaceString);
+
+ return pSpace != pEnd;
+}
+// -----------------------------------------------------------------------------
+
+struct HasSubString
+{
+ HasSubString(rtl::OUString const & _aSubStr)
+ : m_aSubStr(_aSubStr)
+ {}
+
+ bool operator()(rtl::OUString const & _aStr)
+ { return _aStr.indexOf(m_aSubStr) >= 0; }
+
+ rtl::OUString const m_aSubStr;
+};
+// -----------------------------------------------------------------------------
+
+static
+bool hasStringWithSubstring(const uno::Sequence< rtl::OUString > &aSeq, rtl::OUString const & _aSubStr)
+{
+ rtl::OUString const * const pBegin = aSeq.getConstArray();
+ rtl::OUString const * const pEnd = pBegin + aSeq.getLength();
+
+ rtl::OUString const * const pSpace = std::find_if(pBegin,pEnd,HasSubString(_aSubStr));
+
+ return pSpace != pEnd;
+}
+// -----------------------------------------------------------------------------
+
+
+template <class Element_>
+struct IsEmptySequence
+{
+ bool operator()(uno::Sequence<Element_> const & aSeq) const
+ {
+ return aSeq.getLength() == 0;
+ }
+};
+// -----------------------------------------------------------------------------
+
+template <class Element_>
+bool hasEmptySequence(uno::Sequence< uno::Sequence<Element_> > const & aSeqSeq)
+{
+ // BACK: true, if whitespace Separator is ok, (no whitespace in Strings, no empty strings)
+ uno::Sequence<Element_> const * const pBegin = aSeqSeq.getConstArray();
+ uno::Sequence<Element_> const * const pEnd = pBegin + aSeqSeq.getLength();
+
+ uno::Sequence<Element_> const * const pEmpty = std::find_if(pBegin, pEnd, IsEmptySequence<Element_>() );
+
+ return pEmpty != pEnd;
+}
+// -----------------------------------------------------------------------------
+
+inline
+bool canUseSeparator(uno::Sequence< rtl::OUString > const & aSeq, rtl::OUString const & aSeparator)
+{
+ return ! hasStringWithSubstring(aSeq,aSeparator);
+}
+// -----------------------------------------------------------------------------
+
+inline
+bool canUseWhitespaceSeparator(uno::Sequence< rtl::OUString > const & aSeq)
+{
+ return ! hasWhitespaceString(aSeq);
+}
+// -----------------------------------------------------------------------------
+
+template <class Element_>
+inline
+bool canUseWhitespaceSeparator(const uno::Sequence< uno::Sequence<Element_> > &aSeq)
+{
+ return ! hasEmptySequence(aSeq);
+}
+// -----------------------------------------------------------------------------
+
+class Separator
+{
+ rtl::OUString m_sValue;
+public:
+ // -----------------------------------------------------------------------------
+ Separator() : m_sValue() {}
+ // -----------------------------------------------------------------------------
+ bool isDefault() const { return m_sValue.getLength() == 0; }
+ // -----------------------------------------------------------------------------
+ rtl::OUString value() const { return isDefault() ? static_cast<rtl::OUString>(SEPARATOR_WHITESPACE) : m_sValue; }
+ // -----------------------------------------------------------------------------
+
+ bool check(const uno::Sequence<rtl::OUString> &aSeq) const
+ {
+ return isDefault() ? canUseWhitespaceSeparator(aSeq) : canUseSeparator(aSeq, m_sValue);
+ }
+
+ // -----------------------------------------------------------------------------
+ bool trySeparator(rtl::OUString const& sSep, const uno::Sequence<rtl::OUString> & aSeq)
+ {
+ OSL_ENSURE( ! isWhitespaceString(sSep), "There should be no spaces in non-default separators");
+ // BACK: true, if Separator is ok, not in Strings
+ if (!canUseSeparator(aSeq, sSep))
+ return false;
+ this->setSeparator(sSep);
+ return true;
+ }
+ // -----------------------------------------------------------------------------
+ void setSeparator(rtl::OUString const& sSep)
+ {
+ m_sValue = sSep;
+ }
+ // -----------------------------------------------------------------------------
+};
+// -----------------------------------------------------------------------------
+#define ASCII( STRING_LIT_ ) ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STRING_LIT_ ) ) )
+// -----------------------------------------------------------------------------
+static
+Separator createSeparator(const uno::Any& aAny)
+{
+ Separator aResult;
+
+ // create a Separator which isn't in any value
+ if (aAny.getValueTypeClass() == uno::TypeClass_SEQUENCE)
+ {
+ uno::Type aElementType = configmgr::getSequenceElementType(aAny.getValueType());
+ if (aElementType.getTypeClass() == uno::TypeClass_STRING)
+ {
+ // only in strings we need to search a separator
+ uno::Sequence<rtl::OUString> aSeq;
+
+ OSL_VERIFY (aAny >>= aSeq);
+
+ bool bValidSeparator =
+ canUseWhitespaceSeparator(aSeq) ||
+ aResult.trySeparator(ASCII(","), aSeq) ||
+ aResult.trySeparator(ASCII(";"), aSeq) ||
+ aResult.trySeparator(ASCII(":"), aSeq) ||
+ aResult.trySeparator(ASCII("|"), aSeq) ||
+ aResult.trySeparator(ASCII("#"), aSeq) ||
+ aResult.trySeparator(ASCII("-#*=+#-"), aSeq);
+
+ if (!bValidSeparator)
+ {
+ OSL_TRACE("ERROR: configuration formatter: Could not create Separator for string list");
+ OSL_ENSURE(false, "ERROR: Could not create Separator for string list");
+ }
+ else
+ {
+ // maybe the whitespace test was invalid ?
+ OSL_ENSURE(aResult.check(aSeq), "Found Separator does not pass check ?!");
+ }
+ }
+ else if (aElementType == SimpleTypeHelper::getBinaryType())
+ {
+ // only in strings we need to search a separator
+ uno::Sequence< uno::Sequence<sal_Int8> > aSeq;
+ OSL_VERIFY(aAny >>= aSeq);
+
+ if (!canUseWhitespaceSeparator(aSeq))
+ {
+ aResult.setSeparator( ASCII(":") );
+ }
+ }
+ }
+
+ // DefaultSeparator
+ return aResult;
+}
+#undef ASCII
+// -----------------------------------------------------------------------------
+static
+inline
+sal_Unicode hexNibble(sal_uInt8 _nNibble)
+{
+ OSL_ASSERT(_nNibble <= 0x0F);
+
+ const sal_uInt8 cDecOffset = sal_uInt8('0');
+ const sal_uInt8 cHexOffset = sal_uInt8('a') - 10;
+
+ return _nNibble + (_nNibble<10 ? cDecOffset : cHexOffset);
+}
+
+// -----------------------------------------------------------------------------
+static
+inline
+void appendHex(rtl::OUStringBuffer& rBuff, sal_uInt8 _nByte)
+{
+ rBuff.append( hexNibble(_nByte >> 4) );
+ rBuff.append( hexNibble(_nByte & 0x0f) );
+}
+
+// -----------------------------------------------------------------------------
+static
+rtl::OUString binaryToHex(const uno::Sequence<sal_Int8>& _aBinarySeq)
+{
+ sal_Int32 const nLength = _aBinarySeq.getLength();
+
+ rtl::OUStringBuffer sHex(2*nLength);
+
+ for (sal_Int32 nPos = 0;nPos < nLength; ++nPos)
+ {
+ appendHex( sHex, _aBinarySeq[nPos] );
+ }
+
+ OSL_ASSERT(sHex.getLength() == 2*nLength);
+ return sHex.makeStringAndClear();;
+}
+// -----------------------------------------------------------------------------
+rtl::OUString formatSimpleValue(uno::Any const & _aValue, uno::Reference< script::XTypeConverter > const & _xTCV)
+{
+ rtl::OUString sResult;
+
+ if (_aValue.hasValue())
+ {
+ if (_aValue .getValueType() == SimpleTypeHelper::getBinaryType())
+ {
+ uno::Sequence<sal_Int8> aBinarySeq;
+
+ OSL_VERIFY(_aValue >>= aBinarySeq);
+
+ sResult = binaryToHex(aBinarySeq);
+ }
+ else
+ {
+ // cannot have nested any
+ OSL_ASSERT(_aValue.getValueTypeClass() != uno::TypeClass_ANY);
+
+ sResult = toString(_xTCV, _aValue);
+ }
+ }
+ return sResult;
+}
+
+// -----------------------------------------------------------------------------
+template <class Element_>
+rtl::OUString formatSequence(uno::Sequence< Element_ > const& aSequence, rtl::OUString const& sSeparator, uno::Reference< script::XTypeConverter > const & _xTCV)
+{
+ rtl::OUStringBuffer aResult;
+
+ if (sal_Int32 const nLength = aSequence.getLength())
+ {
+ Element_ const * pSeq = aSequence.getConstArray();
+
+ aResult = formatSimpleValue( uno::makeAny(pSeq[0]),_xTCV);
+
+ for(sal_Int32 i=1; i<nLength; ++i)
+ {
+ aResult.append( sSeparator );
+ aResult.append( formatSimpleValue(uno::makeAny(pSeq[i]),_xTCV) );
+ }
+ }
+
+ return aResult.makeStringAndClear();
+}
+// -----------------------------------------------------------------------------
+// template <> // optimized overload for String
+rtl::OUString formatSequence(uno::Sequence< rtl::OUString > const& aSequence, rtl::OUString const& sSeparator, uno::Reference< script::XTypeConverter > const & )
+{
+ rtl::OUStringBuffer aResult;
+
+ if (sal_Int32 const nLength = aSequence.getLength())
+ {
+ rtl::OUString const * pSeq = aSequence.getConstArray();
+
+ aResult = pSeq[0];
+
+ for(sal_Int32 i=1; i<nLength; ++i)
+ {
+ aResult.append( sSeparator ).append( pSeq[i] );
+ }
+ }
+
+ return aResult.makeStringAndClear();
+}
+
+// -----------------------------------------------------------------------------
+
+#define CASE_WRITE_SEQUENCE(TYPE_CLASS, DATA_TYPE) \
+ case TYPE_CLASS: \
+ { \
+ uno::Sequence< DATA_TYPE > aData; \
+ OSL_ENSURE( ::getCppuType(static_cast< DATA_TYPE const*>(0)).getTypeClass() == (TYPE_CLASS), \
+ "Usage Error for CASE_WRITE_SEQUENCE: Type extracted does not match type class"); \
+ OSL_VERIFY( _aValue >>= aData ); \
+ aResult = formatSequence(aData,sSeparator,xTCV); \
+ } break \
+
+rtl::OUString formatSequenceValue(uno::Any const& _aValue, rtl::OUString const& sSeparator, uno::Reference< script::XTypeConverter > const & xTCV)
+{
+ rtl::OUString aResult;
+
+ uno::Type aElementType = getSequenceElementType( _aValue.getValueType() );
+
+ switch(aElementType.getTypeClass())
+ {
+ CASE_WRITE_SEQUENCE( uno::TypeClass_BOOLEAN, sal_Bool );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_SHORT, sal_Int16 );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_LONG, sal_Int32 );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_HYPER, sal_Int64 );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_DOUBLE, double );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_STRING, rtl::OUString );
+
+ CASE_WRITE_SEQUENCE( uno::TypeClass_SEQUENCE, uno::Sequence<sal_Int8> );
+
+ default:
+ OSL_ENSURE(false, "Unexpected typeclass for sequence elements");
+ break;
+ }
+
+ return aResult;
+}
+
+#undef CASE_WRITE_SEQUENCE
+// -----------------------------------------------------------------------------
+} // anonymous namspace
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+static inline bool isListVal(uno::Any const & _aValue)
+{
+ bool bList = false;
+ if (_aValue.hasValue())
+ {
+ getBasicType(_aValue.getValueType(),bList);
+ }
+ return bList;
+}
+// -----------------------------------------------------------------------------
+void ValueFormatter::makeSeparator()
+{
+ if (isListVal(m_aValue))
+ {
+ Separator aSeparator = createSeparator(m_aValue);
+
+ m_sSeparator = aSeparator.value();
+ m_bUseSeparator = !aSeparator.isDefault();
+
+ OSL_POSTCOND( this->isList() , "ValueFormatter: Could not mark as list");
+ }
+ else
+ {
+ m_sSeparator = rtl::OUString();
+ m_bUseSeparator = false;
+
+ OSL_POSTCOND( !this->isList(), "ValueFormatter: Could not mark as non-list");
+ }
+}
+// -----------------------------------------------------------------------------
+
+rtl::OUString ValueFormatter::getContent(uno::Reference< script::XTypeConverter > const & _xTCV) const
+{
+ rtl::OUString aResult;
+ try
+ {
+ if (this->isList())
+ {
+ aResult = formatSequenceValue(m_aValue, m_sSeparator, _xTCV);
+ }
+ else
+ {
+ aResult = formatSimpleValue(m_aValue, _xTCV);
+ }
+ }
+ catch (script::CannotConvertException& cce)
+ {
+ rtl::OUString const sMessage(RTL_CONSTASCII_USTRINGPARAM("Configuration: Could not convert value to XML representation: "));
+ throw uno::RuntimeException(sMessage + cce.Message, cce.Context);
+ }
+
+ return aResult;
+}
+// -----------------------------------------------------------------------------
+
+bool ValueFormatter::addValueAttributes(ElementFormatter & _rFormatter) const
+{
+ // do we have a NULL value
+ if (!m_aValue.hasValue())
+ {
+ _rFormatter.addIsNull();
+ return false;
+ }
+
+ // create a sequence separator
+ if (m_bUseSeparator)
+ {
+ OSL_ASSERT(this->isList());
+ _rFormatter.addSeparator(m_sSeparator);
+ }
+
+ return true;
+}
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+} // namespace xml
+
+// -----------------------------------------------------------------------------
+} // namespace configmgr
+
+
diff --git a/configmgr/source/xml/valueformatter.hxx b/configmgr/source/xml/valueformatter.hxx
new file mode 100644
index 000000000000..2b1f30b0fef7
--- /dev/null
+++ b/configmgr/source/xml/valueformatter.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: valueformatter.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_VALUEFORMATTER_HXX
+#define CONFIGMGR_XML_VALUEFORMATTER_HXX
+
+#include <com/sun/star/script/XTypeConverter.hpp>
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace script= ::com::sun::star::script;
+// -----------------------------------------------------------------------------
+ class ElementFormatter;
+// -----------------------------------------------------------------------------
+
+ // Value to XML (String) conversions
+ class ValueFormatter
+ {
+ public:
+ explicit
+ ValueFormatter(uno::Any const & _aValue)
+ : m_aValue(_aValue)
+ {
+ makeSeparator();
+ }
+
+ void reset(uno::Any const & _aValue)
+ { m_aValue = _aValue; makeSeparator(); }
+
+ bool addValueAttributes(ElementFormatter & _rFormatter) const;
+
+ bool hasContent() const;
+
+ rtl::OUString getContent(uno::Reference< script::XTypeConverter > const & _xTCV) const;
+
+ private:
+ bool isList() const { return m_sSeparator.getLength() != 0; }
+ void makeSeparator();
+
+ uno::Any m_aValue;
+ rtl::OUString m_sSeparator;
+ bool m_bUseSeparator;
+ };
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+ }
+// -----------------------------------------------------------------------------
+} // namespace
+
+#endif
diff --git a/configmgr/source/xml/writersvc.cxx b/configmgr/source/xml/writersvc.cxx
new file mode 100644
index 000000000000..454549c00c50
--- /dev/null
+++ b/configmgr/source/xml/writersvc.cxx
@@ -0,0 +1,261 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: writersvc.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "writersvc.hxx"
+
+#ifndef CONFIGMGR_API_FACTORY_HXX_
+#include "confapifactory.hxx"
+#endif
+#include <com/sun/star/configuration/backend/XLayerHandler.hpp>
+#include <com/sun/star/lang/WrappedTargetException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace io = ::com::sun::star::io;
+ namespace sax = ::com::sun::star::xml::sax;
+ namespace backenduno = ::com::sun::star::configuration::backend;
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+struct WriterServiceTraits;
+// -----------------------------------------------------------------------------
+static inline void clear(rtl::OUString & _rs) { _rs = rtl::OUString(); }
+
+// -----------------------------------------------------------------------------
+template <class BackendInterface>
+WriterService<BackendInterface>::WriterService(uno::Reference< uno::XComponentContext > const & _xContext)
+: m_xServiceFactory(_xContext->getServiceManager(), uno::UNO_QUERY)
+, m_xWriter()
+{
+ if (!m_xServiceFactory.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration XML Writer: Context has no service manager"));
+ throw uno::RuntimeException(sMessage,NULL);
+ }
+}
+// -----------------------------------------------------------------------------
+
+// XInitialization
+template <class BackendInterface>
+void SAL_CALL
+ WriterService<BackendInterface>::initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException)
+{
+ switch(aArguments.getLength())
+ {
+ case 0:
+ {
+ break;
+ }
+
+ case 1:
+ {
+ if (aArguments[0] >>= m_xWriter)
+ break;
+
+ uno::Reference< io::XOutputStream > xStream;
+
+ if (aArguments[0] >>= xStream)
+ {
+ this->setOutputStream(xStream);
+ break;
+ }
+
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Cannot use argument to initialize a Configuration XML Writer"
+ "- SAX XDocumentHandler or XOutputStream expected"));
+ throw lang::IllegalArgumentException(sMessage,*this,1);
+ }
+ default:
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Too many arguments to initialize a Configuration Parser"));
+ throw lang::IllegalArgumentException(sMessage,*this,0);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+inline
+ServiceInfoHelper WriterService<BackendInterface>::getServiceInfo()
+{
+ return WriterServiceTraits<BackendInterface>::getServiceInfo();
+}
+// -----------------------------------------------------------------------------
+
+// XServiceInfo
+template <class BackendInterface>
+::rtl::OUString SAL_CALL
+ WriterService<BackendInterface>::getImplementationName( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getImplementationName( );
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+sal_Bool SAL_CALL
+ WriterService<BackendInterface>::supportsService( const ::rtl::OUString& ServiceName )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().supportsService( ServiceName );
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+uno::Sequence< ::rtl::OUString > SAL_CALL
+ WriterService<BackendInterface>::getSupportedServiceNames( )
+ throw (uno::RuntimeException)
+{
+ return getServiceInfo().getSupportedServiceNames( );
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+void SAL_CALL
+ WriterService<BackendInterface>::setOutputStream( const uno::Reference< io::XOutputStream >& aStream )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< io::XActiveDataSource > xDS( m_xWriter, uno::UNO_QUERY );
+
+ if (xDS.is())
+ {
+ xDS->setOutputStream(aStream);
+ }
+ else
+ {
+ uno::Reference< sax::XDocumentHandler > xNewHandler = this->createHandler();
+
+ xDS.set( xNewHandler, uno::UNO_QUERY );
+ if (!xDS.is())
+ {
+ rtl::OUString sMessage( RTL_CONSTASCII_USTRINGPARAM("Configuration XML Writer: Cannot set output stream to sax.Writer - missing interface XActiveDataSource."));
+ throw uno::RuntimeException(sMessage,*this);
+ }
+ xDS->setOutputStream(aStream);
+
+ m_xWriter = xNewHandler;
+ }
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+uno::Reference< io::XOutputStream > SAL_CALL
+ WriterService<BackendInterface>::getOutputStream( )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< io::XActiveDataSource > xDS( m_xWriter, uno::UNO_QUERY );
+
+ return xDS.is()? xDS->getOutputStream() : uno::Reference< io::XOutputStream >();
+}
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+uno::Reference< sax::XDocumentHandler > WriterService<BackendInterface>::getWriteHandler()
+ throw (uno::RuntimeException)
+{
+ if (!m_xWriter.is())
+ m_xWriter = this->createHandler();
+
+ return m_xWriter;
+}
+
+// -----------------------------------------------------------------------------
+
+template <class BackendInterface>
+uno::Reference< sax::XDocumentHandler > WriterService<BackendInterface>::createHandler() const
+ throw (uno::RuntimeException)
+{
+ try
+ {
+ static rtl::OUString const k_sSaxWriterSvc( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") );
+
+ return uno::Reference< sax::XDocumentHandler >::query( getServiceFactory()->createInstance(k_sSaxWriterSvc) );
+ }
+ catch (uno::RuntimeException& ) { throw; }
+ catch (uno::Exception& e)
+ {
+ lang::XInitialization * const pThis = const_cast<WriterService *>(this);
+ throw lang::WrappedTargetRuntimeException(e.Message, pThis, uno::makeAny(e));
+ }
+}
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+sal_Char const * const aLayerWriterServices[] =
+{
+ "com.sun.star.configuration.backend.xml.LayerWriter",
+ 0
+};
+extern // needed by SunCC 5.2, if used from template
+const ServiceImplementationInfo aLayerWriterSI =
+{
+ "com.sun.star.comp.configuration.backend.xml.LayerWriter",
+ aLayerWriterServices,
+ 0
+};
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+template <>
+struct WriterServiceTraits< backenduno::XLayerHandler >
+{
+ static ServiceImplementationInfo const * getServiceInfo()
+ { return & aLayerWriterSI; }
+};
+// -----------------------------------------------------------------------------
+
+const ServiceRegistrationInfo* getLayerWriterServiceInfo()
+{ return getRegistrationInfo(& aLayerWriterSI); }
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+// instantiate here !
+template class WriterService< backenduno::XLayerHandler >;
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+ } // namespace
+
+// -----------------------------------------------------------------------------
+} // namespace
+
diff --git a/configmgr/source/xml/writersvc.hxx b/configmgr/source/xml/writersvc.hxx
new file mode 100644
index 000000000000..a8bddb24b8cb
--- /dev/null
+++ b/configmgr/source/xml/writersvc.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: writersvc.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_XML_WRITERSVC_HXX
+#define CONFIGMGR_XML_WRITERSVC_HXX
+
+#include "serviceinfohelper.hxx"
+#include <cppuhelper/implbase4.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+
+// -----------------------------------------------------------------------------
+
+namespace com { namespace sun { namespace star { namespace configuration { namespace backend {
+ class XLayerHandler;
+} } } } }
+
+// -----------------------------------------------------------------------------
+
+namespace configmgr
+{
+// -----------------------------------------------------------------------------
+ namespace xml
+ {
+// -----------------------------------------------------------------------------
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+ namespace io = ::com::sun::star::io;
+ namespace sax = ::com::sun::star::xml::sax;
+// -----------------------------------------------------------------------------
+
+ template <class BackendInterface>
+ class WriterService : public ::cppu::WeakImplHelper4<
+ lang::XInitialization,
+ lang::XServiceInfo,
+ io::XActiveDataSource,
+ BackendInterface
+ >
+ {
+ public:
+ explicit
+ WriterService(uno::Reference< uno::XComponentContext > const & _xContext);
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::Exception, uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL
+ getImplementationName( )
+ throw (uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService( const ::rtl::OUString& ServiceName )
+ throw (uno::RuntimeException);
+
+ virtual uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames( )
+ throw (uno::RuntimeException);
+
+ // XActiveDataSink
+ virtual void SAL_CALL
+ setOutputStream( const uno::Reference< io::XOutputStream >& aStream )
+ throw (uno::RuntimeException);
+
+ virtual uno::Reference< io::XOutputStream > SAL_CALL
+ getOutputStream( )
+ throw (uno::RuntimeException);
+
+ protected:
+ uno::Reference< lang::XMultiServiceFactory > getServiceFactory() const
+ { return m_xServiceFactory; }
+
+ uno::Reference< sax::XDocumentHandler > getWriteHandler() throw (uno::RuntimeException);
+ private:
+ uno::Reference< lang::XMultiServiceFactory > m_xServiceFactory;
+ uno::Reference< sax::XDocumentHandler > m_xWriter;
+
+ uno::Reference< sax::XDocumentHandler > createHandler() const throw (uno::RuntimeException);
+
+ static ServiceInfoHelper getServiceInfo();
+ };
+
+// -----------------------------------------------------------------------------
+ } // namespace xml
+// -----------------------------------------------------------------------------
+
+} // namespace configmgr
+#endif
+
+
+
+
diff --git a/configmgr/source/xml/xmlstrings.cxx b/configmgr/source/xml/xmlstrings.cxx
new file mode 100644
index 000000000000..06b223300659
--- /dev/null
+++ b/configmgr/source/xml/xmlstrings.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmlstrings.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "xmlstrings.hxx"
+
+//.........................................................................
+namespace configmgr
+{
+//.........................................................................
+
+ namespace xml
+ {
+//----------------------------------------------------------------------------
+// For now: Include the fixed OOR prefix into (most) attribute names
+#define OOR_PREFIX_ "oor:"
+// ... but not into (most) tag names
+#define OOR_TAG_PREFIX_
+// ... but into root tag names
+#define OOR_ROOTTAG_PREFIX_ OOR_PREFIX_
+//----------------------------------------------------------------------------
+ // extern declaration for strings used in the XML format
+ // namespace prefixes
+ IMPLEMENT_CONSTASCII_USTRING(NS_PREFIX_OOR, "oor");
+ IMPLEMENT_CONSTASCII_USTRING(NS_PREFIX_XS, "xs");
+
+ // namespace urls
+ IMPLEMENT_CONSTASCII_USTRING(NS_URI_OOR,"http://openoffice.org/2001/registry");
+ IMPLEMENT_CONSTASCII_USTRING(NS_URI_XS, "http://www.w3.org/2001/XMLSchema");
+
+ // tag names
+ IMPLEMENT_CONSTASCII_USTRING(TAG_SCHEMA, OOR_ROOTTAG_PREFIX_"component-schema");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_LAYER, OOR_ROOTTAG_PREFIX_"component-data");
+ IMPLEMENT_CONSTASCII_USTRING(DEPRECATED_TAG_LAYER, OOR_ROOTTAG_PREFIX_"node");
+
+ IMPLEMENT_CONSTASCII_USTRING(TAG_COMPONENT, OOR_TAG_PREFIX_"component");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_TEMPLATES, OOR_TAG_PREFIX_"templates");
+
+ IMPLEMENT_CONSTASCII_USTRING(TAG_NODE, OOR_TAG_PREFIX_"node");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_GROUP, OOR_TAG_PREFIX_"group");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_SET, OOR_TAG_PREFIX_"set");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_PROP, OOR_TAG_PREFIX_"prop");
+
+ IMPLEMENT_CONSTASCII_USTRING(TAG_VALUE, OOR_TAG_PREFIX_"value");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_IMPORT, OOR_TAG_PREFIX_"import");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_INSTANCE, OOR_TAG_PREFIX_"node-ref");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_ITEMTYPE, OOR_TAG_PREFIX_"item");
+ IMPLEMENT_CONSTASCII_USTRING(TAG_USES, OOR_TAG_PREFIX_"uses");
+
+ // attribute names
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_NAME, OOR_PREFIX_"name");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_CONTEXT, OOR_PREFIX_"context");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_PACKAGE, OOR_PREFIX_"package");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_COMPONENT,OOR_PREFIX_"component");
+
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_ITEMTYPE, OOR_PREFIX_"node-type");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_ITEMTYPECOMPONENT,OOR_PREFIX_"component");
+
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_VALUETYPE, OOR_PREFIX_"type");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_VALUESEPARATOR, OOR_PREFIX_"separator");
+
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_FLAG_EXTENSIBLE, OOR_PREFIX_"extensible");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_FLAG_FINALIZED, OOR_PREFIX_"finalized");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_FLAG_READONLY, OOR_PREFIX_"readonly");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_FLAG_MANDATORY, OOR_PREFIX_"mandatory");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_FLAG_NULLABLE, OOR_PREFIX_"nillable");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_FLAG_LOCALIZED, OOR_PREFIX_"localized");
+
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_OPERATION, OOR_PREFIX_"op");
+
+ // attributes defined elsewhere
+ IMPLEMENT_CONSTASCII_USTRING(EXT_ATTR_LANGUAGE, "xml:lang");
+ IMPLEMENT_CONSTASCII_USTRING(EXT_ATTR_NULL, "xsi:nil");
+
+ // attribute contents
+ // boolean constants
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_VALUE_TRUE, "true");
+ IMPLEMENT_CONSTASCII_USTRING(ATTR_VALUE_FALSE, "false");
+
+ // simple types names
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_BOOLEAN, "boolean");
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_SHORT, "short");
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_INT, "int");
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_LONG, "long");
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_DOUBLE, "double");
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_STRING, "string");
+ // Type: Sequence<bytes>
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_BINARY, "hexBinary");
+ // Universal type: Any
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_ANY, "any");
+
+ // modifier suffix for list types
+ IMPLEMENT_CONSTASCII_USTRING(VALUETYPE_LIST_SUFFIX, "-list");
+
+ // States for update actions
+ IMPLEMENT_CONSTASCII_USTRING(OPERATION_MODIFY, "modify");
+ IMPLEMENT_CONSTASCII_USTRING(OPERATION_REPLACE, "replace");
+ IMPLEMENT_CONSTASCII_USTRING(OPERATION_FUSE, "fuse");
+ IMPLEMENT_CONSTASCII_USTRING(OPERATION_REMOVE, "remove");
+
+ // the default separator for strings
+ IMPLEMENT_CONSTASCII_USTRING(SEPARATOR_WHITESPACE, " ");
+
+ // Needed for building attribute lists
+ IMPLEMENT_CONSTASCII_USTRING(XML_ATTRTYPE_CDATA, "CDATA");
+
+ } // namespace xml
+
+} // namespace configmgr
+
+
diff --git a/configmgr/source/xml/xmlstrings.hxx b/configmgr/source/xml/xmlstrings.hxx
new file mode 100644
index 000000000000..a81d31e3fede
--- /dev/null
+++ b/configmgr/source/xml/xmlstrings.hxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmlstrings.hxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef CONFIGMGR_XML_STRINGS_HXX_
+#define CONFIGMGR_XML_STRINGS_HXX_
+
+#include "strings.hxx"
+
+//.........................................................................
+namespace configmgr
+{
+//.........................................................................
+
+ namespace xml
+ {
+ // extern declaration for strings used in the XML format
+ // namespace prefixes
+ DECLARE_CONSTASCII_USTRING(NS_PREFIX_OOR);
+ DECLARE_CONSTASCII_USTRING(NS_PREFIX_XS);
+
+ const sal_Unicode k_NS_SEPARATOR(':');
+
+ // namespace urls
+ DECLARE_CONSTASCII_USTRING(NS_URI_OOR);
+ DECLARE_CONSTASCII_USTRING(NS_URI_XS);
+ DECLARE_CONSTASCII_USTRING(NS_URI_XSI);
+
+ // tag names
+ DECLARE_CONSTASCII_USTRING(TAG_SCHEMA);
+ DECLARE_CONSTASCII_USTRING(TAG_LAYER);
+ DECLARE_CONSTASCII_USTRING(DEPRECATED_TAG_LAYER);
+
+ DECLARE_CONSTASCII_USTRING(TAG_COMPONENT);
+ DECLARE_CONSTASCII_USTRING(TAG_TEMPLATES);
+
+ DECLARE_CONSTASCII_USTRING(TAG_NODE);
+ DECLARE_CONSTASCII_USTRING(TAG_GROUP);
+ DECLARE_CONSTASCII_USTRING(TAG_SET);
+ DECLARE_CONSTASCII_USTRING(TAG_PROP);
+
+ DECLARE_CONSTASCII_USTRING(TAG_IMPORT);
+ DECLARE_CONSTASCII_USTRING(TAG_INSTANCE);
+ DECLARE_CONSTASCII_USTRING(TAG_ITEMTYPE);
+ DECLARE_CONSTASCII_USTRING(TAG_VALUE);
+ DECLARE_CONSTASCII_USTRING(TAG_USES);
+
+ // attribute names
+ DECLARE_CONSTASCII_USTRING(ATTR_NAME);
+ DECLARE_CONSTASCII_USTRING(ATTR_CONTEXT);
+ DECLARE_CONSTASCII_USTRING(ATTR_PACKAGE);
+ DECLARE_CONSTASCII_USTRING(ATTR_COMPONENT);
+
+ DECLARE_CONSTASCII_USTRING(ATTR_ITEMTYPE);
+ DECLARE_CONSTASCII_USTRING(ATTR_ITEMTYPECOMPONENT);
+
+ DECLARE_CONSTASCII_USTRING(ATTR_VALUETYPE);
+ DECLARE_CONSTASCII_USTRING(ATTR_VALUESEPARATOR);
+
+ DECLARE_CONSTASCII_USTRING(ATTR_FLAG_EXTENSIBLE);
+ DECLARE_CONSTASCII_USTRING(ATTR_FLAG_FINALIZED);
+ DECLARE_CONSTASCII_USTRING(ATTR_FLAG_READONLY);
+ DECLARE_CONSTASCII_USTRING(ATTR_FLAG_MANDATORY);
+ DECLARE_CONSTASCII_USTRING(ATTR_FLAG_NULLABLE);
+ DECLARE_CONSTASCII_USTRING(ATTR_FLAG_LOCALIZED);
+
+ DECLARE_CONSTASCII_USTRING(ATTR_OPERATION);
+
+ // attributes defined elsewhere
+ DECLARE_CONSTASCII_USTRING(EXT_ATTR_LANGUAGE);
+ DECLARE_CONSTASCII_USTRING(EXT_ATTR_NULL);
+
+ // attribute contents
+ // boolean constants
+ DECLARE_CONSTASCII_USTRING(ATTR_VALUE_TRUE);
+ DECLARE_CONSTASCII_USTRING(ATTR_VALUE_FALSE);
+
+ // simple types names
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_BOOLEAN);
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_SHORT);
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_INT);
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_LONG);
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_DOUBLE);
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_STRING);
+ // Type: Sequence<bytes>
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_BINARY);
+ // Universal type: Any
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_ANY);
+
+ // modifier suffix for list types
+ DECLARE_CONSTASCII_USTRING(VALUETYPE_LIST_SUFFIX);
+
+ // States for update actions
+ DECLARE_CONSTASCII_USTRING(OPERATION_MODIFY);
+ DECLARE_CONSTASCII_USTRING(OPERATION_REPLACE);
+ DECLARE_CONSTASCII_USTRING(OPERATION_FUSE);
+ DECLARE_CONSTASCII_USTRING(OPERATION_REMOVE);
+
+ // the default separator for strings
+ DECLARE_CONSTASCII_USTRING(SEPARATOR_WHITESPACE);
+
+ // Needed for building attribute lists
+ DECLARE_CONSTASCII_USTRING(XML_ATTRTYPE_CDATA);
+
+ } // namespace xml
+
+} // namespace configmgr
+#endif
+
diff --git a/configmgr/util/cfgmgr.mxp.map b/configmgr/util/cfgmgr.mxp.map
new file mode 100644
index 000000000000..2bf8e6c7f991
--- /dev/null
+++ b/configmgr/util/cfgmgr.mxp.map
@@ -0,0 +1,4 @@
+# Global symbols
+_component_getImplementationEnvironment
+_component_writeInfo
+_component_getFactory
diff --git a/configmgr/util/configmgr.map b/configmgr/util/configmgr.map
new file mode 100644
index 000000000000..ad92fbe03e9f
--- /dev/null
+++ b/configmgr/util/configmgr.map
@@ -0,0 +1,8 @@
+CFGMGR_2_0 {
+ global:
+ component_getImplementationEnvironment;
+ component_writeInfo;
+ component_getFactory;
+ local:
+ *;
+};
diff --git a/configmgr/util/configmgr2.uno.xml b/configmgr/util/configmgr2.uno.xml
new file mode 100644
index 000000000000..8a7ac13f3114
--- /dev/null
+++ b/configmgr/util/configmgr2.uno.xml
@@ -0,0 +1,582 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name>configmgr2</module-name>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.ConfigurationProvider</name>
+ <description>
+The configuration service provides access to a hierarchical database of configuration and preference data.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationProvider </supported-service>
+ <service-dependency> com.sun.star.script.Converter </service-dependency>
+ <service-dependency> com.sun.star.io.DataOutputStream </service-dependency>
+ <type> com.sun.star.configuration.MissingBootstrapFileException </type>
+ <type> com.sun.star.configuration.InvalidBootstrapFileException </type>
+ <type> com.sun.star.configuration.InstallationIncompleteException </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.NamedValue </type>
+ <type> com.sun.star.lang.Locale </type>
+ <type> com.sun.star.lang.XUnoTunnel </type>
+ <type> com.sun.star.lang.ServiceNotRegisteredException </type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.script.XTypeConverter </type>
+ <type> com.sun.star.util.XCancellable </type>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.AdministrationProvider</name>
+ <description>
+The configuration service provides access to a hierarchical database of configuration and preference data.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.AdministrationProvider </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationProvider </supported-service>
+ <service-dependency> com.sun.star.configuration.ConfigurationUpdateAccess </service-dependency>
+ <service-dependency> com.sun.star.configuration.ConfigurationAccess </service-dependency>
+ <service-dependency> com.sun.star.script.Converter </service-dependency>
+ <type> com.sun.star.configuration.MissingBootstrapFileException </type>
+ <type> com.sun.star.configuration.InvalidBootstrapFileException </type>
+ <type> com.sun.star.configuration.InstallationIncompleteException </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.beans.NamedValue </type>
+ <type> com.sun.star.lang.Locale </type>
+ <type> com.sun.star.lang.XUnoTunnel </type>
+ <type> com.sun.star.lang.ServiceNotRegisteredException </type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.script.XTypeConverter </type>
+ <type> com.sun.star.util.XCancellable </type>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.ConfigurationProviderWrapper</name>
+ <description>
+Is a configuration provider that forwards its requests to a DefaultProvider.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationProvider </supported-service>
+ <service-dependency> com.sun.star.configuration.DefaultProvider </service-dependency>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.ORootElementGroupInfoAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupAccess </supported-service>
+ <supported-service> com.sun.star.configuration.PropertyHierarchy </supported-service>
+ <supported-service> com.sun.star.configuration.AccessRootElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.ORootElementGroupUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.GroupAccess </supported-service>
+ <supported-service> com.sun.star.configuration.PropertyHierarchy </supported-service>
+ <supported-service> com.sun.star.configuration.UpdateRootElement </supported-service>
+ <supported-service> com.sun.star.configuration.AccessRootElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.ORootElementSetInfoAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.AccessRootElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.ORootElementTreeSetUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.UpdateRootElement </supported-service>
+ <supported-service> com.sun.star.configuration.AccessRootElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.ORootElementValueSetUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.UpdateRootElement </supported-service>
+ <supported-service> com.sun.star.configuration.AccessRootElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OSetElementGroupInfoAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupAccess </supported-service>
+ <supported-service> com.sun.star.configuration.PropertyHierarchy </supported-service>
+ <supported-service> com.sun.star.configuration.SetElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OSetElementGroupUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.GroupAccess </supported-service>
+ <supported-service> com.sun.star.configuration.PropertyHierarchy </supported-service>
+ <supported-service> com.sun.star.configuration.SetElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OSetElementSetInfoAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OSetElementTreeSetUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OSetElementValueSetUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OInnerGroupInfoAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupAccess </supported-service>
+ <supported-service> com.sun.star.configuration.PropertyHierarchy </supported-service>
+ <supported-service> com.sun.star.configuration.GroupElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OInnerGroupUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.GroupAccess </supported-service>
+ <supported-service> com.sun.star.configuration.PropertyHierarchy </supported-service>
+ <supported-service> com.sun.star.configuration.GroupElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OInnerSetInfoAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OInnerTreeSetUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.OInnerValueSetUpdateAccess</name>
+ <description>
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.ConfigurationUpdateAccess </supported-service>
+ <supported-service> com.sun.star.configuration.ConfigurationAccess </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetUpdate </supported-service>
+ <supported-service> com.sun.star.configuration.SimpleSetAccess </supported-service>
+ <supported-service> com.sun.star.configuration.GroupElement </supported-service>
+ <supported-service> com.sun.star.configuration.HierarchyElement </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.bootstrap.BootstrapContext</name>
+ <description>Context containing configuration bootstrap data merged with environment settings.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.bootstrap.BootstrapContext </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.SingleBackendAdapter</name>
+ <description>Backend using a SingleBackend for data access.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.SingleBackendAdapter </supported-service>
+ <supported-service> com.sun.star.configuration.backend.OnlineBackend </supported-service>
+ <supported-service> com.sun.star.configuration.backend.Backend </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.LayerUpdateMerger</name>
+ <description>Merges updates into layer data.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.LayerUpdateMerger </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.MergeImporter</name>
+ <description>Importer for layer data.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.MergeImporter </supported-service>
+ <supported-service> com.sun.star.configuration.backend.Importer </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.CopyImporter</name>
+ <description>Importer for layer data.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.CopyImporter </supported-service>
+ <supported-service> com.sun.star.configuration.backend.Importer </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.xml.SchemaParser</name>
+ <description>Parser for OOR Schema XML.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.xml.SchemaParser </supported-service>
+ <service-dependency> com.sun.star.xml.sax.Parser </service-dependency>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.xml.LayerParser</name>
+ <description>Parser for OOR Layer/Update XML.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.xml.LayerParser </supported-service>
+ <service-dependency> com.sun.star.xml.sax.Parser </service-dependency>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.xml.LayerWriter</name>
+ <description>Service for writing layer data to the OOR Layer/Update XML format.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.xml.LayerWriter </supported-service>
+ <service-dependency> com.sun.star.xml.sax.Writer </service-dependency>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.LocalSingleBackend</name>
+ <description>SingleBackend for accessing locally stored configuration data.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.LocalSingleBackend </supported-service>
+ <supported-service> com.sun.star.configuration.backend.SingleBackend </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.LocalDataImporter</name>
+ <description>Component for importing layer data from local files.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.LocalDataImporter </supported-service>
+ <supported-service> com.sun.star.configuration.backend.DataImporter </supported-service>
+ </component-description>
+ <component-description>
+ <author>Joerg Barfurth</author>
+ <name> com.sun.star.comp.configuration.backend.LocalHierarchyBrowser</name>
+ <description>Component for retrieving available componets from a local configuration data repository.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.LocalHierarchyBrowser </supported-service>
+ <supported-service> com.sun.star.configuration.backend.HierarchyBrowser </supported-service>
+ </component-description>
+ <component-description>
+ <author>Sarah Smith</author>
+ <name> com.sun.star.comp.configuration.backend.LocalSchemaSupplier</name>
+ <description>Component for accessing locally stored schema files</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.LocalSchemaSupplier </supported-service>
+ <supported-service> com.sun.star.configuration.backend.SchemaSupplier </supported-service>
+ </component-description>
+ <component-description>
+ <author>Sarah Smith</author>
+ <name> com.sun.star.comp.configuration.backend.LocalSingleStratum</name>
+ <description>Component for accessing locally stored configuration data</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.LocalSingleStratum </supported-service>
+ <supported-service> com.sun.star.configuration.backend.SingleLayerStratum </supported-service>
+ </component-description>
+ <component-description>
+ <author>Sarah Smith</author>
+ <name> com.sun.star.comp.configuration.backend.MultiStratumBackend</name>
+ <description>Component for co-ordinating access to multiple storage backends</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.configuration.backend.MultiStratumBackend </supported-service>
+ <supported-service> com.sun.star.configuration.backend.Backend </supported-service>
+ </component-description>
+ <component-description>
+ <author>Frank Schoenheit</author>
+ <name> com.sun.star.comp.configuration.OConfigurationRegistry</name>
+ <description>
+The configuration registry service is an adapter, that provides a SimpleRegistry interface to the configuration service.</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service>com.sun.star.configuration.ConfigurationRegistry</supported-service>
+ <supported-service>com.sun.star.registry.SimpleRegistry</supported-service>
+ <service-dependency>com.sun.star.configuration.ConfigurationProvider</service-dependency>
+ <type>com.sun.star.registry.XRegistryKey</type>
+ <type>com.sun.star.registry.XSimpleRegistry</type>
+ <type> com.sun.star.lang.ServiceNotRegisteredException </type>
+ <type> com.sun.star.util.XFlushable </type>
+ </component-description>
+ <type>com.sun.star.uno.XAggregation</type>
+ <type>com.sun.star.uno.XCurrentContext</type>
+ <type>com.sun.star.uno.XWeak</type>
+ <type>com.sun.star.uno.TypeClass</type>
+ <type>com.sun.star.beans.XExactName</type>
+ <type>com.sun.star.beans.XHierarchicalPropertySet</type>
+ <type>com.sun.star.beans.XFastPropertySet</type>
+ <type>com.sun.star.beans.XMultiHierarchicalPropertySet</type>
+ <type>com.sun.star.beans.XMultiPropertySet</type>
+ <type>com.sun.star.beans.XProperty</type>
+ <type>com.sun.star.beans.XPropertyWithState</type>
+ <type>com.sun.star.beans.XPropertyState</type>
+ <type>com.sun.star.beans.XMultiPropertyStates</type>
+ <type>com.sun.star.beans.XPropertySet</type>
+ <type>com.sun.star.beans.PropertyValue</type>
+ <type>com.sun.star.beans.Property</type>
+ <type>com.sun.star.beans.PropertyAttribute</type>
+ <type>com.sun.star.configuration.XTemplateContainer</type>
+ <type>com.sun.star.configuration.XTemplateInstance</type>
+ <type>com.sun.star.configuration.backend.TemplateIdentifier</type>
+ <type>com.sun.star.configuration.backend.SchemaAttribute</type>
+ <type>com.sun.star.configuration.backend.NodeAttribute</type>
+ <type>com.sun.star.configuration.backend.XSchemaHandler</type>
+ <type>com.sun.star.configuration.backend.XLayerHandler</type>
+ <type>com.sun.star.configuration.backend.XUpdateHandler</type>
+ <type>com.sun.star.configuration.backend.XUpdatableLayer</type>
+ <type>com.sun.star.configuration.backend.XCompositeLayer</type>
+ <type>com.sun.star.configuration.backend.XLayerImporter</type>
+ <type>com.sun.star.configuration.backend.XBackend</type>
+ <type>com.sun.star.configuration.backend.XBackendEntities</type>
+ <type>com.sun.star.configuration.backend.XSingleLayerStratum</type>
+ <type>com.sun.star.configuration.backend.XMultiLayerStratum</type>
+ <type>com.sun.star.configuration.backend.XSchemaSupplier</type>
+ <type>com.sun.star.configuration.backend.XSchema</type>
+ <type>com.sun.star.configuration.backend.XLayer</type>
+ <type>com.sun.star.configuration.backend.MalformedDataException</type>
+ <type>com.sun.star.configuration.backend.BackendAccessException</type>
+ <type>com.sun.star.configuration.backend.BackendSetupException</type>
+ <type>com.sun.star.configuration.backend.AuthenticationFailedException</type>
+ <type>com.sun.star.configuration.backend.InvalidAuthenticationMechanismException</type>
+ <type>com.sun.star.configuration.backend.CannotConnectException</type>
+ <type>com.sun.star.configuration.backend.InsufficientAccessRightsException</type>
+ <type>com.sun.star.configuration.backend.ConnectionLostException</type>
+ <type>com.sun.star.configuration.MissingBootstrapFileException</type>
+ <type>com.sun.star.configuration.InvalidBootstrapFileException</type>
+ <type>com.sun.star.configuration.InstallationIncompleteException</type>
+ <type>com.sun.star.container.XNamed</type>
+ <type>com.sun.star.container.XHierarchicalName</type>
+ <type>com.sun.star.container.XChild</type>
+ <type>com.sun.star.container.XNameAccess</type>
+ <type>com.sun.star.container.XNameReplace</type>
+ <type>com.sun.star.container.XNameContainer</type>
+ <type>com.sun.star.container.XHierarchicalNameAccess</type>
+ <type>com.sun.star.container.XElementAccess</type>
+ <type>com.sun.star.container.XContainer</type>
+ <type>com.sun.star.container.NoSuchElementException</type>
+ <type>com.sun.star.io.XActiveDataSink</type>
+ <type>com.sun.star.io.XActiveDataSource</type>
+ <type>com.sun.star.io.XInputStream</type>
+ <type>com.sun.star.io.XOutputStream</type>
+ <type>com.sun.star.io.XDataInputStream</type>
+ <type>com.sun.star.io.XDataOutputStream</type>
+ <type>com.sun.star.io.UnexpectedEOFException</type>
+ <type>com.sun.star.io.WrongFormatException</type>
+ <type>com.sun.star.lang.XComponent</type>
+ <type>com.sun.star.lang.XEventListener</type>
+ <type>com.sun.star.lang.XInitialization</type>
+ <type>com.sun.star.lang.XLocalizable</type>
+ <type>com.sun.star.lang.XMultiComponentFactory</type>
+ <type>com.sun.star.lang.XMultiServiceFactory</type>
+ <type>com.sun.star.lang.XSingleComponentFactory</type>
+ <type>com.sun.star.lang.XSingleServiceFactory</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.lang.XUnoTunnel</type>
+ <type>com.sun.star.lang.EventObject</type>
+ <type>com.sun.star.lang.ServiceNotRegisteredException</type>
+ <type>com.sun.star.lang.IllegalArgumentException</type>
+ <type>com.sun.star.lang.WrappedTargetException</type>
+ <type>com.sun.star.lang.WrappedTargetRuntimeException</type>
+ <type>com.sun.star.lang.DisposedException</type>
+ <type>com.sun.star.script.XTypeConverter</type>
+ <type>com.sun.star.script.FailReason</type>
+ <type>com.sun.star.task.XJob</type>
+ <type>com.sun.star.util.XCancellable</type>
+ <type>com.sun.star.util.XChangesBatch</type>
+ <type>com.sun.star.util.XChangesListener</type>
+ <type>com.sun.star.util.XChangesNotifier</type>
+ <type>com.sun.star.util.XFlushable</type>
+ <type>com.sun.star.util.XStringEscape</type>
+ <type>com.sun.star.util.XTimeStamped</type>
+ <type>com.sun.star.util.Date</type>
+ <type>com.sun.star.util.Time</type>
+ <type>com.sun.star.util.DateTime</type>
+ <type>com.sun.star.xml.sax.XAttributeList</type>
+ <type>com.sun.star.xml.sax.XDocumentHandler</type>
+ <type>com.sun.star.xml.sax.XExtendedDocumentHandler</type>
+ <type>com.sun.star.xml.sax.XParser</type>
+ <type>com.sun.star.xml.sax.SAXParseException</type>
+ <project-build-dependency> comphelper </project-build-dependency>
+ <project-build-dependency> vos </project-build-dependency>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> salhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> comphelp2$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> vos2$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> salhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+</module-description>
diff --git a/configmgr/util/configmgrl.map b/configmgr/util/configmgrl.map
new file mode 100644
index 000000000000..ad92fbe03e9f
--- /dev/null
+++ b/configmgr/util/configmgrl.map
@@ -0,0 +1,8 @@
+CFGMGR_2_0 {
+ global:
+ component_getImplementationEnvironment;
+ component_writeInfo;
+ component_getFactory;
+ local:
+ *;
+};
diff --git a/configmgr/util/exports.dxp b/configmgr/util/exports.dxp
new file mode 100644
index 000000000000..9630d7e06768
--- /dev/null
+++ b/configmgr/util/exports.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
diff --git a/configmgr/util/makefile.mk b/configmgr/util/makefile.mk
new file mode 100644
index 000000000000..6fd7c63195a4
--- /dev/null
+++ b/configmgr/util/makefile.mk
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.25 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..
+PRJNAME=configmgr
+TARGET=configmgr
+
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/makefile.pmk
+.INCLUDE : $(PRJ)$/version.mk
+DLLPRE =
+
+# --- Library -----------------------------------
+
+SHL1TARGET= $(CFGMGR_TARGET)$(CFGMGR_MAJOR).uno
+SHL1VERSIONMAP= $(TARGET).map
+
+SHL1OBJS=$(SLOFILES)
+SHL1STDLIBS=\
+ $(COMPHELPERLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(VOSLIB) \
+ $(SALHELPERLIB) \
+ $(SALLIB) \
+ $(TOOLSLIB)
+
+SHL1DEPN=
+SHL1IMPLIB= i$(SHL1TARGET)
+SHL1LIBS= $(SLB)$/registry.lib \
+ $(SLB)$/treecache.lib \
+ $(SLB)$/misc.lib \
+ $(SLB)$/backend.lib \
+ $(SLB)$/localbe.lib \
+ $(SLB)$/xml.lib \
+ $(SLB)$/treemgr.lib \
+ $(SLB)$/api2.lib \
+ $(SLB)$/api.lib \
+ $(SLB)$/data.lib \
+ $(SLB)$/cm.lib
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+DEF1EXPORTFILE= exports.dxp
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/version.mk b/configmgr/version.mk
new file mode 100644
index 000000000000..d5886b08b2c6
--- /dev/null
+++ b/configmgr/version.mk
@@ -0,0 +1,50 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: version.mk,v $
+#
+# $Revision: 1.4 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+# ----------------------------CFGMGR settings------------------------------------#
+# target
+CFGMGR_TARGET=configmgr
+
+# the major
+CFGMGR_MAJOR=2
+# the minor
+CFGMGR_MINOR=0
+# the micro
+CFGMGR_MICRO=0
+
+# this is a c++ compatible library
+CFGMGR_CPP=1
+
+CFGMGR=$(CFGMGR_TARGET_TARGET)_$(CMPEXT)
+
+
+
+
diff --git a/configmgr/workben/apitest/cfgadduser.cxx b/configmgr/workben/apitest/cfgadduser.cxx
new file mode 100644
index 000000000000..f0b6e2fcddd1
--- /dev/null
+++ b/configmgr/workben/apitest/cfgadduser.cxx
@@ -0,0 +1,358 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgadduser.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <comphelper/stl_types.hxx>
+#include <cppuhelper/extract.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <cppuhelper/servicefactory.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::container;
+
+#define ASCII_STRING(rtlOUString) ::rtl::OString((rtlOUString).getStr(), (rtlOUString).getLength(), RTL_TEXTENCODING_ASCII_US).getStr()
+
+//=============================================================================
+void explain(sal_Bool _bVerbose)
+{
+ cout << "cfgadduser - adding users to a registry server\n";
+ cout << "\nusage :\n";
+ cout << "cfgadduser [-s <server> -p <port>] [-portal] [-r <registry>] [-a <sysaccount>]";
+ cout << " [-h <homedirbase>] [-pwd] <user> [<user>]*\n";
+ cout << "\nparameters\n";
+ cout << " <server> - machine where the registry server is running\n";
+ cout << " <port> - port the registry server is listening at\n";
+ cout << " <registry> - registry file to use to instantiate services. Defaulted to\n";
+ cout << " applicat.rdb\n";
+ cout << " <sysaccount> - system account to use for the newly created user(s)\n";
+ cout << " <homedirbase> - home directory base. The concret home dir of a user will\n";
+ cout << " be built by appending the the user name to the base dir.\n";
+ cout << " <user> - user name to add\n";
+ cout << " -portal - specify that the program should connect to a running portal,\n";
+ cout << " not directly to the registry server (you need a ";
+#ifdef WIN32
+ cout << "portal.dll\n";
+#else
+ cout << "libportal.so\n";
+#endif
+ cout << " for this)\n";
+ cout << " In this case, <server> and <port> specify the location where\n";
+ cout << " StarPortal is running\n";
+ cout << "\n";
+ cout << "If no server is specified, the configuration proxy will try to bootstrap from\n";
+ cout << "the initialization file (";
+#ifdef WIN32
+ cout << "sregistry.ini";
+#else
+ cout << "sregistryrc";
+#endif
+ cout << ")\n\n";
+ cout.flush();
+}
+
+//=============================================================================
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+int _cdecl main( int argc, char * argv[] )
+#endif
+{
+ sal_Char* pPort = NULL;
+ sal_Char* pServer = NULL;
+ sal_Char* pRegistry = NULL;
+ sal_Char* pSysAccount = NULL;
+ sal_Char* pHomeDirBase = NULL;
+ sal_Bool bPortal = sal_False;
+
+ ::std::vector< sal_Char* > aUsers;
+
+ // collect some parameters
+ sal_Char** pArgs = argv + 1;
+ for (sal_Int32 i=1; i<argc; ++i, ++pArgs)
+ {
+ sal_Char* pCurArg = *pArgs;
+ sal_Int32 nLen = strlen(pCurArg);
+ sal_Bool bInvalidArg = sal_True;
+ if (nLen && ('-' == *pCurArg))
+ { // it's a switch
+ sal_Char* pSwitch = pCurArg + 1;
+ switch (nLen)
+ {
+ case 2:
+ switch (*pSwitch)
+ {
+ case '?':
+ explain(sal_True);
+ return 1;
+ case 'h':
+ pHomeDirBase = *++pArgs;
+ ++i;
+ bInvalidArg = sal_False;
+ break;
+ case 'a':
+ pSysAccount = *++pArgs;
+ ++i;
+ bInvalidArg = sal_False;
+ break;
+ case 'p':
+ pPort = *++pArgs;
+ ++i;
+ bInvalidArg = sal_False;
+ break;
+ case 's':
+ pServer = *++pArgs;
+ ++i;
+ bInvalidArg = sal_False;
+ break;
+ case 'r':
+ pRegistry = *++pArgs;
+ ++i;
+ bInvalidArg = sal_False;
+ break;
+ }
+ break;
+ case 7:
+ if (0 == strncmp(pSwitch, "portal", 6))
+ {
+ bInvalidArg = sal_False;
+ bPortal = sal_True;
+ }
+ break;
+ }
+ }
+ else
+ {
+ if ((1 == nLen) && ('?' == *pCurArg))
+ {
+ explain(sal_True);
+ return 1;
+ }
+ else
+ {
+ bInvalidArg = sal_False;
+ aUsers.push_back(pCurArg);
+ }
+ }
+ if (bInvalidArg)
+ {
+ explain(sal_False);
+ return 1;
+ }
+ }
+
+ if ((!pServer && pPort) || (!pPort && pServer))
+ {
+ explain(sal_False);
+ return 1;
+ }
+
+ if (0 == aUsers.size())
+ {
+ explain(sal_False);
+ return 1;
+ }
+
+ // refine some params
+ ::rtl::OUString sHomeDirBase, sSystemAccountName;
+ if (pHomeDirBase)
+ {
+ sHomeDirBase = ::rtl::OUString::createFromAscii(pHomeDirBase);
+ if (!sHomeDirBase.getLength() || ('/' != sHomeDirBase.getStr()[sHomeDirBase.getLength() - 1]))
+ sHomeDirBase += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+ }
+ if (pSysAccount)
+ sSystemAccountName = ::rtl::OUString::createFromAscii(pSysAccount);
+
+ try
+ {
+ ::rtl::OUString const sServiceRegistry = ::rtl::OUString::createFromAscii( pRegistry ? pRegistry : "applicat.rdb" );
+ Reference< XMultiServiceFactory > xORB = ::cppu::createRegistryServiceFactory(
+ sServiceRegistry,
+ ::rtl::OUString()
+ );
+ if (!xORB.is())
+ {
+ cerr << "Could not create the service factory !\n\n";
+ return 1;
+ }
+
+ // collect the params for the config provider
+ Sequence< Any > aProviderArgs(3 + (pServer ? 2 : 0));
+ aProviderArgs[0] = makeAny(PropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("servertype")),
+ 0,
+ makeAny(::rtl::OUString::createFromAscii(bPortal ? "portal" : "remote")),
+ PropertyState_DIRECT_VALUE
+ ));
+ aProviderArgs[1] = makeAny(PropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user")),
+ 0,
+ makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Administrator"))),
+ PropertyState_DIRECT_VALUE
+ ));
+ aProviderArgs[2] = makeAny(PropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("password")),
+ 0,
+ makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unused"))),
+ PropertyState_DIRECT_VALUE
+ ));
+ if (pServer)
+ {
+ aProviderArgs[3] = makeAny(PropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("server")),
+ 0,
+ makeAny(::rtl::OUString::createFromAscii(pServer)),
+ PropertyState_DIRECT_VALUE
+ ));
+
+ sal_Int32 nPort = ::rtl::OUString::createFromAscii(pPort).toInt32();
+ aProviderArgs[4] = makeAny(PropertyValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("port")),
+ 0,
+ makeAny(nPort),
+ PropertyState_DIRECT_VALUE
+ ));
+ }
+
+ Reference< XMultiServiceFactory > xCfgProvider(
+ xORB->createInstanceWithArguments(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"),
+ aProviderArgs),
+ UNO_QUERY);
+ if (!xCfgProvider.is())
+ {
+ cerr << "Could not create the configuration provider !\n\n";
+ return 3;
+ }
+
+ Reference< XInterface > xIFace = xCfgProvider->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.configuration.UserAdministration"));
+ if (!xIFace.is())
+ {
+ cerr << "Could not create the configuration provider !\n\n";
+ return 4;
+ }
+
+ Reference< XChangesBatch > xUserChanges(xIFace, UNO_QUERY);
+ Reference< XNameContainer > xUserContainer(xIFace, UNO_QUERY);
+ Reference< XSingleServiceFactory> xUserFactory(xIFace, UNO_QUERY);
+ if (!xUserChanges.is() || !xUserContainer.is() || !xUserFactory.is())
+ {
+ cerr << "the user admin access does not provide the necessary interfaces !\n\n";
+ return 5;
+ }
+
+ cout << "going to add the users ..." << endl << endl;
+ for ( ::std::vector< sal_Char* >::const_iterator aUserLoop = aUsers.begin();
+ aUserLoop != aUsers.end();
+ ++aUserLoop
+ )
+ {
+ cout << *aUserLoop << " ... ";
+ sal_Bool bHadLinebreak = sal_False;
+ try
+ {
+ Reference< XInterface > xNewUser = xUserFactory->createInstance();
+
+ // the user name as unicode string use more than once)
+ ::rtl::OUString sUserName = ::rtl::OUString::createFromAscii(*aUserLoop);
+
+ // the XNameContainer access to the Security node in the user profile data
+ Reference< XNameReplace > xSecurityDataAccess;
+ Reference< XNameAccess > xUserDataAccess(xNewUser, UNO_QUERY);
+ if (xUserDataAccess.is())
+ {
+ Any aSecurity = xUserDataAccess->getByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Security")));
+ ::cppu::extractInterface(xSecurityDataAccess, aSecurity);
+ }
+
+ if (!xSecurityDataAccess.is())
+ throw Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("The user administration service did not provide a valid user template.")), NULL);
+
+ // set the home directory
+ if (sHomeDirBase.getLength())
+ {
+ ::rtl::OUString sHomeDir(sHomeDirBase);
+ sHomeDir += sUserName;
+ xSecurityDataAccess->replaceByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HomeDirectory")), makeAny(sHomeDir));
+ cout << "\n\thome dir : " << ASCII_STRING(sHomeDir) << " ... ";
+ cout.flush();
+ bHadLinebreak = sal_True;
+ }
+
+ if (sSystemAccountName.getLength())
+ {
+ xSecurityDataAccess->replaceByName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SystemAccount")), makeAny(sSystemAccountName));
+ cout << "\n\tsystem account: " << ASCII_STRING(sSystemAccountName) << " ... ";
+ cout.flush();
+ bHadLinebreak = sal_True;
+ }
+
+ xUserContainer->insertByName(sUserName, makeAny(xNewUser));
+ xUserChanges->commitChanges();
+ if (bHadLinebreak)
+ cout << "\n";
+ cout << "done.\n";
+ cout.flush();
+ }
+ catch(Exception& e)
+ {
+ cout << "\n";
+ if (!bHadLinebreak)
+ cout << "\t";
+ cerr << "unable to add the user named " << *aUserLoop << endl;
+ if (!bHadLinebreak)
+ cout << "\t";
+ cerr << "(exception message: " << ::rtl::OString(e.Message.getStr(), e.Message.getLength(), RTL_TEXTENCODING_ASCII_US).getStr() << ")" << endl;
+ }
+ cout << "\n";
+ }
+ }
+ catch(Exception& e)
+ {
+ cerr << "Caught exception: " << ASCII_STRING(e.Message) << endl;
+ return 2;
+ }
+
+ return 0;
+}
diff --git a/configmgr/workben/apitest/cfgadmin.cxx b/configmgr/workben/apitest/cfgadmin.cxx
new file mode 100644
index 000000000000..791686378c9a
--- /dev/null
+++ b/configmgr/workben/apitest/cfgadmin.cxx
@@ -0,0 +1,520 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgadmin.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#define _PRIVATE_TEST_
+
+#include <iostream>
+using namespace std;
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+#include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
+
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Any.h>
+
+#include "createpropertyvalue.hxx"
+
+#include "typeconverter.hxx"
+#include <osl/time.h>
+
+// #include <com/sun/star/configuration/XConfigurationSync.hpp>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+//using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+using ::rtl::OString;
+//using namespace ::configmgr;
+
+using namespace ::cppu;
+
+#define ASCII(x) ::rtl::OUString::createFromAscii(x)
+
+ostream& operator << (ostream& out, rtl::OUString const& aStr)
+{
+ sal_Unicode const* const pStr = aStr.getStr();
+ sal_Unicode const* const pEnd = pStr + aStr.getLength();
+ for (sal_Unicode const* p = pStr; p < pEnd; ++p)
+ if (0 < *p && *p < 127) // ASCII
+ out << char(*p);
+ else
+ out << "[\\u" << hex << *p << "]";
+ return out;
+}
+
+void showSequence(const Sequence<OUString> &aSeq)
+{
+ OUString aArray;
+ const OUString *pStr = aSeq.getConstArray();
+ for (int i=0;i<aSeq.getLength();i++)
+ {
+ OUString aStr = pStr[i];
+ // aArray += aStr + ASCII(", ");
+ cout << aStr << endl;
+ }
+ volatile int dummy = 0;
+}
+
+//=============================================================================
+//=============================================================================
+void test_read_access(Reference< XInterface >& xIface, Reference< XMultiServiceFactory > &xMSF);
+//=============================================================================
+struct prompt_and_wait
+{
+ char const* myText;
+ prompt_and_wait(char const* text = "") : myText(text) {}
+ ~prompt_and_wait()
+ {
+ cout << myText << ">" << endl;
+ int const mx = int( (+0u - +1u) >> 1);
+
+ char c=0;
+ if (cin.get(c) && c != '\n')
+ cin.ignore(mx,'\n');
+ }
+};
+static prompt_and_wait exit_prompt("Quitting\nQ");
+
+
+// -----------------------------------------------------------------------------
+Sequence<Any> createSequence(const OUString &sUser, const OUString &sPasswd)
+{
+ Sequence< Any > aCPArgs;
+
+ if (sUser.getLength() > 0)
+ {
+ aCPArgs.realloc(1);
+ aCPArgs[0] <<= configmgr::createPropertyValue(ASCII("user"), sUser);
+ }
+ if (sPasswd.getLength() > 0)
+ {
+ aCPArgs.realloc(2);
+ aCPArgs[1] <<= configmgr::createPropertyValue(ASCII("password"), sPasswd);
+ }
+ return aCPArgs;
+}
+
+//=============================================================================
+#include <string.h>
+#if (defined UNX) || (defined OS2)
+#else
+#include <conio.h>
+#endif
+
+OString input(const char* pDefaultText, char cEcho)
+{
+ // PRE: a Default Text would be shown, cEcho is a Value which will show if a key is pressed.
+ const int MAX_INPUT_LEN = 500;
+ char aBuffer[MAX_INPUT_LEN];
+
+ strcpy(aBuffer, pDefaultText);
+ int nLen = strlen(aBuffer);
+
+#ifdef WNT
+ char ch = '\0';
+
+ cout << aBuffer;
+ cout.flush();
+
+ while(ch != 13)
+ {
+ ch = getch();
+ if (ch == 8)
+ {
+ if (nLen > 0)
+ {
+ cout << "\b \b";
+ cout.flush();
+ --nLen;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ cout << "\a";
+ cout.flush();
+ }
+ }
+ else if (ch != 13)
+ {
+ if (nLen < MAX_INPUT_LEN)
+ {
+ if (cEcho == 0)
+ {
+ cout << ch;
+ }
+ else
+ {
+ cout << cEcho;
+ }
+ cout.flush();
+ aBuffer[nLen++] = ch;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ cout << "\a";
+ cout.flush();
+ }
+ }
+ }
+#else
+ if (!cin.getline(aBuffer,sizeof aBuffer))
+ return OString();
+#endif
+ return OString(aBuffer);
+}
+
+// -----------------------------------------------------------------------------
+rtl::OUString enterValue(const char* _aStr, const char* _aDefault, bool _bIsAPassword)
+{
+ cout << _aStr;
+ cout.flush();
+ OString aTxt = input(_aDefault, _bIsAPassword ? '*' : 0);
+
+ OUString sValue = OUString::createFromAscii(aTxt);
+ return sValue;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+void write(Reference<XNameAccess >& xAccess)
+{
+ if (xAccess.is())
+ {
+ Sequence<OUString> aNames( xAccess->getElementNames() );
+
+ cout << "Element Names: (" << aNames.getLength() << ")";
+ for (int i = 0; i < aNames.getLength(); ++i)
+ cout << "\n[" << i << "] -\t" << aNames[i];
+ cout << endl;
+ }
+ else
+ cout << "BUG: XNameAccess not available";
+ cout << endl;
+}
+// -----------------------------------------------------------------------------
+void write(Reference< XChild >& xChild)
+{
+ if (xChild.is())
+ cout << "\n[ P ] -\tParent";
+ else
+ cout << "BUG: Parent not available (no XChild)";
+ cout << endl;
+}
+
+// -----------------------------------------------------------------------------
+void displayTree(Reference< XNameAccess > xIFace){
+
+ write(Reference< XNameAccess >(xIFace));
+}
+
+
+// -----------------------------------------------------------------------------
+void displayGroups(Reference< XNameAccess > xGroupAccess)
+{
+
+ cout << "Currently available groups !\n---------------------------------------------------------------" << endl;
+ write(xGroupAccess);
+}
+
+// -----------------------------------------------------------------------------
+OUString insertGroup(Reference< XNameAccess > xGroupAccess)
+{
+ OUString sGroup = enterValue(" Enter a new group to create: ", "", true);
+
+ Reference< XSingleServiceFactory > xFactory(xGroupAccess, UNO_QUERY);
+ Reference< XNameAccess > xNewGroup(xFactory->createInstance(), UNO_QUERY);
+
+ cout << "Group data: !\n---------------------------------------------------------------" << endl;
+ write(xNewGroup);
+ Any aGroup;
+ aGroup <<= xNewGroup;
+ Reference< XNameContainer >(xGroupAccess, UNO_QUERY)->insertByName(sGroup, aGroup);
+ return sGroup;
+}
+
+// -----------------------------------------------------------------------------
+void deleteGroup(Reference< XNameAccess > xGroupAccess, OUString sGroup)
+{
+ if (!sGroup.getLength())
+ sGroup = enterValue(" Enter a group to delete: ", "", true);
+ cout << "deleting group !\n---------------------------------------------------------------" << endl;
+ Reference< XNameContainer >(xGroupAccess, UNO_QUERY)->removeByName(sGroup);
+}
+
+// -----------------------------------------------------------------------------
+void displayUsers(Reference< XNameAccess > xUserAccess)
+{
+ cout << "Currently available users !\n---------------------------------------------------------------" << endl;
+ write(xUserAccess);
+}
+
+// -----------------------------------------------------------------------------
+OUString insertUser(Reference< XNameAccess > xUserAccess, OUString aGroup)
+{
+ OUString sUser = enterValue(" Enter a new User to create: ", "", true);
+ Reference< XSingleServiceFactory > xFactory(xUserAccess, UNO_QUERY);
+
+ Sequence< Any > aArgs(1);
+ aArgs[0] <<= configmgr::createPropertyValue(ASCII("group"), aGroup);
+ Reference< XNameAccess > xNewUser(xFactory->createInstanceWithArguments(aArgs), UNO_QUERY);
+
+ cout << "User data: !\n---------------------------------------------------------------" << endl;
+ write(xNewUser);
+
+ Any aValue;
+ aValue <<= ASCII("MyCompany");
+
+ // now do some updates for the user
+ Reference< XHierarchicalPropertySet > xUpdate(xNewUser, UNO_QUERY);
+ xUpdate->setHierarchicalPropertyValue(ASCII("Data/Company"),aValue);
+
+ Any aUser;
+ aUser <<= xNewUser;
+ Reference< XNameContainer >(xUserAccess, UNO_QUERY)->insertByName(sUser, aUser);
+
+ return sUser;
+}
+
+// -----------------------------------------------------------------------------
+void deleteUser(Reference< XNameAccess > xUserAccess, OUString sUser)
+{
+ if (!sUser.getLength())
+ sUser = enterValue(" Enter a User to delete: ", "", true);
+ cout << "deleting User !\n---------------------------------------------------------------" << endl;
+ Reference< XNameContainer >(xUserAccess, UNO_QUERY)->removeByName(sUser);
+}
+
+// -----------------------------------------------------------------------------
+Reference< XNameAccess > beginChanges(Reference< XMultiServiceFactory > xFactory, OUString sPath, OUString& sUser)
+{
+ if (!sUser.getLength())
+ sUser = enterValue(" Enter a User: ", "", true);
+
+ Sequence< Any > aArgs(2);
+ aArgs[0] <<= configmgr::createPropertyValue(ASCII("user"), sUser);
+ aArgs[1] <<= configmgr::createPropertyValue(ASCII("nodepath"),sPath);
+
+ cout << "starting update for node:" << sPath << endl;
+
+ Reference< XNameAccess > xTree(xFactory->createInstanceWithArguments(OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"),
+ aArgs), UNO_QUERY);
+
+ return xTree;
+}
+
+template <class Type>
+// -----------------------------------------------------------------------------
+void update(Reference< XInterface > xIFace, OUString sRelPath, Type sValue)
+{
+ Reference< XHierarchicalPropertySet > xTree(xIFace, UNO_QUERY);
+ Any aValue;
+ aValue <<= sValue;
+
+ cout << "updating node:" << sRelPath << endl;
+ xTree->setHierarchicalPropertyValue(sRelPath, aValue);
+}
+
+// -----------------------------------------------------------------------------
+Reference< XHierarchicalPropertySet > insertTree(Reference< XInterface > xIFace, OUString aName)
+{
+ if (!aName.getLength())
+ aName = enterValue("/nEnter a Tree to insert: ", "", false);
+
+ Reference< XSingleServiceFactory > xFactory(xIFace, UNO_QUERY);
+ Reference< XHierarchicalPropertySet > xNewElement(xFactory->createInstance(), UNO_QUERY);
+
+ cout << "inserting new tree element:" << aName << endl;
+
+ Any aTree;
+ aTree <<= xNewElement;
+ Reference< XNameContainer >(xFactory, UNO_QUERY)->insertByName(aName, aTree);
+
+ return xNewElement;
+}
+
+// -----------------------------------------------------------------------------
+void removeTree(Reference< XInterface > xIFace, OUString aName)
+{
+ if (!aName.getLength())
+ aName = enterValue("/nEnter a Tree to remove: ", "", false);
+
+ cout << "removing new tree element:" << aName << endl;
+
+ Reference< XNameContainer >(xIFace, UNO_QUERY)->removeByName(aName);
+}
+
+// -----------------------------------------------------------------------------
+void commitChanges(Reference< XInterface > xIFace)
+{
+ cout << "committing changes:" << endl;
+
+ Reference< XChangesBatch > xChangesBatch(xIFace, UNO_QUERY);
+ xChangesBatch->commitChanges();
+}
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- M A I N ----------------------------------
+// -----------------------------------------------------------------------------
+
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+int _cdecl main( int argc, char * argv[] )
+#endif
+{
+ TimeValue aTimeout;
+ aTimeout.Seconds = 5;
+ aTimeout.Nanosec = 0;
+
+ // cout << " Please insert Text: ";
+ // cout.flush();
+ // OString aTxt = input("Der Text", 0);
+ // cout << endl << "You inserted: " << aTxt.getStr() << endl;
+ //
+ // cout << "Please insert Password: ";
+ // cout.flush();
+ // OString aPasswd = input("", '*');
+ // cout << endl << "You inserted: " << aPasswd.getStr() << endl;
+
+ try
+ {
+ OUString const sServiceRegistry = OUString::createFromAscii( argc > 1 ? argv[1] : "applicat.rdb" );
+ Reference< XMultiServiceFactory > xORB = createRegistryServiceFactory(
+ sServiceRegistry,
+ ::rtl::OUString()
+ );
+ if (!xORB.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the service factory !\n\n";
+ return 1;
+ }
+ cout << "Service factory created !\n---------------------------------------------------------------" << endl;
+
+ Sequence< Any > aCPArgs = createSequence(OUString::createFromAscii("Administrator"), OUString());
+
+ Reference< XMultiServiceFactory > xCfgProvider(
+ xORB->createInstanceWithArguments(
+ ::rtl::OUString::createFromAscii("com.sun.star.configuration.AdministrationProvider"),
+ aCPArgs),
+ UNO_QUERY);
+
+ if (!xCfgProvider.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the configuration provider !\n\n";
+ return 3;
+ }
+
+ cout << "Configuration Provider created !\n---------------------------------------------------------------" << endl;
+
+ Reference< XNameAccess > xUpdateAccess;
+ Reference< XNameAccess > xGroupAccess(xCfgProvider->createInstance(OUString::createFromAscii("com.sun.star.configuration.GroupAccess")),UNO_QUERY);
+ Reference< XNameAccess > xUserAccess(xCfgProvider->createInstance(OUString::createFromAscii("com.sun.star.configuration.UserAccess")),UNO_QUERY);
+
+ displayGroups(xGroupAccess);
+ displayUsers(xUserAccess);
+
+// create a group
+ OUString sGroupName = insertGroup(xGroupAccess);
+// create a user
+ OUString sUserName;
+ sUserName = insertUser(xUserAccess, sGroupName);
+
+// now do updates for the user
+ xUpdateAccess = beginChanges(xCfgProvider, OUString::createFromAscii("org.openoffice.Inet"), sUserName);
+
+ update(xUpdateAccess, OUString::createFromAscii("Proxy/FTP/Port"), sal_Int32(12));
+ update(xUpdateAccess, OUString::createFromAscii("Proxy/FTP/Name"), OUString::createFromAscii("demo"));
+ update(xUpdateAccess, OUString::createFromAscii("DNS/IP_Address"), OUString::createFromAscii("demo1"));
+
+ xUpdateAccess = beginChanges(xCfgProvider, OUString::createFromAscii("org.openoffice.Office.Common"), sUserName);
+ update(xUpdateAccess, OUString::createFromAscii("_3D_Engine/Dithering"), sal_Bool(sal_False));
+ commitChanges(xUpdateAccess);
+
+// now do updates with inserting and removing of nodes
+
+ xUpdateAccess = beginChanges(xCfgProvider, OUString::createFromAscii("org.openoffice.Security/MountPoints"), sUserName);
+ displayTree(xUpdateAccess);
+
+ Reference< XHierarchicalPropertySet > xTree = insertTree(xUpdateAccess, OUString());
+ update(xUpdateAccess, OUString::createFromAscii("InstallationDirectory/Directory"), OUString::createFromAscii("Test1"));
+ removeTree(xUpdateAccess, OUString());
+ commitChanges(xUpdateAccess);
+
+
+/* deleteUser(xUserAccess, sUserName);
+ deleteGroup(xGroupAccess, sGroupName); */
+
+ displayGroups(xGroupAccess);
+ displayUsers(xUserAccess);
+ }
+ catch (Exception& e)
+ {
+ ::flush(cout);
+ cerr << "Caught exception: " << e.Message << endl;
+ return 1;
+ }
+/*
+ catch (...)
+ {
+ flush(cout);
+ cerr << "BUG: Caught UNKNOWN exception (?) " << endl;
+ }
+*/
+ return 0;
+}
+
+
+
+
diff --git a/configmgr/workben/apitest/cfgapi.cxx b/configmgr/workben/apitest/cfgapi.cxx
new file mode 100644
index 000000000000..968aca927e43
--- /dev/null
+++ b/configmgr/workben/apitest/cfgapi.cxx
@@ -0,0 +1,868 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgapi.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#define _PRIVATE_TEST_
+
+#include <iostream>
+using namespace std;
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Any.h>
+#include <osl/profile.hxx>
+#include <osl/process.h>
+#include <osl/file.h>
+
+#include "createpropertyvalue.hxx"
+
+#include "typeconverter.hxx"
+
+// #include <com/sun/star/configuration/XConfigurationSync.hpp>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+//using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+using ::rtl::OString;
+//using namespace ::configmgr;
+
+using namespace ::cppu;
+
+#define ASCII(x) ::rtl::OUString::createFromAscii(x)
+
+ostream& operator << (ostream& out, rtl::OUString const& aStr)
+{
+ sal_Unicode const* const pStr = aStr.getStr();
+ sal_Unicode const* const pEnd = pStr + aStr.getLength();
+ for (sal_Unicode const* p = pStr; p < pEnd; ++p)
+ if (0 < *p && *p < 127) // ASCII
+ out << char(*p);
+ else
+ out << "[\\u" << hex << *p << "]";
+ return out;
+}
+
+void showSequence(const Sequence<OUString> &aSeq)
+{
+ OUString aArray;
+ const OUString *pStr = aSeq.getConstArray();
+ for (int i=0;i<aSeq.getLength();i++)
+ {
+ OUString aStr = pStr[i];
+ // aArray += aStr + ASCII(", ");
+ cout << aStr << endl;
+ }
+ volatile int dummy = 0;
+}
+
+//=============================================================================
+
+inline void operator <<= (::rtl::OUString& _rUnicodeString, const sal_Char* _pAsciiString)
+{
+ _rUnicodeString = ::rtl::OUString::createFromAscii(_pAsciiString);
+}
+
+inline void operator <<= (::rtl::OUString& _rUnicodeString, const ::rtl::OString& _rAsciiString)
+{
+ _rUnicodeString <<= _rAsciiString.getStr();
+}
+
+inline void operator <<= (Any& _rUnoValue, const sal_Char* _pAsciiString)
+{
+ _rUnoValue <<= ::rtl::OUString::createFromAscii(_pAsciiString);
+}
+
+inline void operator <<= (Any& _rUnoValue, const ::rtl::OString& _rAsciiString)
+{
+ _rUnoValue <<= _rAsciiString.getStr();
+}
+
+//=============================================================================
+void test_read_access(Reference< XInterface >& xIface, Reference< XMultiServiceFactory > &xMSF);
+//=============================================================================
+struct prompt_and_wait
+{
+ char const* myText;
+ prompt_and_wait(char const* text = "") : myText(text) {}
+ ~prompt_and_wait()
+ {
+ cout << myText << ">" << endl;
+ int const mx = int( (+0u - +1u) >> 1);
+
+ char c=0;
+ if (cin.get(c) && c != '\n')
+ cin.ignore(mx,'\n');
+ }
+};
+static prompt_and_wait exit_prompt("Quitting\nQ");
+
+
+Reference< XChangesBatch > xChangesBatch = NULL;
+void commit()
+{
+ if (xChangesBatch.is())
+ {
+ xChangesBatch->commitChanges();
+ }
+}
+
+// -----------------------------------------------------------------------------
+static sal_Bool s_bInitialized = sal_False;
+#ifdef LLA_PRIVAT_DEBUG
+static const sal_Char* s_pSourcePath = "l:/src625/configmgr/workben/local_io/share";
+static const sal_Char* s_pUpdatePath = "l:/src625/configmgr/workben/local_io/user";
+static const sal_Char* s_pRootNode = "org.openoffice.ucb.Hierarchy"; // "org.openoffice.test";
+static const sal_Char* s_pServerType = "local";
+static const sal_Char* s_pLocale = "de-DE";
+static const sal_Char* s_pServer = "";
+static const sal_Char* s_pUser = "";
+static const sal_Char* s_pPassword = "";
+#else
+static const sal_Char* s_pSourcePath = "g:/src/configmgr/workben/local_io/share";
+static const sal_Char* s_pUpdatePath = "g:/src/configmgr/workben/local_io/user";
+static const sal_Char* s_pRootNode = "org.openoffice.Office.TypeDetection";
+static const sal_Char* s_pServerType = "setup";
+static const sal_Char* s_pLocale = "de-DE";
+static const sal_Char* s_pServer = "lautrec-3108:19205";
+static const sal_Char* s_pUser = "lars";
+static const sal_Char* s_pPassword = "";
+#endif
+
+
+// -----------------------------------------------------------------------------
+static void loadDefaults()
+{
+ if (s_bInitialized)
+ return;
+
+ s_bInitialized = sal_True;
+
+ try
+ {
+ // the executable file name
+ ::rtl::OUString sExecutable;
+ osl_getExecutableFile(&sExecutable.pData);
+ // cut the name, add a cfgapi.ini to the path
+ sal_Int32 nLastSep = sExecutable.lastIndexOf('/');
+ if (-1 != nLastSep)
+ sExecutable = sExecutable.copy(0, nLastSep + 1);
+#ifdef UNX
+ sExecutable += ::rtl::OUString::createFromAscii("cfgapirc");
+#else
+ sExecutable += ::rtl::OUString::createFromAscii("cfgapi.ini");
+#endif
+ ::rtl::OUString sNormalized;
+ sNormalized = sExecutable;
+ if (1)
+ {
+ ::osl::Profile aProfile(sNormalized);
+
+ static ::rtl::OString sSection("defaults");
+ static ::rtl::OString sSourcePath("sourcepath");
+ static ::rtl::OString sUpdatePath("updatepath");
+ static ::rtl::OString sRootNode("rootnode");
+ static ::rtl::OString sServerType("servertype");
+ static ::rtl::OString sLocale("Locale");
+ static ::rtl::OString sServer("Server");
+ static ::rtl::OString sUser("User");
+ static ::rtl::OString sPassword("Password");
+
+ // read some strings.
+ // Do this static because we want to redirect the global static character pointers to the buffers.
+ static ::rtl::OString s_sSourcePath = aProfile.readString(sSection, sSourcePath, s_pSourcePath);
+ static ::rtl::OString s_sUpdatePath = aProfile.readString(sSection, sUpdatePath, s_pUpdatePath);
+ static ::rtl::OString s_sRootNode = aProfile.readString(sSection, sRootNode, s_pRootNode);
+ static ::rtl::OString s_sServerType = aProfile.readString(sSection, sServerType, s_pServerType);
+ static ::rtl::OString s_sLocale = aProfile.readString(sSection, sLocale, s_pLocale);
+ static ::rtl::OString s_sServer = aProfile.readString(sSection, sServer, s_pServer);
+ static ::rtl::OString s_sUser = aProfile.readString(sSection, sUser, s_pUser);
+ static ::rtl::OString s_sPassword = aProfile.readString(sSection, sPassword, s_pPassword);
+
+ // do this redirection
+ s_pSourcePath = s_sSourcePath.getStr();
+ s_pUpdatePath = s_sUpdatePath.getStr();
+ s_pRootNode = s_sRootNode.getStr();
+ s_pServerType = s_sServerType.getStr();
+ s_pLocale = s_sLocale.getStr();
+ s_pServer = s_sServer.getStr();
+ s_pUser = s_sUser.getStr();
+ s_pPassword = s_sPassword.getStr();
+ }
+ }
+ catch(std::exception& e)
+ {
+ e.what(); // silence warnings
+ }
+}
+
+// -----------------------------------------------------------------------------
+Sequence<Any> createSequence(const OUString &sUser, const OUString &sPasswd)
+{
+ Sequence< Any > aCPArgs;
+
+ if (sUser.getLength() > 0)
+ {
+ aCPArgs.realloc(1);
+ aCPArgs[0] <<= configmgr::createPropertyValue(ASCII("user"), sUser);
+ }
+ if (sPasswd.getLength() > 0)
+ {
+ aCPArgs.realloc(2);
+ aCPArgs[1] <<= configmgr::createPropertyValue(ASCII("password"), sPasswd);
+ }
+ return aCPArgs;
+}
+
+//=============================================================================
+#include <string.h>
+#if (defined UNX) || (defined OS2)
+#else
+#include <conio.h>
+#endif
+
+OString input(const char* pDefaultText, char cEcho)
+{
+ // PRE: a Default Text would be shown, cEcho is a Value which will show if a key is pressed.
+ const int MAX_INPUT_LEN = 500;
+ char aBuffer[MAX_INPUT_LEN];
+
+ strcpy(aBuffer, pDefaultText);
+ int nLen = strlen(aBuffer);
+
+#ifdef WNT
+ char ch = '\0';
+
+ cout << aBuffer;
+ cout.flush();
+
+ while(ch != 13)
+ {
+ ch = getch();
+ if (ch == 8)
+ {
+ if (nLen > 0)
+ {
+ cout << "\b \b";
+ cout.flush();
+ --nLen;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ cout << "\a";
+ cout.flush();
+ }
+ }
+ else if (ch != 13)
+ {
+ if (nLen < MAX_INPUT_LEN)
+ {
+ if (cEcho == 0)
+ {
+ cout << ch;
+ }
+ else
+ {
+ cout << cEcho;
+ }
+ cout.flush();
+ aBuffer[nLen++] = ch;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ cout << "\a";
+ cout.flush();
+ }
+ }
+ }
+#else
+ if (!cin.getline(aBuffer,sizeof aBuffer))
+ return OString();
+#endif
+ return OString(aBuffer);
+}
+
+// -----------------------------------------------------------------------------
+rtl::OUString enterValue(const char* _aStr, const char* _aDefault, bool _bIsAPassword)
+{
+ cout << _aStr;
+ cout.flush();
+
+ OUString sValue;
+ sValue <<= input(_aDefault, _bIsAPassword ? '*' : 0);
+ return sValue;
+}
+
+
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- M A I N ----------------------------------
+// -----------------------------------------------------------------------------
+
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+int _cdecl main( int argc, char * argv[] )
+#endif
+{
+ TimeValue aTimeout;
+ aTimeout.Seconds = 5;
+ aTimeout.Nanosec = 0;
+
+ // cout << " Please insert Text: ";
+ // cout.flush();
+ // OString aTxt = input("Der Text", 0);
+ // cout << endl << "You inserted: " << aTxt.getStr() << endl;
+ //
+ // cout << "Please insert Password: ";
+ // cout.flush();
+ // OString aPasswd = input("", '*');
+ // cout << endl << "You inserted: " << aPasswd.getStr() << endl;
+
+ loadDefaults();
+
+ try
+ {
+ OUString const sServiceRegistry = OUString::createFromAscii( argc > 1 ? argv[1] : "applicat.rdb" );
+ Reference< XMultiServiceFactory > xORB = createRegistryServiceFactory(
+ sServiceRegistry,
+ ::rtl::OUString()
+ );
+ if (!xORB.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the service factory !\n\n";
+ return 1;
+ }
+ cout << "Service factory created !\n---------------------------------------------------------------" << endl;
+
+ Sequence< Any > aCPArgs;
+
+ OUString sServerType = enterValue("servertype: ", s_pServerType, false);
+ cout << endl;
+
+
+ rtl::OUString sUser;
+
+ bool bLocal = sServerType.equalsIgnoreAsciiCase(ASCII("local")) || sServerType.equalsIgnoreAsciiCase(ASCII("setup"));
+ if (!bLocal)
+ {
+ rtl::OUString sServer;
+ sServer = enterValue("server : ", s_pServer,false);
+ cout << endl;
+
+ sUser = enterValue("user : ", s_pUser, false);
+ cout << endl;
+
+ OUString sPasswd = enterValue("password: ", s_pPassword, true);
+ cout << endl;
+
+ aCPArgs = createSequence(sUser, sPasswd);
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("server"), sServer);
+
+ OUString sTimeout = ASCII("10000");
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("timeout"), sTimeout);
+
+ }
+ else
+ {
+ rtl::OUString sSharePath, sUserPath;
+ sSharePath = enterValue("share path: ", s_pSourcePath, false);
+ cout << endl;
+ sUserPath = enterValue("user path : ", s_pUpdatePath, false);
+ cout << endl;
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ sal_Int32 nCount = aCPArgs.getLength() - 1;
+ Any *pAny = &aCPArgs[nCount];
+ *pAny <<= configmgr::createPropertyValue(ASCII("sourcepath"), sSharePath);
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("updatepath"), sUserPath);
+ }
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("servertype"), sServerType);
+
+ Reference< XMultiServiceFactory > xCfgProvider(
+ xORB->createInstanceWithArguments(
+ ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"),
+ aCPArgs),
+ UNO_QUERY);
+ if (!xCfgProvider.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the configuration provider !\n\n";
+ return 3;
+ }
+
+
+
+
+ char aPath[300] = "/";
+ int nStart = sizeof( "/" ) - 1;
+
+ cout << "---------------------------------------------------------------\n Configuration Provider created !\n---------------------------------------------------------------" << endl;
+
+ Sequence< Any > aArgs;
+ aArgs = createSequence(sUser, ASCII(""));
+
+ OUString sPath = enterValue("nodepath: ", s_pRootNode, false);
+ cout << endl;
+
+ aArgs.realloc(aArgs.getLength() + 1);
+ aArgs[aArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("nodepath"), sPath);
+
+ if (!bLocal)
+ {
+ OUString sLocale = enterValue("locale : ", s_pLocale, false);
+ cout << endl;
+ aArgs.realloc(aArgs.getLength() + 1);
+ aArgs[aArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("locale"), sLocale);
+ }
+/*
+#else
+ OUString aStr = ASCII("String");
+ sal_Int32 nDepth = 10;
+ Sequence< Any > aArgs(2);
+
+ aArgs[0] <<= aStr;
+ aArgs[1] <<= nDepth;
+#endif
+*/
+ Reference< XInterface > xIFace = xCfgProvider->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"),
+ aArgs);
+ cout << "---------------------------------------------------------------\n Configuration Read/Write Access created !\n---------------------------------------------------------------" << endl;
+
+ xChangesBatch = Reference< XChangesBatch >(xIFace, UNO_QUERY);
+
+ Sequence<OUString> aSeq = xCfgProvider->getAvailableServiceNames();
+ showSequence(aSeq);
+
+ test_read_access(xIFace, xCfgProvider);
+ }
+ catch (Exception& e)
+ {
+ ::flush(cout);
+ cerr << "Caught exception: " << e.Message << endl;
+ }
+/*
+ catch (...)
+ {
+ flush(cout);
+ cerr << "BUG: Caught UNKNOWN exception (?) " << endl;
+ }
+*/
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+void test(Reference< XHierarchicalName >& xAccessName)
+{
+ if (xAccessName.is())
+ cout << "Accessing Node: " << xAccessName->getHierarchicalName();
+ else
+ cout << "BUG: XHierarchicalName not available";
+ cout << endl;
+}
+void test(Reference< XNamed >& xAccess)
+{
+ if (xAccess.is())
+ cout << "Node is named: " << xAccess->getName();
+ else
+ cout << "BUG: XNamed not available";
+ cout << endl;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+void write(Reference<XNameAccess >& xAccess)
+{
+ if (xAccess.is())
+ {
+ Sequence<OUString> aNames( xAccess->getElementNames() );
+
+ cout << "Element Names: (" << aNames.getLength() << ")";
+ for (int i = 0; i < aNames.getLength(); ++i)
+ cout << "\n[" << i << "] -\t" << aNames[i];
+ cout << endl;
+ }
+ else
+ cout << "BUG: XNameAccess not available";
+ cout << endl;
+}
+void write(Reference< XChild >& xChild)
+{
+ if (xChild.is())
+ cout << "\n[ P ] -\tParent";
+ else
+ cout << "BUG: Parent not available (no XChild)";
+ cout << endl;
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+
+bool ask(Reference< XInterface >& xIface, Reference<XMultiServiceFactory> &);
+
+void test_read_access(Reference< XInterface >& xIface, Reference< XMultiServiceFactory > &xMSF)
+{
+ using com::sun::star::uno::UNO_QUERY;
+ do
+ {
+ cout << "\n\n---------------------------------------------------------------" << endl;
+ Reference< XNameAccess > xAccess(xIface, UNO_QUERY);
+ Reference< XChild > xChild(xIface, UNO_QUERY);
+ Reference< XHierarchicalName > xAccessPath(xIface,UNO_QUERY);
+ Reference< XNamed > xAccessName(xIface,UNO_QUERY);
+// Reference< XHierarchicalNameAccess >& xAccess(xIface, UNO_QUERY);
+
+ test(xAccessPath);
+ test(xAccessName);
+ write(xAccess);
+ write(xChild);
+ }
+ while (ask(xIface, xMSF));
+}
+
+bool ask(Reference< XInterface >& xIface, Reference< XMultiServiceFactory > &xMSF)
+{
+ cout << "\n[ Q ] -> <Quit>";
+ cout << "\n[ S ] -> <SetValue> ";
+ cout << endl;
+
+ cout << "\n:> " << flush;
+ char buf[200] = {0};
+ try
+ {
+ bool bHandled = false;
+ bool bInserted = false;
+
+ if (cin.getline(buf,sizeof buf))
+ {
+ Reference< XInterface > xNext;
+ if ((buf[0] == 'q' || buf[0] == 'Q') && (0 == buf[1]))
+ {
+ return false;
+ }
+ else if (buf[0] == 0)
+ {
+ return true;
+ }
+ else if((buf[0] == 0 || buf[0] == 'o' || buf[0] == 'O') && (0 == buf[1]))
+ {
+/*
+ cout << "work Offline" << endl;
+ Reference<com::sun::star::configuration::XConfigurationSync> xSync(xMSF, UNO_QUERY);
+
+ Sequence< Any > aArgs2(5);
+ sal_Int32 n=0;
+ aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Setup"));
+ // aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Office.Common"));
+ // aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Office.Java"));
+ // aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Office.Writer"));
+ // aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Office.ucb.Hierarchy"));
+ xSync->offline(aArgs2);
+ bHandled = true;
+*/
+ }
+ else if((buf[0] == 0 || buf[0] == 's' || buf[0] == 'S') && (0 == buf[1]))
+ {
+ // Replace a Value
+ Reference< XNameAccess > xAccess(xIface, UNO_QUERY);
+
+ cout << "SetMode, insert a Number" << endl;
+ cin.getline(buf,sizeof buf);
+ bInserted = true;
+ }
+
+ else if ((buf[0] == 'p' || buf[0] == 'P') && (0 == buf[1]))
+ {
+ Reference< XChild > xChild(xIface, UNO_QUERY);
+ if (xChild.is())
+ xNext = xChild->getParent();
+ bHandled = true;
+ }
+
+ if (bHandled == false)
+ {
+ Reference< XNameAccess > xAccess(xIface, UNO_QUERY);
+ Reference< XHierarchicalNameAccess > xDeepAccess(xIface, UNO_QUERY);
+ Reference< XExactName > xExactName(xIface, UNO_QUERY);
+
+ if (xAccess.is() || xDeepAccess.is())
+ {
+ OUString aName;
+ OUString aInput = OUString::createFromAscii(buf);
+
+ if (xExactName.is())
+ {
+ ::rtl::OUString sTemp = xExactName->getExactName(aInput);
+ if (sTemp.getLength())
+ aInput = sTemp;
+ }
+
+ if (xAccess.is() && xAccess->hasByName(aInput))
+ {
+ aName = aInput;
+ }
+ else if (xDeepAccess.is() && xDeepAccess->hasByHierarchicalName(aInput))
+ {
+ aName = aInput;
+ }
+ else if ('0' <= buf[0] && buf[0] <= '9' && xAccess.is())
+ {
+ unsigned int n = unsigned(atoi(buf));
+ Sequence<OUString> aNames = xAccess->getElementNames();
+ if (n < aNames.getLength())
+ aName = aNames[n];
+ }
+
+ if (aName.getLength())
+ {
+ bool bNest = aInput.indexOf(sal_Unicode('/')) >= 0;
+
+ Any aElement = bNest ? ( xDeepAccess.is() ? xDeepAccess->getByHierarchicalName(aName) : Any())
+ : ( xAccess. is() ? xAccess-> getByName(aName) : Any() );
+
+ while (aElement.getValueTypeClass() == TypeClass_ANY)
+ {
+ Any aWrap(aElement);
+ aWrap >>= aElement;
+ }
+ sal_Bool bValue = true;
+ sal_Bool bValueOk = false;
+
+ switch (aElement.getValueTypeClass() )
+ {
+ case TypeClass_INTERFACE: bValue = false; break;
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool* pVal = (sal_Bool*)aElement.getValue();
+ bValueOk = (pVal != 0);
+
+ cout << "VALUE '" << aName << "' is a BOOLEAN = ";
+ if (!bValueOk)
+ cout << "NULL (error!!)";
+ else if (*pVal)
+ cout << "'TRUE'";
+ else
+ cout << "'FALSE'";
+
+ cout << endl;
+ }
+ break;
+ case TypeClass_SHORT:
+ {
+ sal_Int16 aValue;
+ cout << "VALUE '" << aName << "' is a SHORT (16 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ cout << aValue;
+ else
+ cout << "ERROR RETRIEVING VALUE";
+ cout << endl;
+ }
+ break;
+ case TypeClass_LONG:
+ {
+
+ sal_Int32 aValue;
+ cout << "VALUE '" << aName << "' is a INT (32 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ cout << aValue;
+ else
+ cout << "ERROR RETRIEVING VALUE";
+ cout << endl;
+ }
+ break;
+ case TypeClass_HYPER:
+ {
+ sal_Int64 aValue;
+ cout << "VALUE '" << aName << "' is a LONG (64 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ cout << double(aValue);
+ else
+ cout << "ERROR RETRIEVING VALUE";
+ cout << endl;
+ }
+ break;
+ case TypeClass_DOUBLE:
+ {
+ double aValue;
+ cout << "VALUE '" << aName << "' is a DOUBLE = ";
+ if (bValueOk = (aElement >>= aValue))
+ cout << aValue;
+ else
+ cout << "ERROR RETRIEVING VALUE";
+ cout << endl;
+ }
+ break;
+ case TypeClass_STRING:
+ {
+ OUString aValue;
+ cout << "VALUE '" << aName << "' is a STRING = ";
+ if (bValueOk = (aElement >>= aValue))
+ cout << "\"" << aValue << "\"";
+ else
+ cout << "ERROR RETRIEVING VALUE";
+ cout << endl;
+ }
+ break;
+ case TypeClass_SEQUENCE:
+ {
+ cout << "VALUE '" << aName << "' is a SEQUENCE or BINARY" << endl;
+
+ Type aTypeS = configmgr::getSequenceElementType(aElement.getValueType());
+ OUString sType = configmgr::toTypeName(aTypeS.getTypeClass());
+ cout << "Real type is Sequence<" << sType << ">" << endl;
+ bValueOk = true;
+ }
+ break;
+ case TypeClass_VOID:
+ cout << "ELEMENT '" << aName << "' is NULL and VOID " << endl;
+ bValueOk = true;
+ break;
+ default:
+ cout << "Error: ELEMENT '" << aName << "' is of unknown or unrecognized type" << endl;
+ break;
+ }
+ if (bValue)
+ {
+ if (bInserted)
+ {
+ if (aElement.getValueTypeClass() == TypeClass_BOOLEAN ||
+ aElement.getValueTypeClass() == TypeClass_VOID)
+ {
+ cout << "Set Value (Type=BOOL) to :";
+ cout.flush();
+ cin.getline(buf,sizeof buf);
+ OUString aInput = OUString::createFromAscii(buf);
+ sal_Bool bValue = false;
+ if (aInput.equalsIgnoreAsciiCase(ASCII("true")))
+ bValue = true;
+
+ OUString aStr = ASCII("false");
+ Any aValueAny;
+ aValueAny <<= bValue;
+
+ Reference< XNameReplace > xNameReplace(xAccess, UNO_QUERY);
+ if (xNameReplace.is())
+ {
+ xNameReplace->replaceByName(aName, aValueAny);
+ commit();
+ }
+ bInserted = false;
+ }
+ else if (aElement.getValueTypeClass() == TypeClass_STRING)
+ {
+ cout << "set value (type = string) to : ";
+ cout.flush();
+ cin.getline(buf,sizeof buf);
+ Any aValue;
+ aValue <<= buf;
+
+ Reference< XNameReplace > xNameReplace(xAccess, UNO_QUERY);
+ if (xNameReplace.is())
+ {
+ xNameReplace->replaceByName(aName, aValue);
+ commit();
+ }
+ bInserted = false;
+ }
+ else
+ {
+ cout << "Sorry, only BOOLEAN Values can changed today." << endl;
+ }
+ }
+ prompt_and_wait();
+ return bValueOk ? true : false;
+ }
+
+ if (aElement >>= xNext)
+ cout << "Got an Interface for '" << aName << "'" << endl;
+ else
+ cout << "Error: Cannot get an Interface for '" << aName << "'" << endl;
+ }
+ else
+ {
+ cout << "Error: No element \"" << aInput << "\" found." <<endl;
+ }
+ }
+
+ }
+ if (xNext.is())
+ {
+ xIface = xNext;
+ return true;
+ }
+ cout << "Error: could not obtain the requested Object " << endl;
+ }
+ else
+ {
+ cout << "Input Error " << endl;
+ return true;
+ }
+ }
+ catch (Exception& e)
+ {
+ cout << "An Exception occurred: " << e.Message << endl;
+
+ }
+ catch (...)
+ {
+ cout << "An UNKNOWN Exception occurred !" << endl;
+ }
+
+ prompt_and_wait();
+ return true;
+}
diff --git a/configmgr/workben/apitest/cfgapi_timetest.cxx b/configmgr/workben/apitest/cfgapi_timetest.cxx
new file mode 100644
index 000000000000..cd39ce0372d6
--- /dev/null
+++ b/configmgr/workben/apitest/cfgapi_timetest.cxx
@@ -0,0 +1,960 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgapi_timetest.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#define _PRIVATE_TEST_
+
+#include <iostream>
+using namespace std;
+
+#include <vector>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Any.h>
+#include <osl/profile.hxx>
+#include <osl/process.h>
+#include <osl/file.h>
+
+#include "createpropertyvalue.hxx"
+
+#include "typeconverter.hxx"
+
+// #include <com/sun/star/configuration/XConfigurationSync.hpp>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+//using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+using ::rtl::OString;
+//using namespace ::configmgr;
+
+using namespace ::cppu;
+
+#define ASCII(x) ::rtl::OUString::createFromAscii(x)
+
+bool m_bInteractive = false;
+
+#define COUT if(m_bInteractive) cout
+
+ostream& operator << (ostream& out, rtl::OUString const& aStr)
+{
+ sal_Unicode const* const pStr = aStr.getStr();
+ sal_Unicode const* const pEnd = pStr + aStr.getLength();
+ for (sal_Unicode const* p = pStr; p < pEnd; ++p)
+ if (0 < *p && *p < 127) // ASCII
+ out << char(*p);
+ else
+ out << "[\\u" << hex << *p << "]";
+ return out;
+}
+
+void showSequence(const Sequence<OUString> &aSeq)
+{
+ OUString aArray;
+ const OUString *pStr = aSeq.getConstArray();
+ for (int i=0;i<aSeq.getLength();i++)
+ {
+ OUString aStr = pStr[i];
+ // aArray += aStr + ASCII(", ");
+ COUT << aStr << endl;
+ }
+ volatile int dummy = 0;
+}
+
+//=============================================================================
+
+inline void operator <<= (::rtl::OUString& _rUnicodeString, const sal_Char* _pAsciiString)
+{
+ _rUnicodeString = ::rtl::OUString::createFromAscii(_pAsciiString);
+}
+
+inline void operator <<= (::rtl::OUString& _rUnicodeString, const ::rtl::OString& _rAsciiString)
+{
+ _rUnicodeString <<= _rAsciiString.getStr();
+}
+
+inline void operator <<= (Any& _rUnoValue, const sal_Char* _pAsciiString)
+{
+ _rUnoValue <<= ::rtl::OUString::createFromAscii(_pAsciiString);
+}
+
+inline void operator <<= (Any& _rUnoValue, const ::rtl::OString& _rAsciiString)
+{
+ _rUnoValue <<= _rAsciiString.getStr();
+}
+
+//=============================================================================
+void test_read_access(Reference< XInterface >& xIface, const Reference< XMultiServiceFactory > &xMSF);
+//=============================================================================
+
+// -----------------------------------------------------------------------------
+struct prompt_and_wait
+{
+ char const* myText;
+ prompt_and_wait(char const* text = "") : myText(text) {}
+ ~prompt_and_wait()
+ {
+ if (m_bInteractive)
+ {
+ COUT << myText << ">" << endl;
+ int const mx = int( (+0u - +1u) >> 1);
+
+ char c=0;
+ if (cin.get(c) && c != '\n')
+ cin.ignore(mx,'\n');
+ }
+ }
+};
+static prompt_and_wait exit_prompt("Quitting\nQ");
+
+
+Reference< XChangesBatch > xChangesBatch = NULL;
+void commit()
+{
+ if (xChangesBatch.is())
+ {
+ xChangesBatch->commitChanges();
+ }
+}
+
+// -----------------------------------------------------------------------------
+static sal_Bool s_bInitialized = sal_False;
+static const sal_Char* s_pSourcePath = "f:/office60_623/share/config/registry";
+static const sal_Char* s_pUpdatePath = "f:/office60_623/user/config/registry";
+static const sal_Char* s_pRootNode = "org.openoffice.Office.Common";
+static const sal_Char* s_pServerType = "local";
+static const sal_Char* s_pLocale = "de-DE";
+static const sal_Char* s_pServer = "lautrec-3108:19205";
+static const sal_Char* s_pUser = "lars";
+static const sal_Char* s_pPassword = "";
+
+std::vector<rtl::OString> m_sNodes;
+
+// -----------------------------------------------------------------------------
+static void loadDefaults()
+{
+ if (s_bInitialized)
+ return;
+
+ s_bInitialized = sal_True;
+
+ try
+ {
+ // the executable file name
+ ::rtl::OUString sExecutable;
+ osl_getExecutableFile(&sExecutable.pData);
+ // cut the name, add a cfgapi.ini to the path
+ sal_Int32 nLastSep = sExecutable.lastIndexOf('/');
+ if (-1 != nLastSep)
+ sExecutable = sExecutable.copy(0, nLastSep + 1);
+#ifdef UNX
+ sExecutable += ::rtl::OUString::createFromAscii("cfgapirc");
+#else
+ sExecutable += ::rtl::OUString::createFromAscii("cfgapi.ini");
+#endif
+ ::rtl::OUString sSystem;
+ if (osl_File_E_None == osl_getSystemPathFromFileURL(sExecutable.pData, &sSystem.pData))
+ {
+ ::osl::Profile aProfile(sExecutable);
+
+ static ::rtl::OString sSection("defaults");
+ static ::rtl::OString sSourcePath("sourcepath");
+ static ::rtl::OString sUpdatePath("updatepath");
+ static ::rtl::OString sRootNode("rootnode");
+ static ::rtl::OString sServerType("servertype");
+ static ::rtl::OString sLocale("Locale");
+ static ::rtl::OString sServer("Server");
+ static ::rtl::OString sUser("User");
+ static ::rtl::OString sPassword("Password");
+
+ // read some strings.
+ // Do this static because we want to redirect the global static character pointers to the buffers.
+ static ::rtl::OString s_sSourcePath = aProfile.readString(sSection, sSourcePath, s_pSourcePath);
+ static ::rtl::OString s_sUpdatePath = aProfile.readString(sSection, sUpdatePath, s_pUpdatePath);
+ static ::rtl::OString s_sRootNode = aProfile.readString(sSection, sRootNode, s_pRootNode);
+ static ::rtl::OString s_sServerType = aProfile.readString(sSection, sServerType, s_pServerType);
+ static ::rtl::OString s_sLocale = aProfile.readString(sSection, sLocale, s_pLocale);
+ static ::rtl::OString s_sServer = aProfile.readString(sSection, sServer, s_pServer);
+ static ::rtl::OString s_sUser = aProfile.readString(sSection, sUser, s_pUser);
+ static ::rtl::OString s_sPassword = aProfile.readString(sSection, sPassword, s_pPassword);
+
+ // do this redirection
+ s_pSourcePath = s_sSourcePath.getStr();
+ s_pUpdatePath = s_sUpdatePath.getStr();
+ s_pRootNode = s_sRootNode.getStr();
+ s_pServerType = s_sServerType.getStr();
+ s_pLocale = s_sLocale.getStr();
+ s_pServer = s_sServer.getStr();
+ s_pUser = s_sUser.getStr();
+ s_pPassword = s_sPassword.getStr();
+
+ static ::rtl::OString sNodeSection("nodes");
+ static ::rtl::OString sCount("count");
+ rtl::OUString sCountValue;
+ sCountValue <<= aProfile.readString(sNodeSection, sCount, "0");
+ sal_Int32 nCount = sCountValue.toInt32();
+ for (sal_Int32 i=0;i<nCount;i++)
+ {
+ ::rtl::OString sNodeName("node");
+ sNodeName += OString::valueOf(i);
+ ::rtl::OString sNode = aProfile.readString(sNodeSection, sNodeName, "");
+ m_sNodes.push_back(sNode);
+ }
+ }
+ }
+ catch(std::exception& e)
+ {
+ e.what(); // silence warnings
+ }
+}
+
+// -----------------------------------------------------------------------------
+Sequence<Any> createSequence(const OUString &sUser, const OUString &sPasswd)
+{
+ Sequence< Any > aCPArgs;
+
+ if (sUser.getLength() > 0)
+ {
+ aCPArgs.realloc(1);
+ aCPArgs[0] <<= configmgr::createPropertyValue(ASCII("user"), sUser);
+ }
+ if (sPasswd.getLength() > 0)
+ {
+ aCPArgs.realloc(2);
+ aCPArgs[1] <<= configmgr::createPropertyValue(ASCII("password"), sPasswd);
+ }
+ return aCPArgs;
+}
+
+//=============================================================================
+#include <string.h>
+#if (defined UNX) || (defined OS2)
+#else
+#include <conio.h>
+#endif
+
+OString input(const char* pDefaultText, char cEcho)
+{
+ // PRE: a Default Text would be shown, cEcho is a Value which will show if a key is pressed.
+ const int MAX_INPUT_LEN = 500;
+ char aBuffer[MAX_INPUT_LEN];
+
+ strcpy(aBuffer, pDefaultText);
+ int nLen = strlen(aBuffer);
+
+#ifdef WNT
+ char ch = '\0';
+
+ COUT << aBuffer;
+ cout.flush();
+
+ while(ch != 13)
+ {
+ ch = getch();
+ if (ch == 8)
+ {
+ if (nLen > 0)
+ {
+ COUT << "\b \b";
+ cout.flush();
+ --nLen;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ COUT << "\a";
+ cout.flush();
+ }
+ }
+ else if (ch != 13)
+ {
+ if (nLen < MAX_INPUT_LEN)
+ {
+ if (cEcho == 0)
+ {
+ COUT << ch;
+ }
+ else
+ {
+ COUT << cEcho;
+ }
+ cout.flush();
+ aBuffer[nLen++] = ch;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ COUT << "\a";
+ cout.flush();
+ }
+ }
+ }
+#else
+ if (!cin.getline(aBuffer,sizeof aBuffer))
+ return OString();
+#endif
+ return OString(aBuffer);
+}
+
+
+// -----------------------------------------------------------------------------
+rtl::OUString enterValue(const char* _aStr, const char* _aDefault, bool _bIsAPassword)
+{
+ COUT << _aStr;
+ cout.flush();
+
+ OUString sValue;
+ if (m_bInteractive)
+ {
+ sValue <<= input(_aDefault, _bIsAPassword ? '*' : 0);
+ }
+ else
+ {
+ sValue <<= _aDefault;
+ }
+ return sValue;
+}
+
+
+
+void ask_for_a_node_and_test_it(const Reference< XMultiServiceFactory > &xCfgProvider,
+ const OUString& sUser, const OUString &sPasswd,
+ const OUString& sPath, bool bLocal, const OUString &sLocale);
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- M A I N ----------------------------------
+// -----------------------------------------------------------------------------
+
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+int _cdecl main( int argc, char * argv[] )
+#endif
+{
+ TimeValue aTimeout;
+ aTimeout.Seconds = 5;
+ aTimeout.Nanosec = 0;
+
+ // COUT << " Please insert Text: ";
+ // cout.flush();
+ // OString aTxt = input("Der Text", 0);
+ // COUT << endl << "You inserted: " << aTxt.getStr() << endl;
+ //
+ // COUT << "Please insert Password: ";
+ // cout.flush();
+ // OString aPasswd = input("", '*');
+ // COUT << endl << "You inserted: " << aPasswd.getStr() << endl;
+
+ loadDefaults();
+
+ m_bInteractive = false;
+ //if (argc > 1)
+ //{
+ // OString aParam(argv[1]);
+ // if (aParam.equals("ask"))
+ // {
+ // m_bInteractive = true;
+ // }
+ //}
+
+ try
+ {
+ OUString const sServiceRegistry = OUString::createFromAscii( argc > 1 ? argv[1] : "applicat.rdb" );
+ Reference< XMultiServiceFactory > xORB = createRegistryServiceFactory(
+ sServiceRegistry,
+ ::rtl::OUString()
+ );
+ if (!xORB.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the service factory !\n\n";
+ return 1;
+ }
+ COUT << "Service factory created !\n---------------------------------------------------------------" << endl;
+
+ Sequence< Any > aCPArgs;
+
+ OUString sServerType = enterValue("servertype: ", s_pServerType, false);
+ COUT << endl;
+
+
+ rtl::OUString sUser, sPasswd;
+
+ bool bLocal = sServerType.equalsIgnoreAsciiCase(ASCII("local")) || sServerType.equalsIgnoreAsciiCase(ASCII("setup"));
+ if (!bLocal)
+ {
+ rtl::OUString sServer;
+ sServer = enterValue("server : ", s_pServer,false);
+ COUT << endl;
+
+ sUser = enterValue("user : ", s_pUser, false);
+ COUT << endl;
+
+ sPasswd = enterValue("password: ", s_pPassword, true);
+ COUT << endl;
+
+ aCPArgs = createSequence(sUser, sPasswd);
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("server"), sServer);
+
+ long nTimeout = 10000;
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("timeout"), nTimeout);
+
+ long nPort = 9205;
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("port"), nPort);
+ }
+ else
+ {
+ rtl::OUString sSharePath, sUserPath;
+ sSharePath = enterValue("share path: ", s_pSourcePath, false);
+ COUT << endl;
+ sUserPath = enterValue("user path : ", s_pUpdatePath, false);
+ COUT << endl;
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ Any* pAny;
+ pAny = &aCPArgs[aCPArgs.getLength() - 1];
+ *pAny <<= configmgr::createPropertyValue(ASCII("sourcepath"), sSharePath);
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("updatepath"), sUserPath);
+ }
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("servertype"), sServerType);
+
+ Reference< XMultiServiceFactory > xCfgProvider(
+ xORB->createInstanceWithArguments(
+ ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"),
+ aCPArgs),
+ UNO_QUERY);
+ if (!xCfgProvider.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the configuration provider !\n\n";
+ return 3;
+ }
+
+ cout << "---------------------------------------------------------------\n Configuration Provider created !\n---------------------------------------------------------------" << endl;
+
+ OUString sPath;
+ sPath <<= s_pRootNode;
+ OUString sLocale;
+ sLocale <<= s_pLocale;
+
+ if (m_bInteractive)
+ {
+ sPath = enterValue("nodepath: ", s_pRootNode, false);
+ COUT << endl;
+ if (bLocal)
+ {
+ sLocale = enterValue("locale : ", s_pLocale, false);
+ COUT << endl;
+ }
+ ask_for_a_node_and_test_it(xCfgProvider, sUser, sPasswd, sPath, bLocal, sLocale);
+ }
+ else
+ {
+ sUser <<= "";
+ for(std::vector<OString>::const_iterator it = m_sNodes.begin();
+ it != m_sNodes.end();
+ ++it)
+ {
+ OUString sPath;
+ sPath <<= *it;
+ if (sPath.getLength() > 0)
+ ask_for_a_node_and_test_it(xCfgProvider, sUser, sPasswd, sPath, bLocal, sLocale);
+ }
+ }
+ }
+ catch (Exception& e)
+ {
+ ::flush(cout);
+ cerr << "Caught exception: " << e.Message << endl;
+ return 1;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+void ask_for_a_node_and_test_it(const Reference< XMultiServiceFactory > &xCfgProvider,
+ const OUString& sUser, const OUString &sPasswd,
+ const OUString& sPath, bool bLocal, const OUString &sLocale)
+{
+ try
+ {
+ Sequence< Any > aArgs;
+ aArgs = createSequence(sUser, sPasswd);
+
+ aArgs.realloc(aArgs.getLength() + 1);
+ aArgs[aArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("nodepath"), sPath);
+
+ if (!bLocal)
+ {
+ aArgs.realloc(aArgs.getLength() + 1);
+ aArgs[aArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("locale"), sLocale);
+ }
+
+ Reference< XInterface > xIFace = xCfgProvider->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"),
+ aArgs);
+ cout << "Configuration Read/Write Access created for :" << sPath << endl;
+
+ xChangesBatch = Reference< XChangesBatch >(xIFace, UNO_QUERY);
+
+ Sequence<OUString> aSeq = xCfgProvider->getAvailableServiceNames();
+ showSequence(aSeq);
+
+ test_read_access(xIFace, xCfgProvider);
+ }
+ catch (Exception& e)
+ {
+ ::flush(cout);
+ cerr << "Caught exception: " << e.Message << endl;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+void test(Reference< XHierarchicalName >& xAccessName)
+{
+ if (xAccessName.is())
+ {
+ COUT << "Accessing Node: " << xAccessName->getHierarchicalName() << endl;
+ }
+ else
+ {
+ cerr << "BUG: XHierarchicalName not available" << endl;
+ }
+}
+// -----------------------------------------------------------------------------
+void test(Reference< XNamed >& xAccess)
+{
+ if (xAccess.is())
+ {
+ COUT << "Node is named: " << xAccess->getName() << endl;
+ }
+ else
+ cerr << "BUG: XNamed not available" << endl;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+void write(Reference<XNameAccess >& xAccess)
+{
+ if (xAccess.is())
+ {
+ Sequence<OUString> aNames( xAccess->getElementNames() );
+
+ COUT << "Element Names: (" << aNames.getLength() << ")";
+ for (int i = 0; i < aNames.getLength(); ++i)
+ {
+ COUT << "\n[" << i << "] -\t" << aNames[i];
+ }
+ COUT << endl;
+ }
+ else
+ cerr << "BUG: XNameAccess not available" << endl;
+}
+// -----------------------------------------------------------------------------
+void write(Reference< XChild >& xChild)
+{
+ if (xChild.is())
+ {
+ COUT << "\n[ P ] -\tParent" << endl;
+ }
+ else
+ cerr << "BUG: Parent not available (no XChild)" << endl;
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+
+bool ask(Reference< XInterface >& xIface, const Reference<XMultiServiceFactory> &);
+
+void test_read_access(Reference< XInterface >& xIface, const Reference< XMultiServiceFactory > &xMSF)
+{
+ using com::sun::star::uno::UNO_QUERY;
+ do
+ {
+ COUT << "\n\n---------------------------------------------------------------" << endl;
+ Reference< XNameAccess > xAccess(xIface, UNO_QUERY);
+ Reference< XChild > xChild(xIface, UNO_QUERY);
+ Reference< XHierarchicalName > xAccessPath(xIface,UNO_QUERY);
+ Reference< XNamed > xAccessName(xIface,UNO_QUERY);
+// Reference< XHierarchicalNameAccess >& xAccess(xIface, UNO_QUERY);
+
+ test(xAccessPath);
+ test(xAccessName);
+ write(xAccess);
+ write(xChild);
+
+ if (!m_bInteractive) break;
+ }
+ while (ask(xIface, xMSF));
+}
+
+bool ask(Reference< XInterface >& xIface, const Reference< XMultiServiceFactory > &xMSF)
+{
+ COUT << "\n[ Q ] -> <Quit>";
+ COUT << "\n[ S ] -> <SetValue> ";
+ COUT << endl;
+
+ COUT << "\n:> " << flush;
+ char buf[200] = {0};
+ try
+ {
+ bool bHandled = false;
+ bool bInserted = false;
+
+ if (cin.getline(buf,sizeof buf))
+ {
+ Reference< XInterface > xNext;
+ if ((buf[0] == 'q' || buf[0] == 'Q') && (0 == buf[1]))
+ {
+ return false;
+ }
+ else if (buf[0] == 0)
+ {
+ return true;
+ }
+ else if((buf[0] == 0 || buf[0] == 'o' || buf[0] == 'O') && (0 == buf[1]))
+ {
+/*
+ COUT << "work Offline" << endl;
+ Reference<com::sun::star::configuration::XConfigurationSync> xSync(xMSF, UNO_QUERY);
+
+ Sequence< Any > aArgs2(5);
+ sal_Int32 n=0;
+ aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Setup"));
+ // aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Office.Common"));
+ // aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Office.Java"));
+ // aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Office.Writer"));
+ // aArgs2[n++] <<= configmgr::createPropertyValue(ASCII("path"), ASCII("org.openoffice.Office.ucb.Hierarchy"));
+ xSync->offline(aArgs2);
+ bHandled = true;
+*/
+ }
+ else if((buf[0] == 0 || buf[0] == 's' || buf[0] == 'S') && (0 == buf[1]))
+ {
+ // Replace a Value
+ Reference< XNameAccess > xAccess(xIface, UNO_QUERY);
+
+ COUT << "SetMode, insert a Number" << endl;
+ cin.getline(buf,sizeof buf);
+ bInserted = true;
+ }
+
+ else if ((buf[0] == 'p' || buf[0] == 'P') && (0 == buf[1]))
+ {
+ Reference< XChild > xChild(xIface, UNO_QUERY);
+ if (xChild.is())
+ xNext = xChild->getParent();
+ bHandled = true;
+ }
+
+ if (bHandled == false)
+ {
+ Reference< XNameAccess > xAccess(xIface, UNO_QUERY);
+ Reference< XHierarchicalNameAccess > xDeepAccess(xIface, UNO_QUERY);
+ Reference< XExactName > xExactName(xIface, UNO_QUERY);
+
+ if (xAccess.is() || xDeepAccess.is())
+ {
+ OUString aName;
+ OUString aInput = OUString::createFromAscii(buf);
+
+ if (xExactName.is())
+ {
+ ::rtl::OUString sTemp = xExactName->getExactName(aInput);
+ if (sTemp.getLength())
+ aInput = sTemp;
+ }
+
+ if (xAccess.is() && xAccess->hasByName(aInput))
+ {
+ aName = aInput;
+ }
+ else if (xDeepAccess.is() && xDeepAccess->hasByHierarchicalName(aInput))
+ {
+ aName = aInput;
+ }
+ else if ('0' <= buf[0] && buf[0] <= '9' && xAccess.is())
+ {
+ unsigned int n = unsigned(atoi(buf));
+ Sequence<OUString> aNames = xAccess->getElementNames();
+ if (n < aNames.getLength())
+ aName = aNames[n];
+ }
+
+ if (aName.getLength())
+ {
+ bool bNest = aInput.indexOf(sal_Unicode('/')) >= 0;
+
+ Any aElement = bNest ? ( xDeepAccess.is() ? xDeepAccess->getByHierarchicalName(aName) : Any())
+ : ( xAccess. is() ? xAccess-> getByName(aName) : Any() );
+
+ while (aElement.getValueTypeClass() == TypeClass_ANY)
+ {
+ Any aWrap(aElement);
+ aWrap >>= aElement;
+ }
+ sal_Bool bValue = true;
+ sal_Bool bValueOk = false;
+
+ switch (aElement.getValueTypeClass() )
+ {
+ case TypeClass_INTERFACE: bValue = false; break;
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool* pVal = (sal_Bool*)aElement.getValue();
+ bValueOk = (pVal != 0);
+
+ COUT << "VALUE '" << aName << "' is a BOOLEAN = ";
+ if (!bValueOk)
+ {
+ COUT << "NULL (error!!)";
+ }
+ else if (*pVal)
+ {
+ COUT << "'TRUE'";
+ }
+ else
+ {
+ COUT << "'FALSE'";
+ }
+ COUT << endl;
+ }
+ break;
+ case TypeClass_SHORT:
+ {
+ sal_Int16 aValue;
+ COUT << "VALUE '" << aName << "' is a SHORT (16 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ COUT << aValue;
+ }
+ else
+ cerr << "ERROR RETRIEVING VALUE";
+ COUT << endl;
+ }
+ break;
+ case TypeClass_LONG:
+ {
+
+ sal_Int32 aValue;
+ COUT << "VALUE '" << aName << "' is a INT (32 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ COUT << aValue;
+ }
+ else
+ cerr << "ERROR RETRIEVING VALUE";
+ COUT << endl;
+ }
+ break;
+ case TypeClass_HYPER:
+ {
+ sal_Int64 aValue;
+ COUT << "VALUE '" << aName << "' is a LONG (64 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ COUT << double(aValue);
+ }
+ else
+ cerr << "ERROR RETRIEVING VALUE";
+ COUT << endl;
+ }
+ break;
+ case TypeClass_DOUBLE:
+ {
+ double aValue;
+ COUT << "VALUE '" << aName << "' is a DOUBLE = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ COUT << aValue;
+ }
+ else
+ cerr << "ERROR RETRIEVING VALUE";
+ COUT << endl;
+ }
+ break;
+ case TypeClass_STRING:
+ {
+ OUString aValue;
+ COUT << "VALUE '" << aName << "' is a STRING = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ COUT << "\"" << aValue << "\"";
+ }
+ else
+ cerr << "ERROR RETRIEVING VALUE";
+ COUT << endl;
+ }
+ break;
+ case TypeClass_SEQUENCE:
+ {
+ COUT << "VALUE '" << aName << "' is a SEQUENCE or BINARY" << endl;
+
+ Type aTypeS = configmgr::getSequenceElementType(aElement.getValueType());
+ OUString sType = configmgr::toTypeName(aTypeS.getTypeClass());
+ COUT << "Real type is Sequence<" << sType << ">" << endl;
+ bValueOk = true;
+ }
+ break;
+ case TypeClass_VOID:
+ COUT << "ELEMENT '" << aName << "' is NULL and VOID " << endl;
+ bValueOk = true;
+ break;
+ default:
+ cerr << "Error: ELEMENT '" << aName << "' is of unknown or unrecognized type" << endl;
+ break;
+ }
+ if (bValue)
+ {
+ if (bInserted)
+ {
+ if (aElement.getValueTypeClass() == TypeClass_BOOLEAN ||
+ aElement.getValueTypeClass() == TypeClass_VOID)
+ {
+ COUT << "Set Value (Type=BOOL) to :";
+ cout.flush();
+ cin.getline(buf,sizeof buf);
+ OUString aInput = OUString::createFromAscii(buf);
+ sal_Bool bValue = false;
+
+ Any aValueAny;
+ if (aInput.equalsIgnoreAsciiCase(ASCII("true")))
+ {
+ bValue = true;
+ aValueAny <<= bValue;
+ }
+ else if (aInput.equalsIgnoreAsciiCase(ASCII("false")))
+ {
+ bValue = false;
+ aValueAny <<= bValue;
+ }
+ else if (aInput.equalsIgnoreAsciiCase(ASCII("null")))
+ {
+ }
+
+ Reference< XNameReplace > xNameReplace(xAccess, UNO_QUERY);
+ if (xNameReplace.is())
+ {
+ xNameReplace->replaceByName(aName, aValueAny);
+ commit();
+ }
+ bInserted = false;
+ }
+ else if (aElement.getValueTypeClass() == TypeClass_STRING)
+ {
+ COUT << "set value (type = string) to : ";
+ cout.flush();
+ cin.getline(buf,sizeof buf);
+ Any aValue;
+ aValue <<= buf;
+
+ Reference< XNameReplace > xNameReplace(xAccess, UNO_QUERY);
+ if (xNameReplace.is())
+ {
+ xNameReplace->replaceByName(aName, aValue);
+ commit();
+ }
+ bInserted = false;
+ }
+ else
+ {
+ cerr << "Sorry, only BOOLEAN Values can changed today." << endl;
+ }
+ }
+ prompt_and_wait();
+ return bValueOk ? true : false;
+ }
+
+ if (aElement >>= xNext)
+ {
+ COUT << "Got an Interface for '" << aName << "'" << endl;
+ }
+ else
+ cerr << "Error: Cannot get an Interface for '" << aName << "'" << endl;
+ }
+ else
+ {
+ cerr << "Error: No element \"" << aInput << "\" found." <<endl;
+ }
+ }
+
+ }
+ if (xNext.is())
+ {
+ xIface = xNext;
+ return true;
+ }
+ cerr << "Error: could not obtain the requested Object " << endl;
+ }
+ else
+ {
+ COUT << "Input Error " << endl;
+ return true;
+ }
+ }
+ catch (Exception& e)
+ {
+ cerr << "An Exception occurred: " << e.Message << endl;
+
+ }
+ catch (...)
+ {
+ cerr << "An UNKNOWN Exception occurred !" << endl;
+ }
+
+ prompt_and_wait();
+ return true;
+}
diff --git a/configmgr/workben/apitest/cfgregistry.cxx b/configmgr/workben/apitest/cfgregistry.cxx
new file mode 100644
index 000000000000..5666f62be52d
--- /dev/null
+++ b/configmgr/workben/apitest/cfgregistry.cxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgregistry.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <memory.h>
+#include <stdio.h>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/implbase1.hxx>
+#ifndef _CPPUHELPER_EXTRACT_HXX_
+#include <cppuhelper/extract.hxx>
+#endif
+#include <vos/conditn.hxx>
+#include <osl/diagnose.h>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::xml;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::registry;
+using namespace ::vos;
+using namespace ::cppu;
+//using namespace ::configmgr;
+
+//=============================================================================
+//= a dirty littly class for printing ascii characters
+//=============================================================================
+class OAsciiOutput
+{
+protected:
+ sal_Char* m_pCharacters;
+
+public:
+ OAsciiOutput(const ::rtl::OUString& _rUnicodeChars);
+ ~OAsciiOutput() { delete m_pCharacters; }
+
+ const sal_Char* getCharacters() const { return m_pCharacters; }
+};
+
+//-----------------------------------------------------------------------------
+OAsciiOutput::OAsciiOutput(const ::rtl::OUString& _rUnicodeChars)
+{
+ sal_Int32 nLen = _rUnicodeChars.getLength();
+ m_pCharacters = new sal_Char[nLen + 1];
+ sal_Char* pFillPtr = m_pCharacters;
+ const sal_Unicode* pSourcePtr = _rUnicodeChars.getStr();
+#if OSL_DEBUG_LEVEL > 1
+ sal_Bool bAsserted = sal_False;
+#endif
+ for (sal_Int32 i=0; i<nLen; ++i, ++pFillPtr, ++pSourcePtr)
+ {
+ OSL_ENSURE(bAsserted || !(bAsserted = (*pSourcePtr >= 0x80)),
+ "OAsciiOutput::OAsciiOutput : non-ascii character found !");
+ *pFillPtr = *reinterpret_cast<const sal_Char*>(pSourcePtr);
+ }
+ *pFillPtr = 0;
+}
+
+#define ASCII_STRING(rtlOUString) OAsciiOutput(rtlOUString).getCharacters()
+#define UNI_STRING(asciiString) ::rtl::OUString::createFromAscii(asciiString)
+
+//=============================================================================
+//=============================================================================
+
+#if (defined UNX) || (defined OS2)
+void main( int argc, char * argv[] )
+#else
+void _cdecl main( int argc, char * argv[] )
+#endif
+{
+ TimeValue aTimeout;
+ aTimeout.Seconds = 5;
+ aTimeout.Nanosec = 0;
+
+ Reference< XMultiServiceFactory > xORB = createRegistryServiceFactory(
+ ::rtl::OUString::createFromAscii("l:\\bin.a\\applicat.rdb"),
+ ::rtl::OUString()
+ );
+ if (!xORB.is())
+ {
+ fprintf(stdout, "could not create the service factory !\n\n");
+ return;
+ }
+
+ try
+ {
+ Reference< XSimpleRegistry > xConfigurationRegistry;
+ printf("instantiating the configuration registry access\n\r");
+ xConfigurationRegistry = xConfigurationRegistry.query(
+ xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationRegistry"))
+ );
+
+ const sal_Char* pLayoutNode = "com.sun.star.Inet";
+ printf("opening the registry access to %s\n\r", pLayoutNode);
+ xConfigurationRegistry->open(UNI_STRING(pLayoutNode), sal_False, sal_False);
+
+ printf("retrieving the root key, enumerating elements\n\r");
+ Reference< XRegistryKey > xRoot = xConfigurationRegistry->getRootKey();
+ Sequence< ::rtl::OUString > aKeyNames = xRoot->getKeyNames();
+ const ::rtl::OUString* pKeyNames = aKeyNames.getConstArray();
+ for (sal_Int32 i=0; i<aKeyNames.getLength(); ++i, ++pKeyNames)
+ printf("\t%i\t%s\n\r", i, ASCII_STRING(*pKeyNames));
+
+ const sal_Char* pUpdateKey = "Proxy/NoProxy";
+ printf("retrieving the key for %s\n\r", pUpdateKey);
+ Reference< XRegistryKey > xTabStopsKey = xRoot->openKey(UNI_STRING(pUpdateKey));
+
+/* xTabStopsKey->createKey(UNI_STRING("blupp"));
+
+ Sequence< ::rtl::OUString > sLanguages = xTabStopsKey->getStringListValue();
+ sLanguages.realloc(sLanguages.getLength() + 1);
+ sLanguages[sLanguages.getLength() - 1] = UNI_STRING("ru");
+ xTabStopsKey->setStringListValue(sLanguages);
+*/
+
+ ::rtl::OUString sTest = xTabStopsKey->getStringValue();
+ xTabStopsKey->setStringValue(UNI_STRING("blimp"));
+
+ printf("flushing the changes\n\r");
+ Reference< XFlushable > xCommit(xConfigurationRegistry, UNO_QUERY);
+ xCommit->flush();
+ }
+ catch(RuntimeException& e)
+ {
+ printf("\n\r\n\rcaught an RuntimeException :\n\r");
+ printf(" exception message : %s\n\r", ASCII_STRING(e.Message));
+ return;
+ }
+ catch(Exception& e)
+ {
+ printf("\n\r\n\rcaught an Exception :\n\r");
+ printf(" exception message : %s\n\r", ASCII_STRING(e.Message));
+ return;
+ }
+}
diff --git a/configmgr/workben/apitest/cfgupdate.cxx b/configmgr/workben/apitest/cfgupdate.cxx
new file mode 100644
index 000000000000..bde03bba9600
--- /dev/null
+++ b/configmgr/workben/apitest/cfgupdate.cxx
@@ -0,0 +1,435 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgupdate.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#define _PRIVATE_TEST_
+
+#include <iostream>
+using namespace std;
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
+
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <osl/time.h>
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Any.h>
+
+#include "createpropertyvalue.hxx"
+
+#include "typeconverter.hxx"
+
+// #include <com/sun/star/configuration/XConfigurationSync.hpp>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+//using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+using ::rtl::OString;
+//using namespace ::configmgr;
+
+using namespace ::cppu;
+
+#define ASCII(x) ::rtl::OUString::createFromAscii(x)
+
+ostream& operator << (ostream& out, rtl::OUString const& aStr)
+{
+ sal_Unicode const* const pStr = aStr.getStr();
+ sal_Unicode const* const pEnd = pStr + aStr.getLength();
+ for (sal_Unicode const* p = pStr; p < pEnd; ++p)
+ if (0 < *p && *p < 127) // ASCII
+ out << char(*p);
+ else
+ out << "[\\u" << hex << *p << "]";
+ return out;
+}
+
+void showSequence(const Sequence<OUString> &aSeq)
+{
+ OUString aArray;
+ const OUString *pStr = aSeq.getConstArray();
+ for (int i=0;i<aSeq.getLength();i++)
+ {
+ OUString aStr = pStr[i];
+ // aArray += aStr + ASCII(", ");
+ cout << aStr << endl;
+ }
+ volatile int dummy = 0;
+}
+
+//=============================================================================
+//=============================================================================
+void test_read_access(Reference< XInterface >& xIface, Reference< XMultiServiceFactory > &xMSF);
+//=============================================================================
+struct prompt_and_wait
+{
+ char const* myText;
+ prompt_and_wait(char const* text = "") : myText(text) {}
+ ~prompt_and_wait()
+ {
+ cout << myText << ">" << endl;
+ int const mx = int( (+0u - +1u) >> 1);
+
+ char c=0;
+ if (cin.get(c) && c != '\n')
+ cin.ignore(mx,'\n');
+ }
+};
+static prompt_and_wait exit_prompt("Quitting\nQ");
+
+
+// -----------------------------------------------------------------------------
+Sequence<Any> createSequence(const OUString &sUser, const OUString &sPasswd)
+{
+ Sequence< Any > aCPArgs;
+
+ if (sUser.getLength() > 0)
+ {
+ aCPArgs.realloc(1);
+ aCPArgs[0] <<= configmgr::createPropertyValue(ASCII("user"), sUser);
+ }
+ if (sPasswd.getLength() > 0)
+ {
+ aCPArgs.realloc(2);
+ aCPArgs[1] <<= configmgr::createPropertyValue(ASCII("password"), sPasswd);
+ }
+ return aCPArgs;
+}
+
+//=============================================================================
+#include <string.h>
+#if (defined UNX) || (defined OS2)
+#else
+#include <conio.h>
+#endif
+
+OString input(const char* pDefaultText, char cEcho)
+{
+ // PRE: a Default Text would be shown, cEcho is a Value which will show if a key is pressed.
+ const int MAX_INPUT_LEN = 500;
+ char aBuffer[MAX_INPUT_LEN];
+
+ strcpy(aBuffer, pDefaultText);
+ int nLen = strlen(aBuffer);
+
+#ifdef WNT
+ char ch = '\0';
+
+ cout << aBuffer;
+ cout.flush();
+
+ while(ch != 13)
+ {
+ ch = getch();
+ if (ch == 8)
+ {
+ if (nLen > 0)
+ {
+ cout << "\b \b";
+ cout.flush();
+ --nLen;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ cout << "\a";
+ cout.flush();
+ }
+ }
+ else if (ch != 13)
+ {
+ if (nLen < MAX_INPUT_LEN)
+ {
+ if (cEcho == 0)
+ {
+ cout << ch;
+ }
+ else
+ {
+ cout << cEcho;
+ }
+ cout.flush();
+ aBuffer[nLen++] = ch;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ cout << "\a";
+ cout.flush();
+ }
+ }
+ }
+#else
+ if (!cin.getline(aBuffer,sizeof aBuffer))
+ return OString();
+#endif
+ return OString(aBuffer);
+}
+
+// -----------------------------------------------------------------------------
+rtl::OUString enterValue(const char* _aStr, const char* _aDefault, bool _bIsAPassword)
+{
+ cout << _aStr;
+ cout.flush();
+ OString aTxt = input(_aDefault, _bIsAPassword ? '*' : 0);
+
+ OUString sValue = OUString::createFromAscii(aTxt);
+ return sValue;
+}
+
+// -----------------------------------------------------------------------------
+Reference< XNameAccess > beginChanges(Reference< XMultiServiceFactory > xFactory, OUString sPath)
+{
+ Sequence< Any > aArgs(1);
+ aArgs[0] <<= configmgr::createPropertyValue(ASCII("nodepath"),sPath);
+
+ cout << "starting update for node:" << sPath << endl;
+
+ Reference< XNameAccess > xTree(xFactory->createInstanceWithArguments(OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"),
+ aArgs), UNO_QUERY);
+
+ return xTree;
+}
+
+template <class Type>
+// -----------------------------------------------------------------------------
+void update(Reference< XInterface > xIFace, OUString sRelPath, Type sValue)
+{
+ Reference< XHierarchicalPropertySet > xTree(xIFace, UNO_QUERY);
+ Any aValue;
+ aValue <<= sValue;
+
+ cout << "updating node:" << sRelPath << endl;
+ xTree->setHierarchicalPropertyValue(sRelPath, aValue);
+}
+
+// -----------------------------------------------------------------------------
+Reference< XHierarchicalPropertySet > insertTree(Reference< XInterface > xIFace, OUString aName)
+{
+ if (!aName.getLength())
+ aName = enterValue("/nEnter a Tree to insert: ", "", false);
+
+ Reference< XSingleServiceFactory > xFactory(xIFace, UNO_QUERY);
+ Reference< XHierarchicalPropertySet > xNewElement(xFactory->createInstance(), UNO_QUERY);
+
+ cout << "inserting new tree element:" << aName << endl;
+
+ Any aTree;
+ aTree <<= xNewElement;
+ Reference< XNameContainer >(xFactory, UNO_QUERY)->insertByName(aName, aTree);
+
+ return xNewElement;
+}
+
+// -----------------------------------------------------------------------------
+void removeTree(Reference< XInterface > xIFace, OUString aName)
+{
+ if (!aName.getLength())
+ aName = enterValue("/nEnter a Tree to remove: ", "", false);
+
+ cout << "removing new tree element:" << aName << endl;
+
+ Reference< XNameContainer >(xIFace, UNO_QUERY)->removeByName(aName);
+}
+
+// -----------------------------------------------------------------------------
+void commitChanges(Reference< XInterface > xIFace)
+{
+ cout << "committing changes:" << endl;
+
+ Reference< XChangesBatch > xChangesBatch(xIFace, UNO_QUERY);
+ xChangesBatch->commitChanges();
+}
+
+// -----------------------------------------------------------------------------
+void displayTree(Reference< XNameAccess > xIFace, sal_Int32 nLevel)
+{
+ const char* pTab = " ";
+ Sequence<OUString> aNames( xIFace->getElementNames() );
+ for (int i = 0; i < aNames.getLength(); ++i)
+ {
+ Any aElement = xIFace->getByName(aNames[i]);
+ Reference< XNameAccess > xAccess;
+ Reference< XSingleServiceFactory > xFactory;
+ aElement >>= xFactory;
+ aElement >>= xAccess;
+
+ cout << endl;
+ for (int j = 0; j < nLevel; j++)
+ cout << " ";
+
+ if (xAccess.is())
+ {
+ OUString sType;
+ if (xFactory.is())
+ sType = OUString::createFromAscii(" type = 'set' " );
+
+ cout << "<" << aNames[i] << sType << ">";
+ displayTree(xAccess, nLevel + 1);
+ cout << endl << "</" << aNames[i] << ">";
+ }
+ else
+ cout << "<" << aNames[i] << "/>";
+
+ }
+ ::flush(cout);
+}
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- M A I N ----------------------------------
+// -----------------------------------------------------------------------------
+
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+int _cdecl main( int argc, char * argv[] )
+#endif
+{
+ TimeValue aTimeout;
+ aTimeout.Seconds = 5;
+ aTimeout.Nanosec = 0;
+
+ // cout << " Please insert Text: ";
+ // cout.flush();
+ // OString aTxt = input("Der Text", 0);
+ // cout << endl << "You inserted: " << aTxt.getStr() << endl;
+ //
+ // cout << "Please insert Password: ";
+ // cout.flush();
+ // OString aPasswd = input("", '*');
+ // cout << endl << "You inserted: " << aPasswd.getStr() << endl;
+
+ try
+ {
+ OUString const sServiceRegistry = OUString::createFromAscii( argc > 1 ? argv[1] : "applicat.rdb" );
+ Reference< XMultiServiceFactory > xORB = createRegistryServiceFactory(
+ sServiceRegistry,
+ ::rtl::OUString()
+ );
+ if (!xORB.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the service factory !\n\n";
+ return 1;
+ }
+ cout << "Service factory created !\n---------------------------------------------------------------" << endl;
+
+ Sequence< Any > aCPArgs;
+
+ /*OUString sServerType = enterValue("Enter Servertype: ", "remote", false);
+ cout << endl;*/
+
+
+ rtl::OUString sFilePath;
+ rtl::OUString sPort;
+ rtl::OUString sUser;
+
+ sUser = enterValue("Enter User: ", "user1", false);
+ cout << endl;
+
+ OUString sPasswd;// = enterValue("Enter Password: ", "", true);
+ cout << endl;
+
+ aCPArgs = createSequence(sUser, sPasswd);
+
+ Reference< XMultiServiceFactory > xCfgProvider(
+ xORB->createInstanceWithArguments(
+ ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"),
+ aCPArgs),
+ UNO_QUERY);
+ if (!xCfgProvider.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the configuration provider !\n\n";
+ return 3;
+ }
+
+ Reference< XNameAccess > xUpdateAccess;
+
+// now do updates for the user
+ xUpdateAccess = beginChanges(xCfgProvider, OUString::createFromAscii("org.openoffice.Security"));
+ displayTree(xUpdateAccess, 0);
+
+ update(xUpdateAccess, OUString::createFromAscii("_3D_Engine/Dithering"), sal_Bool(sal_False));
+
+/* xUpdateAccess = beginChanges(xCfgProvider, OUString::createFromAscii("org.openoffice.Inet"));
+
+ update(xUpdateAccess, OUString::createFromAscii("Proxy/FTP/Port"), sal_Int32(11));
+ update(xUpdateAccess, OUString::createFromAscii("Proxy/FTP/Name"), OUString::createFromAscii("Test3"));
+ update(xUpdateAccess, OUString::createFromAscii("DNS/IP_Address"), OUString::createFromAscii("Test4"));
+*/
+ commitChanges(xUpdateAccess);
+
+// now do updates with inserting and removing of nodes
+
+ xUpdateAccess = beginChanges(xCfgProvider, OUString::createFromAscii("org.openoffice.Security/MountPoints"));
+ displayTree(xUpdateAccess, 0);
+
+ Reference< XHierarchicalPropertySet > xTree = insertTree(xUpdateAccess, OUString());
+ update(xUpdateAccess, OUString::createFromAscii("InstallationDirectory/Directory"), OUString::createFromAscii("Test1"));
+ removeTree(xUpdateAccess, OUString());
+ commitChanges(xUpdateAccess);
+ }
+ catch (Exception& e)
+ {
+ ::flush(cout);
+ cerr << "Caught exception: " << e.Message << endl;
+ }
+/*
+ catch (...)
+ {
+ ::flush(cout);
+ cerr << "BUG: Caught UNKNOWN exception (?) " << endl;
+ }
+*/
+ return 0;
+}
+
diff --git a/configmgr/workben/apitest/makefile.mk b/configmgr/workben/apitest/makefile.mk
new file mode 100644
index 000000000000..08b46a53f873
--- /dev/null
+++ b/configmgr/workben/apitest/makefile.mk
@@ -0,0 +1,128 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.15 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source
+
+PRJNAME=configmgr
+
+TARGET=cfgapi
+TARGET2=cfgreg
+TARGET3=cfgadduser
+TARGET4=cfgadmin
+TARGET5=cfgupdate
+TARGET6=cfgapi_timetest
+TARGETTYPE=CUI
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+# ... common for all test executables ..............................
+APPSTDLIBS=\
+ $(SALLIB) \
+ $(VOSLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB)
+
+# ... cfgapi ..............................
+APP1STDLIBS = $(APPSTDLIBS)
+
+APP1STDLIBS+=$(STDLIBCPP)
+
+APP1TARGET= $(TARGET)
+APP1OBJS= \
+ $(SLO)$/cfgapi.obj \
+ $(SLO)$/strimpl.obj \
+ $(SLO)$/typeconverter.obj \
+ $(SLO)$/simpletypehelper.obj \
+
+# ... cfgapi_timetest ..............................
+APP6STDLIBS = $(APPSTDLIBS)
+
+APP6STDLIBS+=$(STDLIBCPP)
+
+APP6TARGET= $(TARGET6)
+APP6OBJS= \
+ $(SLO)$/cfgapi_timetest.obj \
+ $(SLO)$/strimpl.obj \
+ $(SLO)$/typeconverter.obj \
+ $(SLO)$/simpletypehelper.obj \
+
+# ... cfgreg ..............................
+APP2STDLIBS = $(APPSTDLIBS)
+
+APP2STDLIBS+=$(STDLIBCPP)
+
+APP2TARGET= $(TARGET2)
+APP2OBJS= \
+ $(SLO)$/cfgregistry.obj \
+
+# ... cfgadduser ..............................
+APP3STDLIBS = $(APPSTDLIBS)
+
+APP3STDLIBS+=$(STDLIBCPP)
+
+APP3TARGET= $(TARGET3)
+APP3OBJS= \
+ $(SLO)$/cfgadduser.obj \
+
+# ... cfgadmin ..............................
+APP4STDLIBS = $(APPSTDLIBS)
+
+APP4STDLIBS+=$(STDLIBCPP)
+
+APP4TARGET= $(TARGET4)
+APP4OBJS= \
+ $(SLO)$/cfgadmin.obj \
+ $(SLO)$/strimpl.obj \
+ $(SLO)$/typeconverter.obj \
+ $(SLO)$/simpletypehelper.obj \
+
+# ... cfgupdate ..............................
+APP5STDLIBS = $(APPSTDLIBS)
+
+APP5STDLIBS+=$(STDLIBCPP)
+
+APP5TARGET= $(TARGET5)
+APP5OBJS= \
+ $(SLO)$/cfgupdate.obj \
+ $(SLO)$/strimpl.obj \
+ $(SLO)$/typeconverter.obj \
+ $(SLO)$/simpletypehelper.obj \
+
+.INCLUDE : target.mk
+
+
diff --git a/configmgr/workben/apitest/sregistry b/configmgr/workben/apitest/sregistry
new file mode 100644
index 000000000000..f4f353181f25
--- /dev/null
+++ b/configmgr/workben/apitest/sregistry
@@ -0,0 +1,8 @@
+[configuration]
+servertype=remote
+[RemoteRegistry]
+Server=munch-11072:100
+Timeout=2500
+[LocalRegistry]
+rootpath="G:\Configuration"
+
diff --git a/configmgr/workben/local_io/cfgfile.cxx b/configmgr/workben/local_io/cfgfile.cxx
new file mode 100644
index 000000000000..90f6578385de
--- /dev/null
+++ b/configmgr/workben/local_io/cfgfile.cxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfgfile.cxx,v $
+ * $Revision: 1.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+
+// -----------------------------------------------------------------------------
+// ------------------------------------ main ------------------------------------
+// -----------------------------------------------------------------------------
+
+/*
+ OUString operator+(const OUString &a, const OUString &b)
+ {
+ OUString c = a;
+ c += b;
+ return c;
+ }
+*/
+
+namespace configmgr
+{
+ void simpleMappingTest();
+
+ void importTest();
+ void exportTest();
+
+ void hierarchyTest();
+ //void simpleTest();
+ void speedTest();
+ void stringTest();
+ void classTest();
+ void hash_test();
+ void testRefs();
+ void ConfigName();
+
+ void oslTest();
+}
+
+
+
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+ int _cdecl main( int argc, char * argv[] )
+#endif
+{
+
+// configmgr::hierarchyTest();
+
+
+// configmgr::importTest();
+// configmgr::exportTest();
+// configmgr::speedTest();
+// configmgr::simpleTest();
+
+// configmgr::simpleMappingTest();
+// configmgr::stringTest();
+// configmgr::classTest();
+
+// configmgr::hash_test();
+
+ // configmgr::testRefs();
+ // configmgr::ConfigName();
+
+ configmgr::oslTest();
+ return 0;
+}
+
+
diff --git a/configmgr/workben/local_io/cfglocal.cxx b/configmgr/workben/local_io/cfglocal.cxx
new file mode 100644
index 000000000000..da01b4f51232
--- /dev/null
+++ b/configmgr/workben/local_io/cfglocal.cxx
@@ -0,0 +1,623 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cfglocal.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#define _PRIVATE_TEST_
+
+#include <memory.h>
+#include <string.h>
+#include <stdio.h>
+#include <vos/socket.hxx>
+#include "attributes.hxx"
+
+#ifndef _CONFIGMGR_SESSION_REMOTESESSION_HXX_
+#include "remotesession.hxx"
+#endif
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <vos/conditn.hxx>
+
+#include <osl/time.h>
+
+#include "localsession.hxx"
+#include "confname.hxx"
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::xml;
+using namespace ::vos;
+using namespace ::cppu;
+using namespace ::configmgr;
+using namespace rtl;
+
+// #define USE_LAYOUT_NODE
+
+//=============================================================================
+//= a dirty littly class for printing ascii characters
+//=============================================================================
+class OAsciiOutput
+{
+protected:
+ sal_Char* m_pCharacters;
+
+public:
+ OAsciiOutput(const ::rtl::OUString& _rUnicodeChars);
+ ~OAsciiOutput() { delete m_pCharacters; }
+
+ const sal_Char* getCharacters() const { return m_pCharacters; }
+};
+
+//-----------------------------------------------------------------------------
+OAsciiOutput::OAsciiOutput(const ::rtl::OUString& _rUnicodeChars)
+{
+ sal_Int32 nLen = _rUnicodeChars.getLength();
+ m_pCharacters = new sal_Char[nLen + 1];
+ sal_Char* pFillPtr = m_pCharacters;
+ const sal_Unicode* pSourcePtr = _rUnicodeChars.getStr();
+#ifdef DBG_UTIL
+ sal_Bool bAsserted = sal_False;
+#endif
+ for (sal_Int32 i=0; i<nLen; ++i, ++pFillPtr, ++pSourcePtr)
+ {
+ OSL_ENSURE(bAsserted || !(bAsserted = (*pSourcePtr >= 0x80)),
+ "OAsciiOutput::OAsciiOutput : non-ascii character found !");
+ *pFillPtr = *reinterpret_cast<const sal_Char*>(pSourcePtr);
+ }
+ *pFillPtr = 0;
+}
+
+#define ASCII_STRING(rtlOUString) OAsciiOutput(rtlOUString).getCharacters()
+#define UNI_STRING(salCharPtr) ::rtl::OUString::createFromAscii(salCharPtr)
+
+//=============================================================================
+//= OOpenNodeCallback
+//=============================================================================
+typedef ::cppu::WeakImplHelper1< sax::XDocumentHandler > OOpenNodeCallback_Base;
+class OOpenNodeCallback : public IOpenObjectCallback, public OOpenNodeCallback_Base
+{
+protected:
+ OUString m_sNodeId;
+ ::vos::OCondition& m_rFinishCondition;
+
+ enum ACTION { STARTELEMENT, CHARACTERS, ENDELEMENT };
+ ACTION m_eLastAction;
+ sal_Int32 m_nLevel;
+ sal_Bool m_bCloseStartTag;
+
+protected:
+ ~OOpenNodeCallback()
+ {
+ }
+
+public:
+ OOpenNodeCallback(::vos::OCondition& _rFinishCond) : m_rFinishCondition(_rFinishCond), m_nLevel(0), m_eLastAction(ENDELEMENT), m_bCloseStartTag(sal_False) { }
+
+ OUString getNodeId() const { return m_sNodeId; }
+
+ // IOpenObjectCallback
+ virtual void gotObjectId(const OUString &aName);
+
+ // IDataRequestCallback
+ virtual Reference< sax::XDocumentHandler > getDataReader() { return static_cast< sax::XDocumentHandler* >(this); }
+
+ // IRequestCallback
+ virtual void acknowledged(sal_Int32 _nTransId);
+ virtual void failed(sal_Int32 _nErrorCode);
+ virtual void done(const StatusInfo& _rStatus);
+
+ // IInterface
+ virtual void SAL_CALL acquire( ) throw (::com::sun::star::uno::RuntimeException) { OOpenNodeCallback_Base::acquire(); }
+ virtual void SAL_CALL release( ) throw (::com::sun::star::uno::RuntimeException) { OOpenNodeCallback_Base::release(); }
+
+ // XDocumentHandler
+ virtual void SAL_CALL startDocument( ) throw(sax::SAXException, RuntimeException) { }
+ virtual void SAL_CALL endDocument( ) throw(sax::SAXException, RuntimeException) { }
+ virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const Reference< sax::XAttributeList >& xAttribs ) throw(sax::SAXException, RuntimeException);
+ virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw(sax::SAXException, RuntimeException);
+ virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw(sax::SAXException, RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw(sax::SAXException, RuntimeException) { }
+ virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw(sax::SAXException, RuntimeException) { }
+ virtual void SAL_CALL setDocumentLocator( const Reference< sax::XLocator >& xLocator ) throw(sax::SAXException, RuntimeException) { }
+};
+
+//.............................................................................
+inline void linefeed()
+{
+ // printf("\n");
+}
+
+//.............................................................................
+void printTabs(sal_Int32 _nCount)
+{
+ sal_Char* pBuffer = new sal_Char[2 * _nCount + 1];
+ memset(pBuffer, ' ', 2 * _nCount);
+ pBuffer[2 * _nCount] = 0;
+ // printf(pBuffer);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL OOpenNodeCallback::startElement( const ::rtl::OUString& _rName, const Reference< sax::XAttributeList >& xAttribs ) throw(sax::SAXException, RuntimeException)
+{
+ switch (m_eLastAction)
+ {
+ case STARTELEMENT:
+ if (m_bCloseStartTag)
+ {
+ // printf(">");
+ }
+
+ m_bCloseStartTag = sal_False;
+ // no break
+ case CHARACTERS:
+ case ENDELEMENT:
+ linefeed();
+ printTabs(m_nLevel);
+ break;
+ }
+ m_eLastAction = STARTELEMENT;
+ ++m_nLevel;
+ // printf("<%s", ASCII_STRING(_rName));
+ m_bCloseStartTag = sal_True;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL OOpenNodeCallback::endElement( const ::rtl::OUString& _rName ) throw(sax::SAXException, RuntimeException)
+{
+ --m_nLevel;
+ switch (m_eLastAction)
+ {
+ case STARTELEMENT:
+ if (m_bCloseStartTag)
+ {
+ // printf("/>");
+ }
+
+ m_bCloseStartTag = sal_False;
+ break;
+ case ENDELEMENT:
+ linefeed();
+ printTabs(m_nLevel);
+ // dont break
+ case CHARACTERS:
+ // printf("</%s>", ASCII_STRING(_rName));
+ break;
+ }
+ m_eLastAction = ENDELEMENT;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL OOpenNodeCallback::characters( const ::rtl::OUString& _rChars ) throw(sax::SAXException, RuntimeException)
+{
+ if (STARTELEMENT == m_eLastAction)
+ {
+ if (m_bCloseStartTag && _rChars.trim().getLength())
+ {
+ // printf(">");
+ m_bCloseStartTag = sal_False;
+ }
+ }
+ if (_rChars.trim().getLength() != 0)
+ {
+ // printf("%s", ASCII_STRING(_rChars));
+ m_eLastAction = CHARACTERS;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void OOpenNodeCallback::gotObjectId(const OUString &_nId)
+{
+ m_sNodeId = _nId;
+ // printf("object id %i\n", m_nNodeId);
+}
+
+//-----------------------------------------------------------------------------
+void OOpenNodeCallback::acknowledged(sal_Int32 _nTransId)
+{
+ // printf("acknowledged, transaction id : %i\n", _nTransId);
+}
+
+//-----------------------------------------------------------------------------
+void OOpenNodeCallback::failed(sal_Int32 _nErrorCode)
+{
+ // printf("failed because of a connection error (%i)\n", _nErrorCode);
+ m_rFinishCondition.set();
+}
+
+//-----------------------------------------------------------------------------
+void OOpenNodeCallback::done(const StatusInfo& _rStatus)
+{
+ if (_rStatus.nCode)
+ {
+ printf("\n\ndone, but had an error : %s\n", ASCII_STRING(_rStatus.sMessage));
+ }
+ else
+ {
+ // printf("\n\nsuccessfully done\n", ASCII_STRING(_rStatus.sMessage));
+ }
+
+ m_rFinishCondition.set();
+}
+
+//=============================================================================
+//= ONodeUpdater
+//=============================================================================
+class ONodeUpdater : public IDOMNodeDataProvider
+{
+ sal_Bool m_bWriterLevel;
+ sal_Bool m_bAdd;
+public:
+ ONodeUpdater(sal_Bool _bStartAtWriterLevel, sal_Bool bAdd) : m_bWriterLevel(_bStartAtWriterLevel), m_bAdd(bAdd) { }
+
+ virtual void writeNodeData(const Reference< sax::XDocumentHandler >& _rHandler);
+};
+
+//-----------------------------------------------------------------------------
+void ONodeUpdater::writeNodeData(const Reference< sax::XDocumentHandler >& _rHandler)
+{
+ AttributeListImpl *pAttr = new AttributeListImpl;
+ Reference< sax::XAttributeList > xEmptyAttrList = pAttr;
+
+ pAttr = new AttributeListImpl;
+ pAttr->addAttribute(UNI_STRING("type"),UNI_STRING("CDATA"),UNI_STRING("string"));
+ Reference< sax::XAttributeList > xStringAttrList = pAttr;
+
+ if (m_bWriterLevel)
+ _rHandler->startElement(UNI_STRING("Writer"), xEmptyAttrList);
+#ifdef USE_LAYOUT_NODE
+ _rHandler->startElement(UNI_STRING("Layout"), xEmptyAttrList);
+ _rHandler->startElement(UNI_STRING("TabStops"), xEmptyAttrList);
+ if (m_bAdd)
+ _rHandler->characters(UNI_STRING("0.90"));
+ else
+ _rHandler->characters(UNI_STRING("99.99"));
+
+ _rHandler->endElement(UNI_STRING("TabStops"));
+ _rHandler->endElement(UNI_STRING("Layout"));
+#else
+ // _rHandler->startElement(UNI_STRING("com.sun.star.office.Setup"), xEmptyAttrList);
+ _rHandler->startElement(UNI_STRING("Modules"), xEmptyAttrList);
+ _rHandler->startElement(UNI_STRING("StandFonts"), xEmptyAttrList);
+ _rHandler->startElement(UNI_STRING("Standard"), xStringAttrList);
+ _rHandler->startElement(UNI_STRING("value"), xEmptyAttrList);
+ if (m_bAdd)
+ _rHandler->characters(UNI_STRING("Arial"));
+ else
+ _rHandler->characters(UNI_STRING("Courier"));
+
+ _rHandler->endElement(UNI_STRING("value"));
+ _rHandler->endElement(UNI_STRING("Standard"));
+ _rHandler->endElement(UNI_STRING("StandFonts"));
+ _rHandler->endElement(UNI_STRING("Modules"));
+ // _rHandler->endElement(UNI_STRING("com.sun.star.office.Setup"));
+
+ _rHandler->ignorableWhitespace(OUString());
+#endif
+ if (m_bWriterLevel)
+ _rHandler->endElement(UNI_STRING("Writer"));
+}
+
+//=============================================================================
+//= OSessionListener
+//=============================================================================
+class OSessionListener : public ISessionListener
+{
+protected:
+ oslInterlockedCount m_refCount;
+
+public:
+ // ISessionListener
+ virtual void nodeUpdated(const ::rtl::OUString& _rNodePath);
+ virtual void nodeDeleted(const ::rtl::OUString& _rNodePath);
+ virtual void nodeAdded(const ::rtl::OUString& _rNodePath);
+
+ // IInterface
+ virtual void SAL_CALL acquire( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL release( ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+//-----------------------------------------------------------------------------
+void OSessionListener::nodeUpdated(const ::rtl::OUString& _rNodePath)
+{
+ // printf("[listener] : a node was updated, node path : %s\n", ASCII_STRING(_rNodePath));
+}
+
+//-----------------------------------------------------------------------------
+void OSessionListener::nodeDeleted(const ::rtl::OUString& _rNodePath)
+{
+ // printf("[listener] : a node was deleted, node path : %s\n", ASCII_STRING(_rNodePath));
+}
+
+//-----------------------------------------------------------------------------
+void OSessionListener::nodeAdded(const ::rtl::OUString& _rNodePath)
+{
+ // printf("\n[listener] : a node was added, node path : %s", ASCII_STRING(_rNodePath));
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL OSessionListener::acquire( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ osl_incrementInterlockedCount(&m_refCount);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL OSessionListener::release( ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if (!osl_decrementInterlockedCount(&m_refCount))
+ delete this;
+}
+
+//=============================================================================
+//=============================================================================
+
+//=============================================================================
+static ::rtl::OUString sHost;
+static sal_Int32 nPort;
+static ::rtl::OUString sRegistry = ::rtl::OUString::createFromAscii("applicat.rdb");
+
+//=============================================================================
+sal_Bool collectArgs(int argc, char * argv[])
+{
+ if (argc > 1)
+ {
+ sal_Char* pConnectTo = argv[1];
+ sal_Char* pSeparator = strchr(pConnectTo, ':');
+ if (pSeparator && (0 != *(pSeparator + 1)))
+ {
+ sHost = ::rtl::OUString(pConnectTo, pSeparator - pConnectTo, RTL_TEXTENCODING_ASCII_US);
+ nPort = ::rtl::OUString::createFromAscii(pSeparator + 1).toInt32();
+
+ if (argc > 2)
+ sRegistry = ::rtl::OUString::createFromAscii(argv[2]);
+ return sal_True;
+ }
+ }
+
+ printf("cfgclient - registry server client test ...\n\r\n\r");
+ printf("usage :\n\r");
+ printf(" cfgclient <server>:<port> [<registry file>]\n\r\n\r");
+ printf(" <server> : machine to connect to\n\r");
+ printf(" <port> : port to connect to\n\r");
+ printf(" <registry file> : (optional) registry to bootstrap from. defaulted to \"applicat.rdb\"\n\r\n\r");
+ return sal_False;
+}
+
+//=============================================================================
+
+#if (defined UNX) || (defined OS2)
+void main( int argc, char * argv[] )
+#else
+void _cdecl main( int argc, char * argv[] )
+#endif
+{
+ Reference< XMultiServiceFactory > xORB;
+ try
+ {
+ xORB = createRegistryServiceFactory(sRegistry, ::rtl::OUString());
+ }
+ catch (Exception& e)
+ {
+ printf("could not bootstrap the services from %s\n\r", ASCII_STRING(sRegistry));
+ printf(" (error message : %s)", ASCII_STRING(e.Message));
+ }
+
+ if (!xORB.is())
+ {
+ fprintf(stdout, "could not create the service factory !");
+ return;
+ }
+
+ ORef< OSessionListener > xListener = new OSessionListener;
+ {
+/*
+ ORemoteSession aSession(xORB);
+ // --------- connect ----------
+ sal_Bool bSuccess = aSession.connect(sHost, nPort, &aTimeout);
+ if (!bSuccess)
+ {
+ printf("could not connect to the server (error : %i) ...", aSession.getConnectionError());
+ return;
+ }
+*/
+
+ void testSession(const Reference< XMultiServiceFactory > &xORB, bool bPrint);
+
+ for (int i=0;i<100;i++)
+ {
+ TimeValue aStartTime, aEndTime;
+ osl_getSystemTime(&aStartTime);
+ testSession(xORB, false);
+ osl_getSystemTime(&aEndTime);
+
+ sal_Int32 nSeconds = aEndTime.Seconds - aStartTime.Seconds;
+ sal_Int32 nNanoSec = aEndTime.Nanosec - aStartTime.Nanosec;
+ if (nNanoSec < 0)
+ {
+ nNanoSec = 1000000000 - nNanoSec;
+ nSeconds++;
+ }
+
+ cout << "Time: " << nSeconds << ". " << nNanoSec << endl;
+ }
+ }
+}
+
+void testSession(const Reference< XMultiServiceFactory > &xORB, bool bPrint)
+{
+ TimeValue aTimeout;
+ aTimeout.Seconds = 5;
+ aTimeout.Nanosec = 0;
+
+
+ // create it .. and connect
+ LocalSession aSession(xORB);
+
+ // --------- openSession ----------
+
+ OUString aRootPath = OUString::createFromAscii("f:/local/SRC598/configmgr/workben/local_io");
+ // f:/local/SRC595/configmgr/workben/local_io);
+ aSession.open(aRootPath);
+
+ if (aSession.isOpen())
+ {
+ if (bPrint) printf("\nopened the session ...");
+ }
+ else
+ {
+ printf("\ncould not open the session ... exiting\n\n");
+ return;
+ }
+
+ // aSession.setListener(xListener.getBodyPtr());
+
+ OCondition aWaitForSomething;
+ aWaitForSomething.reset();
+
+ // --------- openNode ----------
+ char* pWriterNode = "com.sun.star.Setup/Modules";
+ if (bPrint) printf("\nsending an openNode request for %s ...\n", pWriterNode);
+ ORef< OOpenNodeCallback > xOpenCallback = new OOpenNodeCallback(aWaitForSomething);
+ aSession.openNode(UNI_STRING(pWriterNode), 2, xOpenCallback.getBodyPtr());
+
+ aTimeout.Seconds = 30;
+ switch (aWaitForSomething.wait(&aTimeout))
+ {
+ case ICondition::result_error:
+ printf("error while waiting for the callback ... exiting\n\n");
+ return;
+ case ICondition::result_timeout:
+ if (bPrint) printf("timed out ... exiting\n\n");
+ return;
+ }
+
+ OUString sOpenedNode = xOpenCallback->getNodeId();
+
+// aSession.getNode(UNI_STRING("com.sun.star.Spreadsheet"), NULL);
+//
+// // --------- getNode (1) ----------
+//#ifdef USE_LAYOUT_NODE
+// char* pLayoutNode = "com.sun.star.office.Setup/Modules";
+//#else
+ char* pLayoutNode = "com.sun.star.Setup/Modules";
+//#endif
+// printf("\nsending an getNode request for %s ...\n", pLayoutNode);
+// aWaitForSomething.reset();
+// aSession.getNode(UNI_STRING(pLayoutNode), new OOpenNodeCallback(aWaitForSomething));
+//
+// switch (aWaitForSomething.wait(&aTimeout))
+// {
+// case ICondition::result_error:
+// printf("error while waiting for the callback ... exiting\n\n");
+// return;
+// case ICondition::result_timeout:
+// printf("timed out ... exiting\n\n");
+// return;
+// }
+
+ // --------- addNode ----------
+ if (bPrint) printf("\n\naddNode ....");
+ ONodeUpdater aAddTabstops(sal_False, true); // true = WRITER LEVEL
+ aWaitForSomething.reset();
+ aSession.addNode(sOpenedNode, UNI_STRING(pLayoutNode), &aAddTabstops, new OOpenNodeCallback(aWaitForSomething));
+ switch (aWaitForSomething.wait(&aTimeout))
+ {
+ case ICondition::result_error:
+ printf("error while waiting for the callback ... exiting\n\n");
+ return;
+ case ICondition::result_timeout:
+ if (bPrint) printf("timed out ... exiting\n\n");
+ return;
+ }
+
+ // --------- updateNode ----------
+ if (bPrint) printf("\n\nokay, let's try an update ....\n");
+
+ ONodeUpdater aUpdateWriter(sal_False, false);
+ aWaitForSomething.reset();
+ aSession.updateNode(sOpenedNode, UNI_STRING(pLayoutNode), &aUpdateWriter, new OOpenNodeCallback(aWaitForSomething));
+
+ switch (aWaitForSomething.wait(&aTimeout))
+ {
+ case ICondition::result_error:
+ printf("error while waiting for the callback ... exiting\n\n");
+ return;
+ case ICondition::result_timeout:
+ if (bPrint) printf("timed out ... exiting\n\n");
+ return;
+ }
+
+ // --------- deleteNode ----------
+ char* pLayoutNode2 = "com.sun.star.Setup/Modules/StandFonts";
+
+ if (bPrint) printf("\n\ndeleteNode ....");
+ aWaitForSomething.reset();
+ aSession.deleteNode(sOpenedNode, UNI_STRING(pLayoutNode2), new OOpenNodeCallback(aWaitForSomething));
+ switch (aWaitForSomething.wait(&aTimeout))
+ {
+ case ICondition::result_error:
+ printf("error while waiting for the callback ... exiting\n\n");
+ return;
+ case ICondition::result_timeout:
+ if (bPrint) printf("timed out ... exiting\n\n");
+ return;
+ }
+
+/*
+ // --------- startListening ----------
+ printf("\n\nadding a listener for the Layout node\n");
+ Sequence< ::rtl::OUString > aNodesToListen(1);
+ aNodesToListen[0] = UNI_STRING(pLayoutNode);
+ aSession.startListening(aNodesToListen, NULL);
+
+ printf("waiting 10 seconds ....\n\n");
+ aWaitForSomething.reset();
+ aTimeout.Seconds = 10;
+ aWaitForSomething.wait(&aTimeout);
+*/
+ // --------- getNode (2) ----------
+// printf("\ndoing a new getNode for the Layout node ...\n");
+// aWaitForSomething.reset();
+// aSession.getNode(UNI_STRING(pLayoutNode), new OOpenNodeCallback(aWaitForSomething));
+// switch (aWaitForSomething.wait(&aTimeout))
+// {
+// case ICondition::result_error:
+// printf("error while waiting for the callback ... exiting\n\n");
+// return;
+// case ICondition::result_timeout:
+// printf("timed out ... exiting\n\n");
+// return;
+// }
+
+ aSession.closeNode(sOpenedNode, NULL);
+ aSession.close(NULL);
+
+}
+
diff --git a/configmgr/workben/local_io/com.sun.star.office.Setup.xml b/configmgr/workben/local_io/com.sun.star.office.Setup.xml
new file mode 100644
index 000000000000..4018ab3b8d5d
--- /dev/null
+++ b/configmgr/workben/local_io/com.sun.star.office.Setup.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<com.sun.star.office.Setup>
+ <Language>
+ <Language_ID Type="string"><value>1033</value></Language_ID>
+ </Language>
+ <Modules>
+ <SCalc Type="boolean">
+ <value>true</value>
+ </SCalc>
+ <SChart Type="boolean">
+ <value>true</value>
+ </SChart>
+ <SDraw Type="boolean">
+ <value>true</value>
+ </SDraw>
+ <SImage Type="boolean">
+ <value>true</value>
+ </SImage>
+ <SImpress Type="boolean">
+ <value>true</value>
+ </SImpress>
+ <SMath Type="boolean">
+ <value>true</value>
+ </SMath>
+ <SWriter Type="boolean">
+ <value>true</value>
+ </SWriter>
+ </Modules>
+</com.sun.star.office.Setup> \ No newline at end of file
diff --git a/configmgr/workben/local_io/filetest.cxx b/configmgr/workben/local_io/filetest.cxx
new file mode 100644
index 000000000000..aa7f1a6ad1b7
--- /dev/null
+++ b/configmgr/workben/local_io/filetest.cxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: filetest.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <iostream>
+#include<osl/file.hxx>
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+// -----------------------------------------------------------------------------
+// --------------------------------- namespaces ---------------------------------
+// -----------------------------------------------------------------------------
+using namespace com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::osl::File;
+// -----------------------------------------------------------------------------
+// ---------------------------------- defines ----------------------------------
+// -----------------------------------------------------------------------------
+#define ASCII(x) OUString::createFromAscii(x)
+
+
+// -----------------------------------------------------------------------------
+// ------------------------------------ main ------------------------------------
+// -----------------------------------------------------------------------------
+
+/*
+OUString operator+(const OUString &a, const OUString &b)
+{
+ OUString c = a;
+ c += b;
+ return c;
+}
+*/
+
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+int _cdecl main( int argc, char * argv[] )
+#endif
+{
+ OUString aPath = ASCII("f:/local/SRC598/configmgr/workben/local_io");
+ OUString aFilename = ASCII("com.sun.star.office.Setup");
+ OUString aExtension = ASCII("xml");
+
+ OUString aFullname = aPath + ASCII("/") + aFilename + ASCII(".") + aExtension;
+
+ // Filename convertieren
+ OUString aURL;
+ File aConvert(ASCII(""));
+ aConvert.normalizePath(aFullname, aURL);
+
+ // File oeffnen
+ File aFile(aURL);
+ aFile.open(osl_File_OpenFlag_Read);
+
+ sal_uInt64 nBytesRead;
+ Sequence< sal_Int8 > aBufferSeq(2000);
+ sal_Int8 *pBuff = aBufferSeq.getArray();
+ aFile.read(pBuff, 2000, nBytesRead);
+
+ aFile.close();
+ return 0;
+}
diff --git a/configmgr/workben/local_io/makefile.mk b/configmgr/workben/local_io/makefile.mk
new file mode 100644
index 000000000000..9b839d0fd795
--- /dev/null
+++ b/configmgr/workben/local_io/makefile.mk
@@ -0,0 +1,114 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.12 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source
+
+PRJNAME=configmgr
+
+TARGET=cfgfile
+TARGETTYPE=CUI
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+# ... common for all test executables ..............................
+APPSTDLIBS=\
+ $(SALLIB) \
+ $(VOSLIB) \
+ $(CPPULIB) \
+ $(UNOTOOLSLIB) \
+ $(CPPUHELPERLIB) \
+
+
+# ... FileTests .....................................................
+APP1STDLIBS = $(APPSTDLIBS) \
+ $(STDLIBCPP) \
+
+APP1STDLIBS+=$(STDLIBCPP)
+
+APP1TARGET= $(TARGET)
+
+APP1OBJS= \
+ $(SLO)$/cfgfile.obj \
+ $(SLO)$/oslstream.obj \
+ $(SLO)$/filehelper.obj \
+ $(SLO)$/simpletest.obj \
+ $(SLO)$/strimpl.obj \
+ $(SLO)$/confname.obj \
+
+# $(SLO)$/xmlexport.obj \
+# $(SLO)$/xmlimport.obj \
+
+# $(SLO)$/xmltreebuilder.obj \
+# $(SLO)$/cmtree.obj \
+# $(SLO)$/cmtreemodel.obj \
+# $(SLO)$/typeconverter.obj \
+# $(SLO)$/changes.obj \
+# $(SLO)$/xmlformater.obj \
+# $(SLO)$/attributes.obj \
+# $(SLO)$/tracer.obj \
+
+
+# ... common for all test executables ..............................
+# APP2STDLIBS = $(APPSTDLIBS)
+#
+# APP2STDLIBS+=$(STDLIBCPP)
+#
+# APP2TARGET= cfglocal
+# APP2OBJS= \
+# $(SLO)$/cfglocal.obj \
+# $(SLO)$/receivethread.obj \
+# $(SLO)$/redirector.obj \
+# $(SLO)$/socketstream.obj \
+# $(SLO)$/attributes.obj \
+# $(SLO)$/localsession.obj \
+# $(SLO)$/saxtools.obj \
+# $(SLO)$/mergeupdates.obj \
+# $(SLO)$/oslstream.obj \
+# $(SLO)$/configsession.obj \
+# $(SLO)$/confname.obj \
+# $(SLO)$/sessionstream.obj \
+# $(SLO)$/filehelper.obj \
+# $(SLO)$/tracer.obj \
+# $(SLO)$/updatedom.obj \
+# $(SLO)$/strconverter.obj \
+# $(SLO)$/strimpl.obj \
+#
+
+.INCLUDE : target.mk
+
+
diff --git a/configmgr/workben/local_io/org.openoffice.test.xml b/configmgr/workben/local_io/org.openoffice.test.xml
new file mode 100644
index 000000000000..ff8e37be411c
--- /dev/null
+++ b/configmgr/workben/local_io/org.openoffice.test.xml
@@ -0,0 +1,70 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<org.openoffice.test
+xmlns="http://openoffice.org/2000/registry/components/org.openoffice.Inet"
+xmlns:cfg="http://openoffice.org/2000/registry/instance"
+xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xml:lang="en-US">
+
+<!-- long -->
+ <Long cfg:type="long">100000000000000</Long>
+ <LongList cfg:type="long" cfg:derivedBy="list">1 2 3
+
+ 4 5
+
+
+
+
+ 6 7 8 9</LongList>
+ <LongList2 cfg:type="long" cfg:derivedBy="list" cfg:separator=".">1.2.3.4.5.6.7.8.9</LongList2>
+
+<!-- double -->
+ <DoubleWithDot cfg:type="double">.787564</DoubleWithDot>
+ <EuroDM cfg:type="double">1.95583</EuroDM>
+ <ZeroDotZeroZeroOne cfg:type="double">0.001</ZeroDotZeroZeroOne>
+ <ZeroDotOne cfg:type="double">0.1</ZeroDotOne>
+ <NZeroDotOne cfg:type="double">-0.1</NZeroDotOne>
+
+<!-- binary -->
+ <Binary cfg:type="binary" cfg:nullable="true" xsi:null="true"/>
+ <Binary2 cfg:type="binary" xsi:null="true"/>
+ <Binary3 cfg:type="binary" >010203040506070809</Binary3>
+ <Binary4 cfg:type="binary" cfg:nullable="true">000102030405060708090a</Binary4>
+
+<!-- Strings -->
+ <NullString cfg:type="string" xsi:null="true"/>
+ <String cfg:type="string">Identifier</String>
+ <StringList cfg:type="string" cfg:derivedBy="list">file:/ private:explorer private:help private:newmenu private:schedule private:searchfolder private:user</StringList>
+ <List cfg:type="string" cfg:derivedBy="list">NULL</List>
+ <PathAutoCorrect cfg:type="string" cfg:separator=":" cfg:derivedBy="list">$(inst)/share/autocorr:$(user)/autocorr</PathAutoCorrect>
+ <List2 cfg:type="string" cfg:derivedBy="list" cfg:separator="stupid" >NULLstupidFIRSTstupidSECONDstupid</List2>
+ <SeparatorKiller cfg:type="string" cfg:derivedBy="list" cfg:separator="." > .,.;.:.#.|.a._.!.$.%./.(.)=.?.+.*.#.~.'.\.{.}._</SeparatorKiller>
+
+<!-- localized -->
+ <LocaleString cfg:type="string" cfg:localized="true">
+ <cfg:value xml:lang="en-US">This is a string</cfg:value>
+ <cfg:value xml:lang="de-DE">Dies ist ein String</cfg:value>
+ </LocaleString>
+
+<!-- boolean -->
+ <BoolFalse cfg:type="boolean">false</BoolFalse>
+ <BoolTrue cfg:type="boolean">true</BoolTrue>
+ <BoolList cfg:type="boolean" cfg:derivedBy="list">true true false</BoolList>
+ <BoolNULL cfg:type="boolean" xsi:null="true"/>
+
+<!-- int -->
+ <Integer cfg:type="int">3</Integer>
+ <IntegerNullWithXsi cfg:type="int" xsi:null="true">10</IntegerNullWithXsi>
+ <IntegerNull cfg:type="int"/>
+
+ <IntList cfg:type="int" cfg:derivedBy="list">1 2 3 4 5 6 7 8 224 226 222 223 5</IntList>
+
+<!-- short -->
+ <Short cfg:type="short">100</Short>
+
+ <Inner>
+ <Inner2>
+ <IntList cfg:type="int" cfg:derivedBy="list">224 226 222 223 5</IntList>
+ </Inner2>
+ </Inner>
+
+</org.openoffice.test>
diff --git a/configmgr/workben/local_io/simpletest.cxx b/configmgr/workben/local_io/simpletest.cxx
new file mode 100644
index 000000000000..8a26cbe21112
--- /dev/null
+++ b/configmgr/workben/local_io/simpletest.cxx
@@ -0,0 +1,761 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: simpletest.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <memory>
+#include <vector>
+#include <stack>
+#include<osl/file.hxx>
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/servicefactory.hxx>
+
+#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HDL_
+#include <com/sun/star/lang/XComponent.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HDL_
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HDL_
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATACONTROL_HDL_
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XDATATRANSFEREVENTLISTENER_HDL_
+#include <com/sun/star/io/XDataTransferEventListener.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XDATAIMPORTER_HDL_
+#include <com/sun/star/io/XDataImporter.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HDL_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <vos/thread.hxx>
+
+#include <vos/pipe.hxx>
+#include <osl/diagnose.h>
+#include "oslstream.hxx"
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <osl/conditn.hxx>
+
+#include "xmltreebuilder.hxx"
+
+#include "dataimport.hxx"
+
+#include "createpropertyvalue.hxx"
+#include "strdecl.hxx"
+
+#include "confname.hxx"
+
+#include "FileHelper.hxx"
+
+// -----------------------------------------------------------------------------
+// --------------------------------- namespaces ---------------------------------
+// -----------------------------------------------------------------------------
+namespace uno = com::sun::star::uno;
+namespace lang = com::sun::star::lang;
+namespace io = com::sun::star::io;
+namespace sax = com::sun::star::xml::sax;
+namespace script = com::sun::star::script;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::io;
+using namespace rtl;
+using namespace osl;
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- defines ----------------------------------
+// -----------------------------------------------------------------------------
+#ifndef ASCII
+#define ASCII(x) OUString::createFromAscii(x)
+#endif
+
+ostream& operator << (ostream& out, rtl::OUString const& aStr)
+{
+ sal_Unicode const* const pStr = aStr.getStr();
+ sal_Unicode const* const pEnd = pStr + aStr.getLength();
+ for (sal_Unicode const* p = pStr; p < pEnd; ++p)
+ if (0 < *p && *p < 127) // ASCII
+ out << char(*p);
+ else
+ out << "[\\u" << hex << *p << "]";
+ return out;
+}
+
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- a Class ----------------------------------
+// -----------------------------------------------------------------------------
+// <Name a="xyz" b="bar">
+
+//==========================================================================
+//= Visitors
+//==========================================================================
+
+
+namespace configmgr
+{
+
+ class XMLSimpleDocHandler : public ::cppu::WeakImplHelper1<sax::XDocumentHandler>
+ {
+ // uno::Reference< sax::XDocumentHandler > m_xWriter; // the service object for writing XML code
+
+ sal_Int32 m_nElementDepth;
+ sal_Int32 m_nIgnoreLevel;
+ public:
+ XMLSimpleDocHandler::XMLSimpleDocHandler()
+ {}
+
+
+ // DECLARE_UNO3_DEFAULTS(XMLReadFilter, CmDocumentHandler_BASE);
+
+ // XDocumentHandler
+ virtual void SAL_CALL startDocument(void)
+ throw (sax::SAXException, uno::RuntimeException)
+ {
+ }
+
+ virtual void SAL_CALL endDocument(void)
+ throw(sax::SAXException, uno::RuntimeException)
+ {
+ }
+
+ virtual void SAL_CALL startElement(const rtl::OUString& aName,
+ const uno::Reference< sax::XAttributeList > &_xAttrList)
+ throw(sax::SAXException, uno::RuntimeException)
+ {
+ sal_Int16 nAttrCount = _xAttrList.is() ? _xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; i++ )
+ {
+ OUString aParamName( _xAttrList->getNameByIndex( i ) );
+ OUString aParamValue( _xAttrList->getValueByIndex( i ) );
+ volatile int dummy = 0;
+ }
+ }
+
+ virtual void SAL_CALL endElement(const rtl::OUString& aName)
+ throw(sax::SAXException, uno::RuntimeException)
+ {
+ }
+
+ virtual void SAL_CALL characters(const rtl::OUString& aChars)
+ throw(sax::SAXException, uno::RuntimeException)
+ {}
+
+
+ virtual void SAL_CALL ignorableWhitespace(const rtl::OUString& aWhitespaces)
+ throw(sax::SAXException, uno::RuntimeException)
+ {}
+
+
+ virtual void SAL_CALL processingInstruction(const rtl::OUString& aTarget,
+ const rtl::OUString& aData)
+ throw(sax::SAXException, uno::RuntimeException)
+ {}
+
+ virtual void SAL_CALL setDocumentLocator(const uno::Reference< sax::XLocator > &xLocator)
+ throw(sax::SAXException, uno::RuntimeException)
+ {}
+ };
+
+// -----------------------------------------------------------------------------
+// ------------------------------------ Test ------------------------------------
+// -----------------------------------------------------------------------------
+#define ASCII_STRING(rtlOUString) rtl::OUStringToOString(rtlOUString, RTL_TEXTENCODING_ASCII_US).getStr()
+ static ::rtl::OUString sRegistry = ::rtl::OUString::createFromAscii("applicat.rdb");
+
+ void simpleTest()
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMSF;
+ try
+ {
+ xMSF = cppu::createRegistryServiceFactory(sRegistry, ::rtl::OUString());
+ }
+ catch (uno::Exception& e)
+ {
+ cout << "could not bootstrap the services from " << ASCII_STRING(sRegistry) << endl ;
+ cout << " (error message : " << ASCII_STRING(e.Message) << ")" << endl;
+ }
+
+ if (!xMSF.is())
+ {
+ cerr << "could not create the service factory !" << endl;
+ return;
+ }
+
+ OUString aPath = ASCII("e:/temp/Test");
+ OUString aFilename = ASCII("calc");
+ OUString aExtension = ASCII("xml");
+
+ OUString aFullname = aPath + ASCII("/") + aFilename + ASCII(".") + aExtension;
+
+ // Filename convertieren
+ OUString aURL;
+ File aConvert(ASCII(""));
+ aConvert.normalizePath(aFullname, aURL);
+
+ // File oeffnen
+ File aFile(aURL);
+ aFile.open(osl_File_OpenFlag_Read);
+
+ uno::Reference<io::XInputStream> xInputStream =
+ new configmgr::OSLInputStreamWrapper(aFile);
+
+ // connect stream to input stream to the parser
+ InputSource aInputSource;
+ Reference<XInputStream> xPipeInput( xInputStream, UNO_QUERY );
+ aInputSource.aInputStream = xPipeInput;
+
+ Reference< sax::XParser > xParser;
+ xParser = Reference< sax::XParser > (
+ xMSF->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser")), UNO_QUERY);
+
+ XMLSimpleDocHandler *pTest = new XMLSimpleDocHandler();
+
+ // get filter
+ Reference<XDocumentHandler> xFilter = pTest;
+
+ // connect parser and filter
+ xParser->setDocumentHandler( xFilter );
+
+ // parse
+ sal_Int16 nRet = 0;
+ OUString sError;
+ try
+ {
+ xParser->parseStream( aInputSource );
+ }
+ catch( SAXParseException &e )
+ {
+ OUString sLine = OUString::valueOf(e.LineNumber);
+ OUString aStr = ASCII("SAXParseException occured in ");
+ sError = aStr + ASCII(" Line: (") + sLine + ASCII(")");
+
+ OSL_ENSURE(0, rtl::OUStringToOString(sError,RTL_TEXTENCODING_ASCII_US).getStr());
+ nRet = 3;
+ }
+ catch( SAXException &e )
+ {
+ sError = e.Message;
+ OSL_ENSURE(0, rtl::OUStringToOString(sError,RTL_TEXTENCODING_ASCII_US).getStr());
+ nRet = 4;
+ }
+ catch( IOException &e )
+ {
+ sError = e.Message;
+ OSL_ENSURE(0, rtl::OUStringToOString(sError,RTL_TEXTENCODING_ASCII_US).getStr());
+ nRet = 5;
+ }
+ }
+
+
+#include <osl/time.h>
+#include <rtl/string.hxx>
+
+class TimeTest
+{
+ TimeValue m_aStartTime, m_aEndTime;
+ bool m_bStarted;
+public:
+ TimeTest()
+ :m_bStarted(false)
+ {
+ }
+
+ void start()
+ {
+ m_bStarted = true;
+ osl_getSystemTime(&m_aStartTime);
+ }
+ void stop()
+ {
+ osl_getSystemTime(&m_aEndTime);
+ OSL_ENSURE(m_bStarted, "Not Started.");
+ m_bStarted = false;
+ }
+ void showTime(const rtl::OString & aWhatStr)
+ {
+ OSL_ENSURE(!m_bStarted, "Not Stopped.");
+
+ sal_Int32 nSeconds = m_aEndTime.Seconds - m_aStartTime.Seconds;
+ sal_Int32 nNanoSec = m_aEndTime.Nanosec - m_aStartTime.Nanosec;
+ if (nNanoSec < 0)
+ {
+ nNanoSec = 1000000000 - nNanoSec;
+ nSeconds++;
+ }
+ rtl::OString aStr = "Time for ";
+ aStr += aWhatStr;
+ aStr += " : ";
+ aStr += rtl::OString::valueOf(nSeconds);
+ aStr += ".";
+ aStr += rtl::OString::valueOf(nNanoSec);
+
+ cout << aStr.getStr() << endl;
+ }
+
+};
+
+// -----------------------------------------------------------------------------
+// -------------------------------- Mapping Test --------------------------------
+// -----------------------------------------------------------------------------
+// Simple Map created with a stl::vector
+
+typedef ::std::pair< rtl::OUString, rtl::OUString > Assoc;
+// typedef ::std::set<Assoc, ltNode> MappingTable;
+typedef std::vector<Assoc> MappingTable;
+
+rtl::OUString mapTo(const rtl::OUString& aFrom, bool bToNew)
+{
+ static MappingTable aMap;
+ if (aMap.empty())
+ {
+ // Fill Map old, new
+
+ aMap.push_back(Assoc(ASCII("value"), TAG_VALUE));
+ aMap.push_back(Assoc(ASCII("type"), ATTR_TYPE));
+ aMap.push_back(Assoc(ASCII("instance"), ATTR_INSTANCE));
+ }
+ if (bToNew)
+ {
+ // check, if we should convert first to second
+ for (std::vector<Assoc>::const_iterator it = aMap.begin();it != aMap.end();++it)
+ {
+ if ((*it).first.equals(aFrom))
+ return (*it).second;
+ }
+ }
+ else
+ {
+ // check if we should convert second to first
+ for (std::vector<Assoc>::const_iterator it = aMap.begin();it != aMap.end();++it)
+ {
+ if ((*it).second.equals(aFrom))
+ return (*it).first;
+ }
+ }
+
+ // do nothing!
+ return aFrom;
+}
+// -----------------------------------------------------------------------------
+void simpleMappingTest()
+{
+ OUString aValue = ASCII("value");
+ OUString aNew;
+
+ aNew = mapTo(aValue, true); // true for ToNew
+ aNew = mapTo(aNew, false);
+ aNew = mapTo(aNew, false);
+
+ volatile int dummy = 0;
+}
+
+// -----------------------------------------------------------------------------
+ void speedTest()
+ {
+ // check speed of:
+ // ASCII("value")
+ // TAG_VALUE
+ // ...
+
+ sal_Int32 nCount = 1000 * 1000 * 100;
+ sal_Int32 n;
+
+ cout << "Starting Timetest" << endl;
+ TimeTest tt;
+ tt.start();
+ for(n=0;n<nCount;n++)
+ {
+ }
+ tt.stop();
+ tt.showTime("Leere Schleife: ");
+
+
+ nCount = 1000 * 1000 * 5;
+ rtl::OUString aStr;
+
+ tt.start();
+ for(n=0;n<nCount;n++)
+ {
+ aStr = ASCII("value");
+ }
+ tt.stop();
+ tt.showTime("ASCII() ");
+
+
+ OUString aValue = ASCII("value");
+ tt.start();
+ for(n=0;n<nCount;n++)
+ {
+ aStr = TAG_VALUE;
+ }
+ tt.stop();
+ tt.showTime("TAG_VALUE: ");
+
+ }
+
+OUString changeToComSunStarPath(const OUString &aPath)
+{
+ static OUString aOO = ASCII("org.OpenOffice");
+ static OUString aCSS = ASCII("com.sun.star");
+ OUString aNewPath;
+
+ // compare
+ if (aPath.compareTo( aOO, aOO.getLength() ) == 0)
+ {
+ aNewPath = aCSS;
+ aNewPath += aPath.copy(aOO.getLength());
+ return aNewPath;
+ }
+ return aPath;
+}
+
+void stringTest2()
+{
+ OUString aPath = ASCII("org.OpenOffice.Setup/blah/blub");
+
+ OUString aNewPath = changeToComSunStarPath(aPath);
+ volatile int dummy = 0;
+}
+
+/*
+
+class A
+{
+public:
+ static void run() {
+ cout << "This is A::run();" << endl;
+ }
+
+};
+
+class B : public A
+{
+public:
+
+ static void run() {
+ cout << "This is B::run();" << endl;
+ }
+};
+
+void classTest()
+{
+ A a;
+ B b;
+ B::run();
+}
+*/
+
+// -----------------------------------------------------------------------------
+// ------------------------------------ Map ------------------------------------
+// -----------------------------------------------------------------------------
+struct ltstr
+{
+ bool operator()(const rtl::OUString &s1, const rtl::OUString &s2) const
+ {
+ return s1.compareTo(s2) < 0 ? true : false;
+ }
+};
+
+void stringTest()
+{
+ map<const OUString, int, ltstr> months;
+
+ months[ASCII("january")] = 31;
+ months[ASCII("february")] = 28;
+ months[ASCII("march")] = 31;
+ months[ASCII("april")] = 30;
+ months[ASCII("may")] = 31;
+ months[ASCII("june")] = 30;
+ months[ASCII("july")] = 31;
+ months[ASCII("august")] = 31;
+ months[ASCII("september")] = 30;
+ months[ASCII("october")] = 31;
+ months[ASCII("november")] = 30;
+ months[ASCII("december")] = 31;
+
+ cout << "june -> " << months[ASCII("june")] << endl;
+ map<const OUString, int, ltstr>::iterator cur = months.find(ASCII("april"));
+ // map<const OUString, int, ltstr>::iterator prev = cur;
+ map<const OUString, int, ltstr>::iterator next = cur;
+ // ++next;
+ // --prev;
+ // cout << "Previous (in alphabetical order) is " << (*prev).first << endl;
+ for(int i=0;i<12;i++)
+ {
+ cout << "Next (in alphabetical order) is " << (*next).first << " days " << (*next).second << endl;
+ ++next;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- HashMap ----------------------------------
+// -----------------------------------------------------------------------------
+#include <hash_map>
+
+
+namespace test {
+
+struct eqstr
+{
+ bool operator()(const rtl::OUString &s1, const rtl::OUString &s2) const
+ {
+ return s1.equals(s2) == sal_True ? true : false;
+ }
+};
+
+struct hash_oustring
+{
+ // This hash funktion is a copy of hash<char*> from SGI-STL
+ size_t operator()(const rtl::OUString &_s) const
+ {
+ sal_Int64 nStrLen = _s.getLength();
+ const sal_Unicode *pStr = _s.getStr();
+ unsigned long h = 0;
+ for (sal_Int64 i=0;i<nStrLen; ++i)
+ h = 5*h + *pStr++;
+
+ return size_t(h);
+ }
+};
+
+void hash_test()
+{
+ hash_map<const rtl::OUString, rtl::OUString, hash_oustring, eqstr> months;
+
+ rtl::OUString sJanuary = ASCII("january");
+ months[sJanuary] = ASCII("31");
+ months[ASCII("february")] = ASCII("28");
+ months[ASCII("march")] = ASCII("31");
+ months[ASCII("april")] = ASCII("30");
+ months[ASCII("may")] = ASCII("31");
+ months[ASCII("june")] = ASCII("30");
+ months[ASCII("july")] = ASCII("31");
+ months[ASCII("august")] = ASCII("31");
+ months[ASCII("september")] = ASCII("30");
+ months[ASCII("october")] = ASCII("31");
+ months[ASCII("november")] = ASCII("30");
+ months[ASCII("december")] = ASCII("31");
+
+ cout << "september -> " << months[ASCII("september")] << endl;
+ cout << "april -> " << months[ASCII("april")] << endl;
+ cout << "june -> " << months[ASCII("june")] << endl;
+ cout << "november -> " << months[ASCII("november")] << endl;
+}
+}
+
+
+// -----------------------------------------------------------------------------
+// Fri Nov 10 15:10:45 2000
+// -----------------------------------------------------------------------------
+
+#include <vos/ref.hxx>
+
+class Options : public vos::OReference
+{
+ int m_aValue;
+public:
+ int getValue() {return m_aValue;}
+ void setValue(int _aValue) {m_aValue = _aValue;}
+
+
+};
+
+class A
+{
+ vos::ORef<Options> m_aOptions;
+public:
+
+ vos::ORef<Options> getOptions() {return m_aOptions;}
+ void setOptions(vos::ORef<Options>& _aOptions) {
+ m_aOptions = _aOptions;
+ }
+};
+
+void testRefs()
+{
+ vos::ORef<Options> aO = new Options;
+ aO->setValue(10);
+
+ A a,b;
+ a.setOptions(aO);
+ b.setOptions(aO);
+ cout << "Options from a : " << a.getOptions()->getValue() << endl;
+ cout << "Options from b : " << b.getOptions()->getValue() << endl;
+
+ aO->setValue(20);
+ cout << "Options from a : " << a.getOptions()->getValue() << endl;
+ cout << "Options from b : " << b.getOptions()->getValue() << endl;
+}
+
+
+
+void ConfigName()
+{
+ // OUString aSubtreePath = ASCII("/org.openoffice.office.common/path/blah/blub");
+ OUString aSubtreePath = ASCII("/org.openoffice.office.common");
+ ConfigurationName aName(aSubtreePath);
+ OUString a = aName.localName();
+ OUString b = aName.fullName();
+ OUString c = aName.moduleName();
+ ConfigurationName aParentName(aName.getParentName());
+ OUString d = aParentName.fullName();
+
+
+ {
+ ConfigurationName aName( ASCII("/" ));
+
+ std::stack< rtl::OUString, std::vector<rtl::OUString> > m_aStringStack;
+
+ if (aName.localName().getLength() != 0)
+ {
+ for (ConfigurationName::Iterator it = aName.begin();
+ it != aName.end();
+ ++it)
+ {
+ rtl::OUString aName = *it;
+ m_aStringStack.push(aName);
+ // m_xHandler->startElement(*it, rList);
+ volatile int dummy = 0;
+ }
+ }
+
+ // bBack = writeChanges();
+
+ while(!m_aStringStack.empty())
+ {
+ OUString aName = m_aStringStack.top();
+ m_aStringStack.pop();
+ }
+ }
+}
+
+void ConfigName2()
+{
+ OUString aSubtreePath = ASCII("/org.openoffice.office.common/path/blah/blub");
+ ConfigurationName aName(aSubtreePath);
+ ConfigurationName aParent = aName.getParentName();
+
+ for (ConfigurationName::Iterator it = aName.begin();
+ it != aName.end();
+ ++it)
+ {
+ rtl::OUString aName = *it;
+ volatile int dummy = 0;
+ }
+}
+
+// -----------------------------------------------------------------------------
+inline void operator <<= (rtl::OUString& _rUnicodeString, const sal_Char* _pAsciiString)
+{
+ _rUnicodeString = ::rtl::OUString::createFromAscii(_pAsciiString);
+}
+
+inline void operator <<= (rtl::OUString& _rUnicodeString, const rtl::OString& _rAsciiString)
+{
+ _rUnicodeString <<= _rAsciiString.getStr();
+}
+
+inline void operator <<= (rtl::OString& _rAsciiString, const rtl::OUString& _rUnicodeString)
+{
+ _rAsciiString = rtl::OUStringToOString(_rUnicodeString,RTL_TEXTENCODING_ASCII_US);
+}
+
+// -----------------------------------------------------------------------------
+bool isBTimeGreaterATime(TimeValue const& A, TimeValue const& B)
+{
+ if (B.Seconds > A.Seconds) return true;
+ if (B.Nanosec > A.Nanosec) return true;
+
+ // lower or equal
+ return false;
+}
+
+// -----------------------------------------------------------------------------
+
+void oslTest()
+{
+
+ OUString aDirectory(FileHelper::convertFilenameToFileURL(ASCII("c:/temp/file.out.1")));
+ TimeValue a = FileHelper::getFileModificationStamp(aDirectory);
+
+ OUString aDirectory2(FileHelper::convertFilenameToFileURL(ASCII("c:/temp/file.out.2")));
+ TimeValue b = FileHelper::getFileModificationStamp(aDirectory2);
+
+ if (isBTimeGreaterATime(a,b))
+ {
+ OSL_ENSURE(false, "FileB ist neuer als FileA");
+ }
+
+
+/*
+ OUString aDirectory(FileHelper::convertFilenameToFileURL(ASCII("c:/temp/dies")));
+ osl::FileBase::RC eError = osl::Directory::create(aDirectory);
+ if (eError != osl::FileBase::E_None)
+ {
+ OUString aUStr = FileHelper::createOSLErrorString(eError);
+ OString aStr;
+ aStr <<= aUStr;
+ OSL_ENSURE(false, aStr.getStr());
+ }
+*/
+}
+
+} // namespace configmgr
diff --git a/configmgr/workben/local_io/xmlexport.cxx b/configmgr/workben/local_io/xmlexport.cxx
new file mode 100644
index 000000000000..6302ccb8b947
--- /dev/null
+++ b/configmgr/workben/local_io/xmlexport.cxx
@@ -0,0 +1,239 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmlexport.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include<iostream>
+#include<osl/file.hxx>
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/servicefactory.hxx>
+/*
+#include <cppuhelper/implbase1.hxx>
+*/
+#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HDL_
+#include <com/sun/star/lang/XComponent.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XDATATRANSFEREVENTLISTENER_HDL_
+#include <com/sun/star/io/XDataTransferEventListener.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XDATAIMPORTER_HDL_
+#include <com/sun/star/io/XDataExporter.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HDL_
+#include <com/sun/star/io/XOutputStream.hpp>
+#endif
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <osl/diagnose.h>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+
+#include "oslstream.hxx"
+#include "attributes.hxx"
+#include "typeconverter.hxx"
+#include "xmlformater.hxx"
+#include "filehelper.hxx"
+
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include "createpropertyvalue.hxx"
+// -----------------------------------------------------------------------------
+// --------------------------------- namespaces ---------------------------------
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+
+ namespace uno = com::sun::star::uno;
+ namespace lang = com::sun::star::lang;
+ namespace io = com::sun::star::io;
+ namespace sax = com::sun::star::xml::sax;
+ namespace beans = com::sun::star::beans;
+
+ using ::rtl::OUString;
+ using ::osl::File;
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::container;
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- defines ----------------------------------
+// -----------------------------------------------------------------------------
+#define ASCII(x) OUString::createFromAscii(x)
+
+// -----------------------------------------------------------------------------
+ class Listener : public ::cppu::WeakImplHelper1<io::XDataTransferEventListener>
+ {
+ virtual void SAL_CALL disposing( const lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "disposing");
+ }
+
+
+ virtual void SAL_CALL finished( const io::DataTransferEvent& aEvent )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "finished");
+ }
+
+ virtual void SAL_CALL cancelled( const io::DataTransferEvent& aEvent )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "cancelled");
+ }
+ };
+
+ class Component: public ::cppu::WeakImplHelper1<lang::XComponent>
+ {
+ virtual void SAL_CALL dispose( )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "dispose");
+
+ }
+ virtual void SAL_CALL addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "addEventListener");
+ }
+ virtual void SAL_CALL removeEventListener( const uno::Reference< lang::XEventListener >& aListener )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "removeEventListener");
+ }
+ };
+
+
+
+
+
+#define ASCII_STRING(rtlOUString) rtl::OUStringToOString(rtlOUString, RTL_TEXTENCODING_ASCII_US).getStr()
+ static ::rtl::OUString sRegistry = ::rtl::OUString::createFromAscii("applicat.rdb");
+
+
+
+
+
+
+
+
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+ void exportTest()
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMSF;
+ try
+ {
+ xMSF = cppu::createRegistryServiceFactory(sRegistry, ::rtl::OUString());
+ }
+ catch (uno::Exception& e)
+ {
+ cout << "could not bootstrap the services from " << ASCII_STRING(sRegistry) << endl ;
+ cout << " (error message : " << ASCII_STRING(e.Message) << ")" << endl;
+ }
+
+ if (!xMSF.is())
+ {
+ cerr << "could not create the service factory !" << endl;
+ return;
+ }
+
+ OUString aPath = ASCII("l:/SRC601/configmgr/workben/local_io");
+ OUString sFilename = ASCII("exported_config");
+ OUString aExtension = ASCII("xml");
+
+ OUString aFullname = aPath + ASCII("/") + sFilename + ASCII(".") + aExtension;
+
+ // Filename convertieren
+ OUString aURL;
+ File aConvert(ASCII(""));
+ aConvert.normalizePath(aFullname, aURL);
+
+ FileHelper::tryToRemoveFile(aURL);
+
+ rtl::OUString sError;
+
+ // File oeffnen
+ File aFile(aURL);
+ osl::FileBase::RC eError = aFile.open(OpenFlag_Write | OpenFlag_Create);
+
+ if (eError != osl_File_E_None)
+ {
+ sError = ASCII("XMLExportTest:");
+ rtl::OString aStr = rtl::OUStringToOString(sError,RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(0, aStr.getStr());
+ return;
+ }
+
+ // create an outputstream
+ uno::Reference<io::XOutputStream> xOutputStream = new configmgr::OSLOutputStreamWrapper(aFile);
+
+ // Listener & Component
+ uno::Reference<io::XDataTransferEventListener> rListener = new Listener();
+ uno::Reference<lang::XComponent> rComponent = new Component();
+
+
+ OUString sPath = ASCII("com.sun.star.ucb.Hierarchy");
+
+ // Create a TypeConverter
+ uno::Reference<script::XTypeConverter> aConverter;
+ aConverter = aConverter.query(xMSF->createInstance(ASCII( "com.sun.star.script.Converter" )) );
+
+ // prepare parameters for DataExport
+ Sequence< uno::Any > aArgs(4);
+ aArgs[0] <<= createPropertyValue(ASCII("PackageName"), sFilename);
+ aArgs[1] <<= createPropertyValue(ASCII("Path"), sPath); // multiple occur possible
+ aArgs[2] <<= createPropertyValue(ASCII("TypeConverter"), aConverter); // optional
+ aArgs[3] <<= createPropertyValue(ASCII("Path"), ASCII("com.sun.star.office.Setup")); // multiple occur possible
+
+ // important: createInstanceWithArguments will throw an IllegalArgumentException() if
+ // parameters are wrong...
+ Reference< XInterface > xDataExport = xMSF->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.configuration.DataExport"),
+ aArgs);
+
+ uno::Reference<io::XDataExporter> rExporter(xDataExport, UNO_QUERY);
+
+ // Export Data
+ rExporter->exportData(xOutputStream, rComponent, rListener);
+ }
+
+} // namespace configmgr
diff --git a/configmgr/workben/local_io/xmlimport.cxx b/configmgr/workben/local_io/xmlimport.cxx
new file mode 100644
index 000000000000..d910edd22b56
--- /dev/null
+++ b/configmgr/workben/local_io/xmlimport.cxx
@@ -0,0 +1,472 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmlimport.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <memory>
+#include <vector>
+#include <stack>
+#include<osl/file.hxx>
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/servicefactory.hxx>
+
+#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HDL_
+#include <com/sun/star/lang/XComponent.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HDL_
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HDL_
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XACTIVEDATACONTROL_HDL_
+#include <com/sun/star/io/XActiveDataControl.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XDATATRANSFEREVENTLISTENER_HDL_
+#include <com/sun/star/io/XDataTransferEventListener.hpp>
+#endif
+#ifndef _COM_SUN_STAR_IO_XDATAIMPORTER_HDL_
+#include <com/sun/star/io/XDataImporter.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HDL_
+#include <com/sun/star/io/XInputStream.hpp>
+#endif
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/SAXParseException.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <vos/thread.hxx>
+
+#include <vos/pipe.hxx>
+#include <osl/diagnose.h>
+#include "oslstream.hxx"
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <osl/conditn.hxx>
+
+#include "xmltreebuilder.hxx"
+
+#include "dataimport.hxx"
+
+#include "createpropertyvalue.hxx"
+// -----------------------------------------------------------------------------
+// --------------------------------- namespaces ---------------------------------
+// -----------------------------------------------------------------------------
+namespace uno = com::sun::star::uno;
+namespace lang = com::sun::star::lang;
+namespace io = com::sun::star::io;
+namespace sax = com::sun::star::xml::sax;
+namespace script = com::sun::star::script;
+
+using ::rtl::OUString;
+using ::osl::File;
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- defines ----------------------------------
+// -----------------------------------------------------------------------------
+#ifndef ASCII
+#define ASCII(x) OUString::createFromAscii(x)
+#endif
+
+
+// -----------------------------------------------------------------------------
+// ---------------------------------- a Class ----------------------------------
+// -----------------------------------------------------------------------------
+// <Name a="xyz" b="bar">
+
+//==========================================================================
+//= Visitors
+//==========================================================================
+
+
+// -----------------------------------------------------------------------------
+class Listener : public ::cppu::WeakImplHelper1<io::XDataTransferEventListener>
+{
+ osl::Condition m_aCondition;
+public:
+ Listener()
+ {
+ m_aCondition.reset(); // will block
+ }
+
+ virtual void SAL_CALL disposing( const lang::EventObject& Source )
+ throw(::com::sun::star::uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "disposing");
+ m_aCondition.set(); // will not block
+ }
+
+ virtual void SAL_CALL finished( const io::DataTransferEvent& aEvent )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "finished");
+ m_aCondition.set(); // will not block
+ }
+
+ virtual void SAL_CALL cancelled( const io::DataTransferEvent& aEvent )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "cancelled");
+ m_aCondition.set(); // will not block
+ }
+public:
+ void wait()
+ {
+ m_aCondition.wait();
+ }
+};
+
+class Component: public ::cppu::WeakImplHelper1<lang::XComponent>
+{
+ virtual void SAL_CALL dispose( )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "dispose");
+
+ }
+ virtual void SAL_CALL addEventListener( const uno::Reference< lang::XEventListener >& xListener )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "addEventListener");
+ }
+ virtual void SAL_CALL removeEventListener( const uno::Reference< lang::XEventListener >& aListener )
+ throw(uno::RuntimeException)
+ {
+ OSL_ENSURE(0, "removeEventListener");
+ }
+};
+
+
+
+namespace configmgr
+{
+
+// -----------------------------------------------------------------------------
+// ------------------------------------ Test ------------------------------------
+// -----------------------------------------------------------------------------
+#define ASCII_STRING(rtlOUString) rtl::OUStringToOString(rtlOUString, RTL_TEXTENCODING_ASCII_US).getStr()
+ static ::rtl::OUString sRegistry = ::rtl::OUString::createFromAscii("applicat.rdb");
+
+ void importTest()
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMSF;
+ try
+ {
+ xMSF = cppu::createRegistryServiceFactory(sRegistry, ::rtl::OUString());
+ }
+ catch (uno::Exception& e)
+ {
+ cout << "could not bootstrap the services from " << ASCII_STRING(sRegistry) << endl ;
+ cout << " (error message : " << ASCII_STRING(e.Message) << ")" << endl;
+ }
+
+ if (!xMSF.is())
+ {
+ cerr << "could not create the service factory !" << endl;
+ return;
+ }
+
+ OUString aPath = ASCII("l:/SRC601/configmgr/workben/local_io");
+ OUString aFilename = ASCII("hierarchy");
+ OUString aExtension = ASCII("xml");
+
+ OUString aFullname = aPath + ASCII("/") + aFilename + ASCII(".") + aExtension;
+
+ // Filename convertieren
+ OUString aURL;
+ File aConvert(ASCII(""));
+ aConvert.normalizePath(aFullname, aURL);
+
+ // File oeffnen
+ File aFile(aURL);
+ aFile.open(osl_File_OpenFlag_Read);
+
+ // sal_uInt64 nBytesRead;
+ // uno::Sequence< sal_Int8 > aBufferSeq(2000);
+ // sal_Int8 *pBuff = aBufferSeq.getArray();
+ // aFile.read(pBuff, 2000, nBytesRead);
+ //
+ // aFile.close();
+
+ uno::Reference<io::XInputStream> xInputStream = new configmgr::OSLInputStreamWrapper(aFile);
+
+ uno::Reference <uno::XInterface> xPump = xMSF->createInstance( L"com.sun.star.io.Pump" );
+ OSL_ENSURE(xPump.is(), "there is no pump");
+
+ uno::Reference<io::XActiveDataSink> xPumpSink(xPump, uno::UNO_QUERY);
+ xPumpSink->setInputStream(xInputStream);
+
+ uno::Reference<io::XActiveDataSource> xPumpSource(xPump, uno::UNO_QUERY);
+
+ Listener *pListener = new Listener();
+ uno::Reference<io::XDataTransferEventListener> rListener = pListener;
+ uno::Reference<lang::XComponent> rComponent = new Component();
+
+ // Create a TypeConverter
+ uno::Reference<script::XTypeConverter> aConverter;
+ aConverter = aConverter.query(xMSF->createInstance(ASCII( "com.sun.star.script.Converter" )) );
+
+ Sequence< uno::Any > aArgs(1); // optional arg.
+ aArgs[0] <<= configmgr::createPropertyValue(ASCII("TypeConverter"), aConverter);
+
+ Reference< XInterface > xDataImport = xMSF->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.configuration.DataImport"),
+ aArgs);
+
+ if (xDataImport.is())
+ {
+ uno::Reference<io::XDataImporter> rImporter(xDataImport, UNO_QUERY);
+
+ // Import Data
+ rImporter->importData(xPumpSource, rComponent, rListener);
+
+ // lets pump
+ uno::Reference<io::XActiveDataControl> xControl(xPump, uno::UNO_QUERY);
+ xControl->start();
+
+ // TEST:
+ // rImporter->cancel();
+
+ // pImporter->wait();
+ // Wait until the listener send ready
+ pListener->wait();
+ }
+ return;
+ }
+
+// -----------------------------------------------------------------------------
+// -------------------------------- Import Test --------------------------------
+// -----------------------------------------------------------------------------
+
+ // ----------- TEST ReadAccess -----------
+ void showSequence(const Sequence<OUString> &aSeq);
+
+void hierarchyTest()
+{
+
+ uno::Reference< lang::XMultiServiceFactory > xMSF;
+ try
+ {
+ xMSF = cppu::createRegistryServiceFactory(sRegistry, ::rtl::OUString());
+ }
+ catch (uno::Exception& e)
+ {
+ cout << "could not bootstrap the services from " << ASCII_STRING(sRegistry) << endl ;
+ cout << " (error message : " << ASCII_STRING(e.Message) << ")" << endl;
+ }
+
+ if (!xMSF.is())
+ {
+ cerr << "could not create the service factory !" << endl;
+ return;
+ }
+
+
+ Reference< XMultiServiceFactory > xCfgProvider( xMSF->createInstance(
+ ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")),
+ UNO_QUERY);
+
+ if (!xCfgProvider.is())
+ {
+ OSL_ENSURE(0, "No Configuration Provider");
+ }
+
+ OUString sPath = ASCII("com.sun.star.ucb.Hierarchy");
+
+ Sequence< Any > aArgs(1);
+ aArgs[0] <<= sPath;
+
+ Reference< XInterface > xCfgUpdt = xCfgProvider->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"),
+ aArgs);
+
+ Reference< XNameAccess > xNameAccess(xCfgUpdt, UNO_QUERY);
+
+ // which Names are exist?
+ showSequence(xNameAccess->getElementNames());
+
+ OUString aNamePath = ASCII("Root");
+ if (xNameAccess->hasByName(aNamePath))
+ {
+ Any aAny;
+ aAny = xNameAccess->getByName(aNamePath);
+ TypeClass aTypeClass = aAny.getValueTypeClass();
+ if (aAny.getValueTypeClass() == TypeClass_INTERFACE)
+ {
+ Reference< XInterface > xInterface;
+ aAny >>= xInterface;
+ Reference< XNameAccess > xNameAccess2(xInterface, UNO_QUERY);
+ if (xNameAccess.is())
+ {
+ Sequence<OUString> aSeq = xNameAccess2->getElementNames();
+ showSequence(aSeq);
+
+ // insert a new set
+/*
+ Reference<XHierarchicalName> xHierarchical(xNameAccess, UNO_QUERY);
+ OUString aHierachicalName = xHierarchical->getHierarchicalName();
+
+ Sequence< Any > aArgs(2);
+ aArgs[0] <<= aHierachicalName;
+ sal_Int32 nLevels=1;
+ aArgs[1] <<= nLevels;
+
+ Reference< XInterface > xCfgNewUpdt = xCfgProvider->createInstanceWithArguments(
+ OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"),
+ aArgs);
+*/
+ Reference< lang::XSingleServiceFactory > xChildFactory(xNameAccess2, UNO_QUERY);
+ if (xChildFactory.is())
+ {
+ Reference< XInterface > xChild = xChildFactory->createInstance();
+ if (xChild.is())
+ {
+ Reference<XNameAccess> xObjectOnTheMedow(xChild, UNO_QUERY);
+
+
+
+
+ // which Names are exist?
+ showSequence(xObjectOnTheMedow->getElementNames());
+
+ OUString aChildren = ASCII("Children");
+ if (xObjectOnTheMedow->hasByName(aChildren))
+ {
+ Any aAny;
+ aAny = xObjectOnTheMedow->getByName(aChildren);
+ TypeClass aTypeClass = aAny.getValueTypeClass();
+ if (aAny.getValueTypeClass() == TypeClass_INTERFACE)
+ {
+ Reference< XInterface > xInterface;
+ aAny >>= xInterface;
+ Reference< XNameAccess > xChildFromOOM(xInterface, UNO_QUERY);
+
+ if (xChildFromOOM.is())
+ {
+ // insert a new Object in the new Object
+
+ Reference< lang::XSingleServiceFactory > xChildFactory(xChildFromOOM, UNO_QUERY);
+ if (xChildFactory.is())
+ {
+ Reference< XInterface > xChild = xChildFactory->createInstance();
+ if (xChild.is())
+ {
+ Reference<XNameContainer> xNameContainer(xChildFromOOM, UNO_QUERY);
+ if (xNameContainer.is())
+ {
+ xNameContainer->insertByName(ASCII("Test2"), makeAny(xChild));
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ Reference<XNameContainer> xNameContainer(xNameAccess2, UNO_QUERY);
+ if (xNameContainer.is())
+ {
+ xNameContainer->insertByName(ASCII("Test"), makeAny(xObjectOnTheMedow));
+ }
+ }
+
+ // commit changes
+ Reference< XChangesBatch > xChangesBatch(xCfgUpdt, UNO_QUERY);
+ if (xChangesBatch.is())
+ {
+ xChangesBatch->commitChanges();
+ }
+ }
+
+ Sequence<OUString> aSeq2 = xNameAccess2->getElementNames();
+ showSequence(aSeq2);
+
+/*
+ OUString *pStr = aSeq.getArray();
+ for (int i=0;i<aSeq.getLength();i++)
+ {
+ OUString aStr = pStr[i];
+ Any aAny;
+ aAny = xNameAccess->getByName(aStr);
+ TypeClass aTypeClass = aAny.getValueTypeClass();
+
+ Reference< XNameReplace > xNameReplace(xNameAccess, UNO_QUERY);
+
+ Any aNewAny;
+ sal_Bool bValue = false;
+ aNewAny <<= bValue;
+ xNameReplace->replaceByName(aStr, aNewAny);
+
+ volatile int dummy = 0;
+ }
+*/
+ }
+ }
+ volatile int dummy = 0;
+ }
+}
+
+// ------------------------------ Helperfunctions ------------------------------
+
+ void showSequence(const Sequence<OUString> &aSeq)
+ {
+ OUString aArray;
+ const OUString *pStr = aSeq.getConstArray();
+ for (int i=0;i<aSeq.getLength();i++)
+ {
+ OUString aStr = pStr[i];
+ aArray += aStr + ASCII(", ");
+ }
+ volatile int dummy = 0;
+ }
+
+} // namespace configmgr
diff --git a/configmgr/workben/logger/exports.dxp b/configmgr/workben/logger/exports.dxp
new file mode 100644
index 000000000000..9630d7e06768
--- /dev/null
+++ b/configmgr/workben/logger/exports.dxp
@@ -0,0 +1,3 @@
+component_getImplementationEnvironment
+component_writeInfo
+component_getFactory
diff --git a/configmgr/workben/logger/loggerdfn.cxx b/configmgr/workben/logger/loggerdfn.cxx
new file mode 100644
index 000000000000..8449da042c03
--- /dev/null
+++ b/configmgr/workben/logger/loggerdfn.cxx
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: loggerdfn.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "simplelogger.hxx"
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+#include <rtl/ustrbuf.hxx>
+
+namespace cssuno = com::sun::star::uno;
+using rtl::OUString;
+using rtl::OUStringBuffer;
+
+//==============================================================================
+
+static cssuno::Reference<cssuno::XInterface> SAL_CALL
+ createSimpleLogger( const cssuno::Reference<cssuno::XComponentContext>& aContext)
+{
+ return * new logger::SimpleLogger(aContext,"configuration.log") ;
+}
+//==============================================================================
+
+// adapted from the corresponding cppuhelper function
+static sal_Bool component_writeInfoHelper_withSingleton(
+ void *pServiceManager, void *pRegistryKey ,
+ const cppu::ImplementationEntry entries[],
+ char const * const singletons[])
+{
+ using namespace com::sun::star::registry;
+ using rtl::OUString;
+
+ sal_Bool bRet = sal_False;
+ try
+ {
+ if( pRegistryKey )
+ {
+ for( sal_Int32 i = 0; entries[i].create ; i ++ )
+ {
+ rtl::OUStringBuffer buf( 124 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/") );
+ buf.append( entries[i].getImplementationName() );
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM( "/UNO/SERVICES" ) );
+ cssuno::Reference< XRegistryKey > xNewKey(
+ static_cast< XRegistryKey * >( pRegistryKey )->createKey( buf.makeStringAndClear() ) );
+
+ cssuno::Sequence< OUString > const seq = entries[i].getSupportedServiceNames();
+ for ( sal_Int32 nPos = 0 ; nPos < seq.getLength(); nPos ++ )
+ xNewKey->createKey( seq[nPos] );
+
+ if (singletons[i])
+ {
+ rtl::OUStringBuffer buf( 124 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/") );
+ buf.append( entries[i].getImplementationName() );
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM( "/UNO/SINGLETONS/" ) );
+ buf.appendAscii(singletons[i]);
+ cssuno::Reference< XRegistryKey > xNewKey(
+ static_cast< XRegistryKey * >( pRegistryKey )->createKey( buf.makeStringAndClear() ) );
+
+ xNewKey->setStringValue(entries[i].getImplementationName());
+ }
+ }
+ bRet = sal_True;
+ }
+ }
+ catch ( InvalidRegistryException & )
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ catch ( cssuno::Exception & )
+ {
+ OSL_ENSURE( sal_False, "### Unexpected UNO Exception!" );
+ }
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+
+static const cppu::ImplementationEntry kImplementations_entries[] =
+{
+ {
+ createSimpleLogger,
+ logger::SimpleLogger::getImplementationName_static,
+ logger::SimpleLogger::getSupportedServiceNames_static,
+ cppu::createSingleComponentFactory,
+ NULL,
+ 0
+ },
+ { NULL }
+} ;
+static const char * const kSingleton_names[] =
+{
+ "com.sun.star.configuration.theLogger",
+ NULL
+};
+
+//------------------------------------------------------------------------------
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char **aEnvTypeName,
+ uno_Environment **aEnvironment) {
+ *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
+}
+//------------------------------------------------------------------------------
+
+extern "C" sal_Bool SAL_CALL component_writeInfo(void *aServiceManager,
+ void *aRegistryKey) {
+ return component_writeInfoHelper_withSingleton( aServiceManager,
+ aRegistryKey,
+ kImplementations_entries,
+ kSingleton_names) ;
+}
+//------------------------------------------------------------------------------
+
+extern "C" void *component_getFactory(const sal_Char *aImplementationName,
+ void *aServiceManager,
+ void *aRegistryKey) {
+ return cppu::component_getFactoryHelper(aImplementationName,
+ aServiceManager,
+ aRegistryKey,
+ kImplementations_entries) ;
+}
+//------------------------------------------------------------------------------
diff --git a/configmgr/workben/logger/makefile.mk b/configmgr/workben/logger/makefile.mk
new file mode 100644
index 000000000000..a7d37cb00274
--- /dev/null
+++ b/configmgr/workben/logger/makefile.mk
@@ -0,0 +1,73 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJINC=$(PRJ)$/source
+PRJNAME=configmgr
+TARGET=simplelogger
+ENABLE_EXCEPTIONS=TRUE
+
+# Version
+SYSMGR_MAJOR=1
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# --- Files ---
+
+
+SLOFILES=\
+ $(SLO)$/simplelogger.obj \
+ $(SLO)$/loggerdfn.obj
+
+LIB1TARGET=$(SLB)$/_$(TARGET).lib
+LIB1OBJFILES=$(SLOFILES)
+
+SHL1TARGET=$(TARGET)$(SYSMGR_MAJOR).uno
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1LIBS=$(LIB1TARGET)
+SHL1IMPLIB=i$(SHL1TARGET)
+SHL1STDLIBS= \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+DEF1NAME=$(SHL1TARGET)
+DEF1EXPORTFILE=exports.dxp
+DEF1DES=Configuration: Simple Logger
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
diff --git a/configmgr/workben/logger/simplelogger.cxx b/configmgr/workben/logger/simplelogger.cxx
new file mode 100644
index 000000000000..3ca78547f65c
--- /dev/null
+++ b/configmgr/workben/logger/simplelogger.cxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: simplelogger.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "simplelogger.hxx"
+#include <com/sun/star/util/logging/LogLevel.hpp>
+
+#include <osl/thread.h>
+#include <stdlib.h> // for getenv
+
+namespace logger
+{
+
+ namespace LogLevel = com::sun::star::util::logging::LogLevel;
+
+//==============================================================================
+static rtl::OString level2str(sal_Int32 nLevel)
+{
+ return rtl::OString::valueOf(nLevel);
+}
+
+sal_Int32 str2level(rtl::OString const & str)
+{
+ return str.toInt32();
+}
+
+//------------------------------------------------------------------------------
+SimpleLogger::SimpleLogger( const uno::Reference<uno::XComponentContext>& xContext, char const * name)
+: mContext(xContext)
+, mName( OUString::createFromAscii(name) )
+, mOutput(stderr)
+, mLevel(LogLevel::INFO)
+{
+ if (char const * fname = getenv("CFG_LOGFILE"))
+ {
+ mOutput = fopen(fname,"a+");
+ OSL_ENSURE(mOutput,"ERROR: could not open logfile\n");
+ }
+
+ if (char const * level = getenv("CFG_LOGLEVEL"))
+ {
+ mLevel = str2level(level);
+ }
+}
+//------------------------------------------------------------------------------
+SimpleLogger::~SimpleLogger()
+{
+}
+//------------------------------------------------------------------------------
+uno::Reference< logging::XLogger > SAL_CALL
+ SimpleLogger::getLogger( const OUString& name )
+ throw (uno::RuntimeException)
+{
+ if (name == mName) return this;
+
+ // try whatever
+ uno::Reference< logging::XLogger > xNamedLogger;
+ if (mContext.is())
+ {
+ OUString const singleton(RTL_CONSTASCII_USTRINGPARAM("/singletons/"));
+ mContext->getValueByName(singleton.concat(name)) >>= xNamedLogger;
+ }
+ return xNamedLogger;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 SAL_CALL SimpleLogger::getLevel( ) throw (uno::RuntimeException)
+{
+ return mLevel;
+}
+
+//------------------------------------------------------------------------------
+OUString SAL_CALL SimpleLogger::getName( ) throw (uno::RuntimeException)
+{
+ return mName;
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL SimpleLogger::isLoggable( sal_Int32 level ) throw (uno::RuntimeException)
+{
+ return mOutput && level >= mLevel;
+}
+
+//------------------------------------------------------------------------------
+#define OU2OUT( ustr ) ( rtl::OUStringToOString( ustr, enc ).getStr() )
+
+void SAL_CALL SimpleLogger::logp( sal_Int32 level, const OUString& sourceClass, const OUString& sourceMethod, const OUString& msg )
+ throw (uno::RuntimeException)
+{
+ rtl_TextEncoding enc = osl_getThreadTextEncoding();
+ if (mOutput && level > mLevel)
+ {
+ fprintf( mOutput, "%s {%s.%s}: [%s] %s\n", OU2OUT(mName),
+ OU2OUT(sourceClass) , OU2OUT(sourceMethod),
+ level2str(level).getStr(), OU2OUT(msg) );
+ }
+}
+
+//------------------------------------------------------------------------------
+
+OUString SAL_CALL SimpleLogger::getImplementationName_static()
+{
+ static const char kImplementationName[] = "com.sun.star.comp.configmgr.logging.SimpleLogger";
+
+ return OUString(RTL_CONSTASCII_USTRINGPARAM(kImplementationName)) ;
+}
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL SimpleLogger::getImplementationName()
+ throw (uno::RuntimeException)
+{
+ return getImplementationName_static() ;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString> SAL_CALL SimpleLogger::getSupportedServiceNames_static()
+{
+ uno::Sequence<rtl::OUString> aServices(2) ;
+ aServices[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.logging.SimpleLogger")) ;
+ aServices[1] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.logging.Logger")) ;
+
+ return aServices ;
+}
+//------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL SimpleLogger::supportsService(
+ const rtl::OUString& aServiceName)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< rtl::OUString > const svc = getSupportedServiceNames_static();
+
+ for(sal_Int32 i = 0; i < svc.getLength(); ++i )
+ if(svc[i] == aServiceName)
+ return true;
+ return false;
+}
+//------------------------------------------------------------------------------
+
+uno::Sequence<rtl::OUString>
+SAL_CALL SimpleLogger::getSupportedServiceNames()
+ throw (uno::RuntimeException)
+{
+ return getSupportedServiceNames_static() ;
+}
+//------------------------------------------------------------------------------
+
+
+} // namespace logger
diff --git a/configmgr/workben/logger/simplelogger.hxx b/configmgr/workben/logger/simplelogger.hxx
new file mode 100644
index 000000000000..81cfeb70a1ef
--- /dev/null
+++ b/configmgr/workben/logger/simplelogger.hxx
@@ -0,0 +1,86 @@
+#ifndef CONFIGMGR_SIMPLELOGGER_HXX_
+#define CONFIGMGR_SIMPLELOGGER_HXX_
+
+#include "simplelogger.hxx"
+#include <com/sun/star/util/logging/XLogger.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase2.hxx>
+
+#include <stdio.h>
+
+namespace logger {
+
+namespace uno = com::sun::star::uno ;
+namespace lang = com::sun::star::lang ;
+namespace logging = com::sun::star::util::logging ;
+using rtl::OUString;
+
+typedef cppu::WeakImplHelper2< logging::XLogger,
+ lang::XServiceInfo> LoggerBase ;
+
+
+/**
+ Class implementing the Logger service
+ */
+class SimpleLogger : public LoggerBase
+{
+public :
+ /**
+ Service constructor from a service factory.
+
+ @param xContext component context
+ */
+ explicit
+ SimpleLogger( const uno::Reference<uno::XComponentContext>& xContext, char const * name) ;
+
+ /** Destructor */
+ ~SimpleLogger() ;
+
+ // XLogger
+ virtual uno::Reference< logging::XLogger > SAL_CALL
+ getLogger( const OUString& name )
+ throw (uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getLevel( ) throw (uno::RuntimeException);
+ virtual OUString SAL_CALL getName( ) throw (uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isLoggable( sal_Int32 level ) throw (uno::RuntimeException);
+
+ virtual void SAL_CALL
+ logp( sal_Int32 level, const OUString& sourceClass, const OUString& sourceMethod, const OUString& msg )
+ throw (uno::RuntimeException);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw (uno::RuntimeException) ;
+
+ virtual sal_Bool SAL_CALL supportsService( const OUString& aServiceName)
+ throw (uno::RuntimeException) ;
+
+ virtual uno::Sequence<OUString> SAL_CALL
+ getSupportedServiceNames(void) throw (uno::RuntimeException) ;
+
+ /**
+ Provides the implementation name.
+
+ @return implementation name
+ */
+ static OUString SAL_CALL getImplementationName_static() ;
+ /**
+ Provides the list of supported services.
+
+ @return list of service names
+ */
+ static uno::Sequence<OUString> SAL_CALL getSupportedServiceNames_static() ;
+
+private:
+ /** Component Context */
+ uno::Reference<uno::XComponentContext> mContext ;
+ OUString mName;
+ FILE * mOutput;
+ sal_Int32 mLevel;
+} ;
+
+} // namespace logger
+
+#endif
diff --git a/configmgr/workben/memory/logmechanism.hxx b/configmgr/workben/memory/logmechanism.hxx
new file mode 100644
index 000000000000..a76886d33bd7
--- /dev/null
+++ b/configmgr/workben/memory/logmechanism.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: logmechanism.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_MACROS_DEBUG_LOGMECHANISM_HXX_
+#define __FRAMEWORK_MACROS_DEBUG_LOGMECHANISM_HXX_
+
+//*****************************************************************************************************************
+// generic macros for logging
+//*****************************************************************************************************************
+
+#ifdef ENABLE_LOGMECHANISM
+
+ //_____________________________________________________________________________________________________________
+ // includes
+ //_____________________________________________________________________________________________________________
+
+ #ifndef _RTL_STRING_HXX_
+ #include <rtl/string.hxx>
+ #endif
+
+ #include <stdio.h>
+
+ /*_____________________________________________________________________________________________________________
+ WRITE_LOGFILE( SFILENAME, STEXT )
+
+ Log any information in file. We append any information at file and don't clear it anymore.
+ ( Use new scope in macro to declare pFile more then on time in same "parentscope"!
+ Don't control pFile before access! What will you doing if its not valid? Log an error ...
+ An error and an error is an error ... )
+
+ Attention: You must use "%s" and STEXT as parameter ... because otherwise encoded strings (they include e.g. %...)
+ are handled wrong.
+ _____________________________________________________________________________________________________________*/
+
+ #define WRITE_LOGFILE( SFILENAME, STEXT ) \
+ { \
+ ::rtl::OString _swriteLogfileFileName ( SFILENAME ); \
+ ::rtl::OString _swriteLogfileText ( STEXT ); \
+ FILE* pFile = fopen( _swriteLogfileFileName.getStr(), "a" ); \
+ fprintf( pFile, "%s", _swriteLogfileText.getStr() ); \
+ fclose ( pFile ); \
+ }
+
+ /*_____________________________________________________________________________________________________________
+ LOGTYPE
+
+ For other debug macros we need information about the output mode. If user forget to set this information we
+ do it for him. Valid values are: LOGTYPE_FILECONTINUE
+ LOGTYPE_FILEEXIT
+ LOGTYPE_MESSAGEBOX
+ The normal case is LOGTYPE_MESSAGEBOX to show assertions in normal manner!
+ _____________________________________________________________________________________________________________*/
+
+ #define LOGTYPE_MESSAGEBOX 1
+ #define LOGTYPE_FILECONTINUE 2
+ #define LOGTYPE_FILEEXIT 3
+
+ #ifndef LOGTYPE
+ #define LOGTYPE \
+ LOGTYPE_MESSAGEBOX
+ #endif
+
+#else // #ifdef ENABLE_LOGMECHANISM
+
+ /*_____________________________________________________________________________________________________________
+ If right testmode is'nt set - implements these macro empty!
+ _____________________________________________________________________________________________________________*/
+
+ #define WRITE_LOGFILE( SFILENAME, STEXT )
+ #undef LOGTYPE
+
+#endif // #ifdef ENABLE_LOGMECHANISM
+
+//*****************************************************************************************************************
+// end of file
+//*****************************************************************************************************************
+
+#endif // #ifndef __FRAMEWORK_MACROS_DEBUG_LOGMECHANISM_HXX_
diff --git a/configmgr/workben/memory/main.cxx b/configmgr/workben/memory/main.cxx
new file mode 100644
index 000000000000..7d42754f1cf3
--- /dev/null
+++ b/configmgr/workben/memory/main.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: main.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <iostream>
+using namespace std;
+
+#define ENABLE_MEMORYMEASURE
+#define ENABLE_LOGMECHANISM
+
+// If you wish to enable this memory measure macros ... you need "windows.h"
+// But it's not agood idea to include it in your header!!! Because it's not compatible to VCL header .-(
+// So you must include it here ... in cxx, where you whish to use it.
+#ifdef ENABLE_MEMORYMEASURE
+ #define VCL_NEED_BASETSD
+ #include <tools/presys.h>
+ #include <windows.h>
+ #include <tools/postsys.h>
+ #undef VCL_NEED_BASETSD
+#endif
+#include "memorymeasure.hxx"
+
+#include "logmechanism.hxx"
+// -----------------------------------------------------------------------------
+// ---------------------------------- M A I N ----------------------------------
+// -----------------------------------------------------------------------------
+
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+int _cdecl main( int argc, char * argv[] )
+#endif
+{
+
+ START_MEMORYMEASURE( aMemoryInfo );
+
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "first start" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "1" );
+
+ sal_Char* pTest = new sal_Char[1000 * 1000 * 50];
+ sal_Char* pTest1 = new sal_Char[1000 * 1000 * 50];
+ sal_Char* pTest2 = new sal_Char[1000 * 1000 * 50];
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "2" );
+
+ LOG_MEMORYMEASURE( "FirstTest_of_memusage", "Values of memory access for standard filters.", aMemoryInfo );
+
+ return 0;
+}
+
diff --git a/configmgr/workben/memory/makefile.mk b/configmgr/workben/memory/makefile.mk
new file mode 100644
index 000000000000..cad7b533e6f2
--- /dev/null
+++ b/configmgr/workben/memory/makefile.mk
@@ -0,0 +1,259 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.9 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJINC=$(PRJ)$/source
+
+PRJNAME=configmgr
+
+TARGET=memorytest
+TARGET2=memorytesthack
+TARGETTYPE=CUI
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+# ... common for all test executables ..............................
+APPSTDLIBS=\
+ $(SALLIB) \
+ $(VOSLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+
+# ... cfgapi ..............................
+# APP1STDLIBS = $(APPSTDLIBS)
+#
+# APP1STDLIBS+=$(STDLIBCPP)
+#
+# APP1TARGET= $(TARGET)
+# APP1OBJS= \
+# $(SLO)$/cfgapi2.obj \
+# $(SLO)$/strimpl.obj \
+# $(SLO)$/typeconverter.obj \
+# $(SLO)$/simpletypehelper.obj \
+# $(SLO)$/memory.obj \
+
+# ... cfgapi ..............................
+APP2STDLIBS = $(APPSTDLIBS)
+
+APP2STDLIBS+= $(STDLIBCPP)
+
+# CFLAGS+=-DWITHOUTAPI
+
+APP2TARGET= $(TARGET2)
+APP2OBJS= \
+ $(SLO)$/memorytests.obj \
+ $(SLO)$/testmodules.obj \
+ $(SLO)$/treeload.obj \
+ $(SLO)$/accessimpl.obj \
+ $(SLO)$/adminproviderimpl.obj \
+ $(SLO)$/apiaccessobj.obj \
+ $(SLO)$/apifactory.obj \
+ $(SLO)$/apifactoryimpl.obj \
+ $(SLO)$/apinodeaccess.obj \
+ $(SLO)$/apinodeupdate.obj \
+ $(SLO)$/apinotifierimpl.obj \
+ $(SLO)$/apiserviceinfo.obj \
+ $(SLO)$/apitreeaccess.obj \
+ $(SLO)$/apitreeimplobj.obj \
+ $(SLO)$/attributelist.obj \
+ $(SLO)$/attributeparser.obj \
+ $(SLO)$/binarybasereader.obj \
+ $(SLO)$/binarydecide.obj \
+ $(SLO)$/binaryreader.obj \
+ $(SLO)$/binarywritehandler.obj \
+ $(SLO)$/binarywriter.obj \
+ $(SLO)$/bootstrap.obj \
+ $(SLO)$/broadcaster.obj \
+ $(SLO)$/cachewritescheduler.obj \
+ $(SLO)$/changes.obj \
+ $(SLO)$/cmtree.obj \
+ $(SLO)$/cmtreemodel.obj \
+ $(SLO)$/collectchanges.obj \
+ $(SLO)$/committer.obj \
+ $(SLO)$/confeventhelpers.obj \
+ $(SLO)$/confevents.obj \
+ $(SLO)$/configexcept.obj \
+ $(SLO)$/configgroup.obj \
+ $(SLO)$/confignotifier.obj \
+ $(SLO)$/configpath.obj \
+ $(SLO)$/configsession.obj \
+ $(SLO)$/configset.obj \
+ $(SLO)$/confname.obj \
+ $(SLO)$/confprovider2.obj \
+ $(SLO)$/confproviderimpl2.obj \
+ $(SLO)$/confsvccomponent.obj \
+ $(SLO)$/disposetimer.obj \
+ $(SLO)$/elementaccess.obj \
+ $(SLO)$/elementimpl.obj \
+ $(SLO)$/encodename.obj \
+ $(SLO)$/filehelper.obj \
+ $(SLO)$/generatecache.obj \
+ $(SLO)$/groupaccess.obj \
+ $(SLO)$/groupimpl.obj \
+ $(SLO)$/groupobjects.obj \
+ $(SLO)$/groupupdate.obj \
+ $(SLO)$/invalidatetree.obj \
+ $(SLO)$/listenercontainer.obj \
+ $(SLO)$/loader.obj \
+ $(SLO)$/localizednodebuilder.obj \
+ $(SLO)$/localizedtreeactions.obj \
+ $(SLO)$/localsession.obj \
+ $(SLO)$/matchlocale.obj \
+ $(SLO)$/mergechange.obj \
+ $(SLO)$/namehelper.obj \
+ $(SLO)$/nodechange.obj \
+ $(SLO)$/nodechangeimpl.obj \
+ $(SLO)$/nodechangeinfo.obj \
+ $(SLO)$/nodefactory.obj \
+ $(SLO)$/nodeimpl.obj \
+ $(SLO)$/nodeimplobj.obj \
+ $(SLO)$/noderef.obj \
+ $(SLO)$/notifycallback.obj \
+ $(SLO)$/oslstream.obj \
+ $(SLO)$/pathhelper.obj \
+ $(SLO)$/portalstream.obj \
+ $(SLO)$/propertiesfilterednotifier.obj \
+ $(SLO)$/propertyinfohelper.obj \
+ $(SLO)$/propertysetaccess.obj \
+ $(SLO)$/propsetaccessimpl.obj \
+ $(SLO)$/provider.obj \
+ $(SLO)$/providerfactory.obj \
+ $(SLO)$/providerimpl.obj \
+ $(SLO)$/receivethread.obj \
+ $(SLO)$/redirector.obj \
+ $(SLO)$/remotesession.obj \
+ $(SLO)$/roottree.obj \
+ $(SLO)$/saxadapter.obj \
+ $(SLO)$/saxtools.obj \
+ $(SLO)$/sessionfactory.obj \
+ $(SLO)$/sessionstream.obj \
+ $(SLO)$/setaccess.obj \
+ $(SLO)$/setnodeimpl.obj \
+ $(SLO)$/setobjects.obj \
+ $(SLO)$/setupdate.obj \
+ $(SLO)$/simpletypehelper.obj \
+ $(SLO)$/socketstream.obj \
+ $(SLO)$/strimpl.obj \
+ $(SLO)$/synchronize.obj \
+ $(SLO)$/template.obj \
+ $(SLO)$/templateimpl.obj \
+ $(SLO)$/timestamp.obj \
+ $(SLO)$/tracer.obj \
+ $(SLO)$/translatechanges.obj \
+ $(SLO)$/treeactions.obj \
+ $(SLO)$/treebuildercallback.obj \
+ $(SLO)$/treecache.obj \
+ $(SLO)$/treedata.obj \
+ $(SLO)$/treeimpl.obj \
+ $(SLO)$/treeiterators.obj \
+ $(SLO)$/treenodefactory.obj \
+ $(SLO)$/trivialbufferedfile.obj \
+ $(SLO)$/typeconverter.obj \
+ $(SLO)$/updatehandler.obj \
+ $(SLO)$/updateimpl.obj \
+ $(SLO)$/updatetree.obj \
+ $(SLO)$/userimpl.obj \
+ $(SLO)$/valueconverter.obj \
+ $(SLO)$/valuehandler.obj \
+ $(SLO)$/valuenodebuilder.obj \
+ $(SLO)$/writesubtreeasbinaryhandler.obj \
+ $(SLO)$/xmlformater.obj \
+ $(SLO)$/xmltreebuilder.obj \
+ $(SLO)$/valuemembernode.obj \
+ $(SLO)$/anypair.obj \
+
+# $(SLO)$/memory.obj \
+
+
+# $(SLO)$/strimpl.obj \
+# $(SLO)$/typeconverter.obj \
+# $(SLO)$/simpletypehelper.obj \
+# $(SLO)$/memory.obj \
+# $(SLO)$/loadwithtreemanager.obj \
+# $(SLO)$/localsession.obj \
+# $(SLO)$/configsession.obj \
+# $(SLO)$/confname.obj \
+# $(SLO)$/tracer.obj \
+# $(SLO)$/generatecache.obj \
+# $(SLO)$/treeactions.obj \
+# $(SLO)$/cmtreemodel.obj \
+# $(SLO)$/cmtree.obj \
+# $(SLO)$/xmltreebuilder.obj \
+# $(SLO)$/xmlformater.obj \
+# $(SLO)$/binaryreader.obj \
+# $(SLO)$/binarybasereader.obj \
+# $(SLO)$/binarywriter.obj \
+# $(SLO)$/binarywritehandler.obj \
+# $(SLO)$/binarydecide.obj \
+# $(SLO)$/writesubtreeasbinaryhandler.obj \
+# $(SLO)$/oslstream.obj \
+# $(SLO)$/pathhelper.obj \
+# $(SLO)$/treecache.obj \
+# $(SLO)$/updatetree.obj \
+# $(SLO)$/attributeparser.obj \
+# $(SLO)$/updatehandler.obj \
+# $(SLO)$/synchronize.obj \
+# $(SLO)$/filehelper.obj \
+# $(SLO)$/mergechange.obj \
+# $(SLO)$/providerimpl.obj \
+# $(SLO)$/bootstrap.obj \
+# $(SLO)$/matchlocale.obj \
+# $(SLO)$/changes.obj \
+# $(SLO)$/configexcept.obj \
+# $(SLO)$/valuehandler.obj \
+# $(SLO)$/treenodefactory.obj \
+# $(SLO)$/attributelist.obj \
+# $(SLO)$/namehelper.obj \
+# $(SLO)$/localizedtreeactions.obj \
+# $(SLO)$/trivialbufferedfile.obj \
+# $(SLO)$/cachewritescheduler.obj \
+# $(SLO)$/disposetimer.obj \
+# $(SLO)$/noderef.obj \
+# $(SLO)$/treedata.obj \
+# $(SLO)$/confevents.obj \
+# $(SLO)$/treebuildercallback.obj \
+# $(SLO)$/loader.obj \
+# $(SLO)$/apifactoryimpl.obj \
+# $(SLO)$/apitreeimplobj.obj \
+
+# $(SLO)$/.obj \
+
+
+.INCLUDE : target.mk
+
+
diff --git a/configmgr/workben/memory/memorymeasure.hxx b/configmgr/workben/memory/memorymeasure.hxx
new file mode 100644
index 000000000000..75313e23aa85
--- /dev/null
+++ b/configmgr/workben/memory/memorymeasure.hxx
@@ -0,0 +1,228 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: memorymeasure.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __FRAMEWORK_MACROS_DEBUG_MEMORYMEASURE_HXX_
+#define __FRAMEWORK_MACROS_DEBUG_MEMORYMEASURE_HXX_
+
+// *************************************************************************************************************
+// special macros for time measures
+// 1) LOGFILE_MEMORYMEASURE used it to define log file for this operations (default will be set automaticly)
+// 2) MAKE_MEMORY_SNAPSHOT make snapshot of currently set memory informations of OS
+// 3) LOG_MEMORYMEASURE write measured time to logfile
+// *************************************************************************************************************
+
+#ifdef ENABLE_MEMORYMEASURE
+
+#if !defined( WIN ) && !defined( WNT )
+#error "Macros to measure memory access not available under platforms different from windows!"
+#endif
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+
+#include <rtl/strbuf.hxx>
+
+#ifndef __SGI_STL_VECTOR
+#include <vector>
+#endif
+
+/*_____________________________________________________________________________________________________________
+ LOGFILE_MEMORYMEASURE
+
+ For follow macros we need a special log file. If user forget to specify anyone, we must do it for him!
+ _____________________________________________________________________________________________________________*/
+
+#ifndef LOGFILE_MEMORYMEASURE
+#define LOGFILE_MEMORYMEASURE "memorymeasure.log"
+#endif
+
+/*_____________________________________________________________________________________________________________
+ class MemoryMeasure
+
+ We use this baseclass to collect all snapshots in one object and analyze this information at one point.
+ Macros of this file are used to enable using of this class by special compile-parameter only!
+ _____________________________________________________________________________________________________________*/
+
+class _DBGMemoryMeasure
+{
+ //---------------------------------------------------------------------------------------------------------
+private:
+ struct _MemoryInfo
+ {
+ MEMORYSTATUS aStatus ;
+ ::rtl::OString sComment ;
+ };
+
+ //---------------------------------------------------------------------------------------------------------
+public:
+ //_____________________________________________________________________________________________________
+ inline _DBGMemoryMeasure()
+ {
+ makeSnapshot("Initializing Data");
+ }
+ //_____________________________________________________________________________________________________
+ inline _DBGMemoryMeasure(const ::rtl::OString& sComment)
+ {
+ makeSnapshot(sComment);
+ }
+
+ //_____________________________________________________________________________________________________
+ // clear used container!
+ inline ~_DBGMemoryMeasure()
+ {
+ ::std::vector< _MemoryInfo >().swap( m_lSnapshots );
+ }
+
+ //_____________________________________________________________________________________________________
+ inline void makeSnapshot( const ::rtl::OString& sComment )
+ {
+ _MemoryInfo aInfo;
+ aInfo.sComment = sComment;
+ GlobalMemoryStatus ( &(aInfo.aStatus) );
+ m_lSnapshots.push_back( aInfo );
+ }
+
+ //_____________________________________________________________________________________________________
+ inline ::rtl::OString getLog()
+ {
+ ::rtl::OStringBuffer sBuffer( 10000 );
+
+ if( m_lSnapshots.size() > 0 )
+ {
+ // Write informations to return buffer
+ ::std::vector< _MemoryInfo >::const_iterator pItem1;
+ ::std::vector< _MemoryInfo >::const_iterator pItem2;
+
+ pItem1 = m_lSnapshots.begin();
+ pItem2 = pItem1;
+ ++pItem2;
+
+ while( pItem1!=m_lSnapshots.end() )
+ {
+ sBuffer.append( "snap [ " );
+ sBuffer.append( pItem1->sComment );
+ sBuffer.append( " ]\n\tavail phys\t=\t" );
+ sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailPhys );
+ sBuffer.append( "\n\tavail page\t=\t" );
+ sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailPageFile );
+ sBuffer.append( "\n\tavail virt\t=\t" );
+ sBuffer.append( (sal_Int32)pItem1->aStatus.dwAvailVirtual );
+
+ if( pItem1 == m_lSnapshots.begin() )
+ {
+ sBuffer.append( "\n\t[initial values]\n\n" );
+ }
+ else if( pItem2 != m_lSnapshots.end() )
+ {
+ sBuffer.append( "\n\tdifference\t=\t[ " );
+ sBuffer.append( (sal_Int32)(pItem2->aStatus.dwAvailPhys - pItem1->aStatus.dwAvailPhys ) );
+ sBuffer.append( ", " );
+ sBuffer.append( (sal_Int32)(pItem2->aStatus.dwAvailPageFile - pItem1->aStatus.dwAvailPageFile ) );
+ sBuffer.append( ", " );
+ sBuffer.append( (sal_Int32)(pItem2->aStatus.dwAvailVirtual - pItem1->aStatus.dwAvailVirtual ) );
+ sBuffer.append( " ]\n\n" );
+ }
+ else
+ {
+ sBuffer.append( "\n\t[final values]\n\n" );
+ }
+ if( pItem1!=m_lSnapshots.end() ) ++pItem1;
+ if( pItem2!=m_lSnapshots.end() ) ++pItem2;
+ }
+ // clear current list ... make it empty for further snapshots!
+ ::std::vector< _MemoryInfo >().swap( m_lSnapshots );
+ }
+
+ return sBuffer.makeStringAndClear();
+ }
+
+ //---------------------------------------------------------------------------------------------------------
+private:
+ ::std::vector< _MemoryInfo > m_lSnapshots;
+};
+
+/*_____________________________________________________________________________________________________________
+ START_MEMORY_MEASURE
+
+ Create new object to measure memory access.
+ _____________________________________________________________________________________________________________*/
+
+#define START_MEMORYMEASURE( AOBJECT ) \
+ _DBGMemoryMeasure AOBJECT;
+
+#define START_MEMORYMEASURE_FOR( AOBJECT, SCOMMENT ) \
+ _DBGMemoryMeasure AOBJECT( SCOMMENT );
+
+ /*_____________________________________________________________________________________________________________
+ MAKE_MEMORY_SNAPSHOT
+
+ Make snapshot of currently set memory informations of OS.
+ see _DBGMemoryMeasure for further informations
+ _____________________________________________________________________________________________________________*/
+
+#define MAKE_MEMORY_SNAPSHOT( AOBJECT, SCOMMENT ) \
+ AOBJECT.makeSnapshot( SCOMMENT );
+
+ /*_____________________________________________________________________________________________________________
+ LOG_MEMORYMEASURE( SOPERATION, SCOMMENT, AOBJECT )
+
+ Write measured values to logfile.
+ _____________________________________________________________________________________________________________*/
+
+#define LOG_MEMORYMEASURE( SOPERATION, SCOMMENT, AOBJECT ) \
+ { \
+ ::rtl::OStringBuffer _sBuffer( 256 ); \
+ _sBuffer.append( SOPERATION ); \
+ _sBuffer.append( "\n" ); \
+ _sBuffer.append( SCOMMENT ); \
+ _sBuffer.append( "\n\n" ); \
+ _sBuffer.append( AOBJECT.getLog() ); \
+ WRITE_LOGFILE( LOGFILE_MEMORYMEASURE, _sBuffer.makeStringAndClear() ) \
+ }
+
+#else // #ifdef ENABLE_MEMORYMEASURE
+
+/*_____________________________________________________________________________________________________________
+ If right testmode is'nt set - implements these macros empty!
+ _____________________________________________________________________________________________________________*/
+
+#undef LOGFILE_MEMORYMEASURE
+#define START_MEMORYMEASURE( AOBJECT )
+#define MAKE_MEMORY_SNAPSHOT( AOBJECT, SCOMMENT )
+#define LOG_MEMORYMEASURE( SOPERATION, SCOMMENT, AOBJECT )
+
+#endif // #ifdef ENABLE_MEMORYMEASURE
+
+//*****************************************************************************************************************
+// end of file
+//*****************************************************************************************************************
+
+#endif // #ifndef __FRAMEWORK_MACROS_DEBUG_MEMORYMEASURE_HXX_
diff --git a/configmgr/workben/memory/memorytests.cxx b/configmgr/workben/memory/memorytests.cxx
new file mode 100644
index 000000000000..a3080e250c99
--- /dev/null
+++ b/configmgr/workben/memory/memorytests.cxx
@@ -0,0 +1,1244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: memorytests.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#define _PRIVATE_TEST_
+
+#include <iostream>
+#include <vector>
+#include "treeload.hxx"
+
+#include <fstream>
+
+#define ENABLE_MEMORYMEASURE
+#define ENABLE_LOGMECHANISM
+
+// If you wish to enable this memory measure macros ... you need "windows.h"
+// But it's not agood idea to include it in your header!!! Because it's not compatible to VCL header .-(
+// So you must include it here ... in cxx, where you whish to use it.
+#ifdef ENABLE_MEMORYMEASURE
+ #define VCL_NEED_BASETSD
+ #include <tools/presys.h>
+ #include <windows.h>
+ #include <tools/postsys.h>
+ #undef VCL_NEED_BASETSD
+#endif
+#include "memorymeasure.hxx"
+
+#include "logmechanism.hxx"
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Any.h>
+#include <osl/profile.hxx>
+#include <osl/process.h>
+#include <osl/file.h>
+
+#include <conio.h>
+
+#include "createpropertyvalue.hxx"
+
+#include "typeconverter.hxx"
+
+#include "testmodules.hxx"
+
+#include "valuenode.hxx"
+
+namespace configmgr
+{
+
+using namespace std;
+
+namespace css = com::sun::star;
+namespace uno = css::uno;
+namespace lang = css::lang;
+
+using namespace uno;
+using namespace lang;
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::util;
+
+using ::rtl::OUString;
+using ::rtl::OString;
+
+using namespace ::cppu;
+
+#define ASCII(x) ::rtl::OUString::createFromAscii(x)
+
+ostream& operator << (ostream& out, rtl::OUString const& aStr)
+{
+ sal_Unicode const* const pStr = aStr.getStr();
+ sal_Unicode const* const pEnd = pStr + aStr.getLength();
+ for (sal_Unicode const* p = pStr; p < pEnd; ++p)
+ if (0 < *p && *p < 127) // ASCII
+ out << char(*p);
+ else
+ out << "[\\u" << hex << *p << "]";
+ return out;
+}
+
+void showSequence(const Sequence<OUString> &aSeq)
+{
+ OUString aArray;
+ const OUString *pStr = aSeq.getConstArray();
+ for (int i=0;i<aSeq.getLength();i++)
+ {
+ OUString aStr = pStr[i];
+ // aArray += aStr + ASCII(", ");
+ cout << aStr << endl;
+ }
+ volatile int dummy = 0;
+}
+
+//=============================================================================
+
+inline void operator <<= (::rtl::OUString& _rUnicodeString, const sal_Char* _pAsciiString)
+{
+ _rUnicodeString = ::rtl::OUString::createFromAscii(_pAsciiString);
+}
+
+inline void operator <<= (::rtl::OUString& _rUnicodeString, const ::rtl::OString& _rAsciiString)
+{
+ _rUnicodeString <<= _rAsciiString.getStr();
+}
+
+inline void operator <<= (Any& _rUnoValue, const sal_Char* _pAsciiString)
+{
+ _rUnoValue <<= ::rtl::OUString::createFromAscii(_pAsciiString);
+}
+
+inline void operator <<= (Any& _rUnoValue, const ::rtl::OString& _rAsciiString)
+{
+ _rUnoValue <<= _rAsciiString.getStr();
+}
+
+inline void operator <<= (::rtl::OString& _rAsciiString, ::rtl::OUString const& _rUnicodeString )
+{
+ _rAsciiString = rtl::OUStringToOString(_rUnicodeString, RTL_TEXTENCODING_ASCII_US).getStr();
+}
+
+// -----------------------------------------------------------------------------
+
+rtl::OString input(const char* pDefaultText, char cEcho)
+{
+ // PRE: a Default Text would be shown, cEcho is a Value which will show if a key is pressed.
+ const int MAX_INPUT_LEN = 500;
+ char aBuffer[MAX_INPUT_LEN];
+
+ strcpy(aBuffer, pDefaultText);
+ int nLen = strlen(aBuffer);
+
+#ifdef WNT
+ char ch = '\0';
+
+ cout << aBuffer;
+ cout.flush();
+
+ while(ch != 13)
+ {
+ ch = getch();
+ if (ch == 8)
+ {
+ if (nLen > 0)
+ {
+ cout << "\b \b";
+ cout.flush();
+ --nLen;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ cout << "\a";
+ cout.flush();
+ }
+ }
+ else if (ch != 13)
+ {
+ if (nLen < MAX_INPUT_LEN)
+ {
+ if (cEcho == 0)
+ {
+ cout << ch;
+ }
+ else
+ {
+ cout << cEcho;
+ }
+ cout.flush();
+ aBuffer[nLen++] = ch;
+ aBuffer[nLen] = '\0';
+ }
+ else
+ {
+ cout << "\a";
+ cout.flush();
+ }
+ }
+ }
+#else
+ if (!cin.getline(aBuffer,sizeof aBuffer))
+ return OString();
+#endif
+ return rtl::OString(aBuffer);
+}
+
+// -----------------------------------------------------------------------------
+rtl::OUString enterValue(const char* _aStr, const char* _aDefault, bool _bIsAPassword)
+{
+ cout << _aStr;
+ cout.flush();
+
+ rtl::OUString sValue;
+ sValue <<= input(_aDefault, _bIsAPassword ? '*' : 0);
+ return sValue;
+}
+//=============================================================================
+
+uno::Reference< lang::XMultiServiceFactory > getORB();
+// -----------------------------------------------------------------------------
+
+
+Reference< XChangesBatch > xChangesBatch = NULL;
+void commit()
+{
+ if (xChangesBatch.is())
+ {
+ xChangesBatch->commitChanges();
+ }
+}
+
+// -----------------------------------------------------------------------------
+static sal_Bool s_bInitialized = sal_False;
+#ifdef LLA_PRIVAT_DEBUG
+// static const sal_Char* s_pSourcePath = "//./l|/src632/configmgr/workben/local_io/share";
+// static const sal_Char* s_pUpdatePath = "//./l|/src632/configmgr/workben/local_io/user";
+static const sal_Char* s_pSourcePath = "file:///f:/office60_633/share/config/registry";
+static const sal_Char* s_pUpdatePath = "file:///f:/office60_633/user/config/registry";
+static const sal_Char* s_pRootNode = "org.openoffice.test";
+static const sal_Char* s_pServerType = "local";
+static const sal_Char* s_pLocale = "de-DE";
+static const sal_Char* s_pServer = "";
+static const sal_Char* s_pUser = "";
+static const sal_Char* s_pPassword = "";
+#else
+static const sal_Char* s_pSourcePath = "file:///g:/src/configmgr/workben/local_io/share";
+static const sal_Char* s_pUpdatePath = "file:///g:/src/configmgr/workben/local_io/user";
+static const sal_Char* s_pRootNode = "org.openoffice.test";
+static const sal_Char* s_pServerType = "local";
+static const sal_Char* s_pLocale = "de-DE";
+static const sal_Char* s_pServer = "lautrec-3108:19205";
+static const sal_Char* s_pUser = "lars";
+static const sal_Char* s_pPassword = "";
+#endif
+
+static bool m_bChange = false;
+// -----------------------------------------------------------------------------
+static void loadDefaults()
+{
+ if (s_bInitialized)
+ return;
+
+ s_bInitialized = sal_True;
+
+ try
+ {
+ // the executable file name
+ ::rtl::OUString sExecutable;
+ osl_getExecutableFile(&sExecutable.pData);
+ // cut the name, add a cfgapi.ini to the path
+ sal_Int32 nLastSep = sExecutable.lastIndexOf('/');
+ if (-1 != nLastSep)
+ sExecutable = sExecutable.copy(0, nLastSep + 1);
+#ifdef UNX
+ sExecutable += ::rtl::OUString::createFromAscii("cfgapirc");
+#else
+ sExecutable += ::rtl::OUString::createFromAscii("cfgapi.ini");
+#endif
+ ::rtl::OUString sNormalized;
+ sNormalized = sExecutable;
+ if (1) // osl_File_E_None == osl_normalizePath(sExecutable.pData, &sNormalized.pData))
+ {
+ ::osl::Profile aProfile(sNormalized);
+
+ static ::rtl::OString sSection("defaults");
+ static ::rtl::OString sSourcePath("sourcepath");
+ static ::rtl::OString sUpdatePath("updatepath");
+ static ::rtl::OString sRootNode("rootnode");
+ static ::rtl::OString sServerType("servertype");
+ static ::rtl::OString sLocale("Locale");
+ static ::rtl::OString sServer("Server");
+ static ::rtl::OString sUser("User");
+ static ::rtl::OString sPassword("Password");
+
+ // read some strings.
+ // Do this static because we want to redirect the global static character pointers to the buffers.
+ static ::rtl::OString s_sSourcePath = aProfile.readString(sSection, sSourcePath, s_pSourcePath);
+ static ::rtl::OString s_sUpdatePath = aProfile.readString(sSection, sUpdatePath, s_pUpdatePath);
+ static ::rtl::OString s_sRootNode = aProfile.readString(sSection, sRootNode, s_pRootNode);
+ static ::rtl::OString s_sServerType = aProfile.readString(sSection, sServerType, s_pServerType);
+ static ::rtl::OString s_sLocale = aProfile.readString(sSection, sLocale, s_pLocale);
+ static ::rtl::OString s_sServer = aProfile.readString(sSection, sServer, s_pServer);
+ static ::rtl::OString s_sUser = aProfile.readString(sSection, sUser, s_pUser);
+ static ::rtl::OString s_sPassword = aProfile.readString(sSection, sPassword, s_pPassword);
+
+ // do this redirection
+ s_pSourcePath = s_sSourcePath.getStr();
+ s_pUpdatePath = s_sUpdatePath.getStr();
+ s_pRootNode = s_sRootNode.getStr();
+ s_pServerType = s_sServerType.getStr();
+ s_pLocale = s_sLocale.getStr();
+ s_pServer = s_sServer.getStr();
+ s_pUser = s_sUser.getStr();
+ s_pPassword = s_sPassword.getStr();
+ }
+ }
+ catch(std::exception& e)
+ {
+ e.what(); // silence warnings
+ }
+}
+
+// -----------------------------------------------------------------------------
+Sequence<Any> createSequence(const OUString &sUser, const OUString &sPasswd)
+{
+ Sequence< Any > aCPArgs;
+
+ if (sUser.getLength() > 0)
+ {
+ aCPArgs.realloc(1);
+ aCPArgs[0] <<= configmgr::createPropertyValue(ASCII("user"), sUser);
+ }
+ if (sPasswd.getLength() > 0)
+ {
+ aCPArgs.realloc(2);
+ aCPArgs[1] <<= configmgr::createPropertyValue(ASCII("password"), sPasswd);
+ }
+ return aCPArgs;
+}
+
+//=============================================================================
+#include <string.h>
+#if (defined UNX) || (defined OS2)
+#else
+#include <conio.h>
+#endif
+
+// -----------------------------------------------------------------------------
+
+void test_configuration_provider(uno::Reference<lang::XMultiServiceFactory> _xCfgProvider,
+ rtl::OUString const& _sUser, bool _bLocal, sal_Int32 _nCount);
+
+
+// -----------------------------------------------------------------------------
+
+uno::Reference<lang::XMultiServiceFactory>
+getProvider(
+ uno::Reference< lang::XMultiServiceFactory > _xServiceRegistry,
+ rtl::OUString const& _sServerType,
+ rtl::OUString const& _sSharePath, rtl::OUString const& _sUserPath,
+ bool &_bLocal)
+{
+ try
+ {
+ Sequence< Any > aCPArgs;
+
+ OUString sServerType = _sServerType; // enterValue("servertype: ", s_pServerType, false);
+
+ rtl::OUString sUser;
+
+ _bLocal = sServerType.equalsIgnoreAsciiCase(ASCII("local")) || sServerType.equalsIgnoreAsciiCase(ASCII("setup"));
+ if (!_bLocal)
+ {
+ rtl::OUString sServer;
+ sServer = enterValue("server : ", s_pServer,false);
+ cout << endl;
+
+ sUser = enterValue("user : ", s_pUser, false);
+ cout << endl;
+
+ OUString sPasswd = enterValue("password: ", s_pPassword, true);
+ cout << endl;
+
+ aCPArgs = createSequence(sUser, sPasswd);
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("server"), sServer);
+
+ OUString sTimeout = ASCII("10000");
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("timeout"), sTimeout);
+
+ }
+ else
+ {
+ rtl::OUString sSharePath, sUserPath;
+ sSharePath = _sSharePath;// enterValue("share path: ", s_pSourcePath, false);
+ // cout << endl;
+ sUserPath = _sUserPath; // enterValue("user path : ", s_pUpdatePath, false);
+ // cout << endl;
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ sal_Int32 nCount = aCPArgs.getLength() - 1;
+ Any *pAny = &aCPArgs[nCount];
+ *pAny <<= configmgr::createPropertyValue(ASCII("sourcepath"), sSharePath);
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("updatepath"), sUserPath);
+ }
+
+ aCPArgs.realloc(aCPArgs.getLength() + 1);
+ aCPArgs[aCPArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("servertype"), sServerType);
+
+ Reference< XMultiServiceFactory > xCfgProvider(
+ _xServiceRegistry->createInstanceWithArguments(
+ ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"),
+ aCPArgs),
+ UNO_QUERY);
+ if (!xCfgProvider.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the configuration provider !\n\n";
+ return 0;
+ }
+// -----------------------------------------------------------------------------
+ return xCfgProvider;
+ }
+ catch (Exception& e)
+ {
+ ::flush(cout);
+ cerr << "Caught exception: " << e.Message << endl;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+sal_Int32 m_nCount = 0;
+
+void test(uno::Reference<lang::XMultiServiceFactory> _xORB, rtl::OUString const& _sSharePath,
+ rtl::OUString const& _sUserPath)
+{
+
+ rtl::OUString sUser;
+ bool bLocal;
+ cout << ++m_nCount << ". start test with new provider\n";
+ {
+ START_MEMORYMEASURE_FOR( aMemoryInfo, "*** API Test Execution ***" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "initialisierungs-check" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "- Erzeuge Provider" );
+
+ uno::Reference<lang::XMultiServiceFactory>xCfgProvider =
+ getProvider(_xORB, ASCII("local"), _sSharePath, _sUserPath,
+ bLocal);
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "- Habe Provider, starte Test" );
+
+ test_configuration_provider(xCfgProvider, sUser, bLocal, 0); // xml
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "- Test gelaufen, starte erneut" );
+
+ test_configuration_provider(xCfgProvider, sUser, bLocal, 0); // xml
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "- Test gelaufen, entsorge Provider" );
+
+ uno::Reference<lang::XComponent>xComponent(xCfgProvider,UNO_QUERY);
+ xComponent->dispose();
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "- Provider disposed" );
+
+ LOG_MEMORYMEASURE( "---------------- API Memory Test 2-----------------------------", "- Test memory traces.", aMemoryInfo );
+ }
+
+ cout << "finish provider test\n";
+
+ // Test Version 1 and 3, it MUST be equal
+}
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+static rtl::OUString makeFileURL(OUString const& sMaybeURL)
+{
+ rtl::OUString const fileURLStart(RTL_CONSTASCII_USTRINGPARAM("file:/"));
+
+ if ( 0 != fileURLStart.compareTo(sMaybeURL, fileURLStart.getLength()) )
+ {
+ OUString sURL;
+ if (!osl_getFileURLFromSystemPath(sMaybeURL.pData, &sURL.pData))
+ return sURL;
+ }
+
+ return sMaybeURL;
+}
+// -----------------------------------------------------------------------------
+static rtl::OUString makeSystemPath(OUString const& sMaybeURL)
+{
+ rtl::OUString const fileURLStart(RTL_CONSTASCII_USTRINGPARAM("file:/"));
+
+ if ( 0 == fileURLStart.compareTo(sMaybeURL, fileURLStart.getLength()) )
+ {
+ OUString sSysPath;
+ if (!osl_getSystemPathFromFileURL(sMaybeURL.pData, &sSysPath.pData))
+ return sSysPath;
+ }
+
+ return sMaybeURL;
+}
+// -----------------------------------------------------------------------------
+// ---------------------------------- M A I N ----------------------------------
+// -----------------------------------------------------------------------------
+
+int main( int argc, char * argv[] )
+{
+ TimeValue aTimeout;
+ aTimeout.Seconds = 5;
+ aTimeout.Nanosec = 0;
+
+ sal_Int32 nSizeISubtree = sizeof(ISubtree);
+ sal_Int32 nSizeINode = sizeof(INode);
+ sal_Int32 nSizeIValueNode = sizeof(ValueNode);
+ {
+ loadDefaults();
+
+ Reference< XMultiServiceFactory > xORB = getORB();
+
+ rtl::OUString sSharePath = makeSystemPath(enterValue("share path: ", s_pSourcePath, false));
+ cout << endl;
+ rtl::OUString sUserPath = makeSystemPath(enterValue("user path : ", s_pUpdatePath, false));
+ cout << endl;
+
+ // test(xORB, sSharePath, sUserPath, ASCII("org.openoffice.test"));
+
+ // char* pMem = new char[1000 * 1000 * 10];
+ // showMemoryStatistic();
+
+// test(xORB, sSharePath, sUserPath, ASCII("org.openoffice.Office.Views"));
+
+ START_MEMORYMEASURE_FOR( aMemoryInfo, "*** API Test Main ***" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "initialisierungs-check" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "starte test !" );
+
+ test(xORB, sSharePath, sUserPath);
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "tests beendet !" );
+
+ // stop the programm clear.
+ Reference< XComponent > xComponent(xORB, UNO_QUERY);
+ xComponent->dispose();
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "ORB disposed." );
+
+ LOG_MEMORYMEASURE( "---------------- API Memory Test-------------------------------", "Outer memory traces.", aMemoryInfo );
+ }
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+void test(Reference< XHierarchicalName >& xAccessName)
+{
+ if (xAccessName.is())
+ {
+ // cout << "Accessing Node: " << xAccessName->getHierarchicalName();
+ }
+ else
+ {
+ // cout << "BUG: XHierarchicalName not available";
+ }
+ // cout << endl;
+}
+void test(Reference< XNamed >& xAccess)
+{
+ if (xAccess.is())
+ {
+ // cout << "Node is named: " << xAccess->getName();
+ }
+ else
+ {
+ // cout << "BUG: XNamed not available";
+ }
+ // cout << endl;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+void fillAllNames(Reference<XNameAccess >& xAccess, Sequence<OUString>& _aSeq)
+{
+ if (xAccess.is())
+ {
+ _aSeq = Sequence <OUString>(xAccess->getElementNames());
+
+ // cout << "Element Names: (" << _aSeq.getLength() << ")";
+ // for (int i = 0; i < _aSeq.getLength(); ++i)
+ // cout << "\n[" << i << "] -\t" << _aSeq[i];
+ //cout << endl;
+ }
+ else
+ {
+ // cout << "BUG: XNameAccess not available";
+ }
+ // cout << endl;
+}
+void write(Reference< XChild >& xChild)
+{
+ if (xChild.is())
+ {
+ // cout << "\n[ P ] -\tParent";
+ }
+ else
+ {
+ // cout << "BUG: Parent not available (no XChild)";
+ }
+ // cout << endl;
+}
+///////////////////////////////////////////////////////////////////////////////////////////
+
+// -----------------------------------------------------------------------------
+Reference< XInterface > readaccess(uno::Reference< lang::XMultiServiceFactory > &xMSF,
+ uno::Reference< uno::XInterface > const& xIface,
+ rtl::OString const& buf,
+ ostream& outStream)
+{
+ Reference< XInterface > xNext;
+ try
+ {
+ Reference< XNameAccess > xAccess(xIface, UNO_QUERY);
+ Reference< XHierarchicalNameAccess > xDeepAccess(xIface, UNO_QUERY);
+ Reference< XExactName > xExactName(xIface, UNO_QUERY);
+
+ if (xAccess.is() || xDeepAccess.is())
+ {
+ OUString aName;
+ OUString aInput = OUString::createFromAscii(buf);
+
+ if (xExactName.is())
+ {
+ ::rtl::OUString sTemp = xExactName->getExactName(aInput);
+ if (sTemp.getLength())
+ aInput = sTemp;
+ }
+
+ if (xAccess.is() && xAccess->hasByName(aInput))
+ {
+ aName = aInput;
+ }
+ else if (xDeepAccess.is() && xDeepAccess->hasByHierarchicalName(aInput))
+ {
+ aName = aInput;
+ }
+ else if ('0' <= buf[0] && buf[0] <= '9' && xAccess.is())
+ {
+ int n = atoi(buf);
+ Sequence<OUString> aNames = xAccess->getElementNames();
+ if (0 <= n && n < aNames.getLength())
+ aName = aNames[n];
+ }
+
+ if (aName.getLength())
+ {
+ bool bNest = aInput.indexOf(sal_Unicode('/')) >= 0;
+
+ Any aElement = bNest ?
+ ( xDeepAccess.is() ?
+ xDeepAccess->getByHierarchicalName(aName) : Any()
+ ) :
+ ( xAccess.is() ?
+ xAccess->getByName(aName) : Any()
+ );
+
+ while (aElement.getValueTypeClass() == TypeClass_ANY)
+ {
+ Any aWrap(aElement);
+ aWrap >>= aElement;
+ }
+ sal_Bool bValue = true;
+ sal_Bool bValueOk = false;
+
+ switch (aElement.getValueTypeClass() )
+ {
+ case TypeClass_INTERFACE:
+ bValue = false;
+ if (aElement >>= xNext)
+ {
+ outStream << "Group: " << aName << endl;
+ }
+ else
+ {
+ outStream << "ERROR: can't get the interface" << endl;
+ }
+ break;
+ case TypeClass_BOOLEAN:
+ {
+ sal_Bool* pVal = (sal_Bool*)aElement.getValue();
+ bValueOk = (pVal != 0);
+
+ outStream << "VALUE '" << aName << "' is a BOOLEAN = ";
+ if (!bValueOk)
+ outStream << "NULL (error!!)";
+ else if (*pVal)
+ outStream << "'TRUE'";
+ else
+ outStream << "'FALSE'";
+
+ outStream << endl;
+
+ // tryToChange(xAccess, aName, pVal);
+ break;
+ }
+ case TypeClass_SHORT:
+ {
+ sal_Int16 aValue;
+ outStream << "VALUE '" << aName << "' is a SHORT (16 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ outStream << aValue;
+ // tryToChange(xAccess, aName, aValue);
+ }
+ else
+ {
+ outStream << "ERROR RETRIEVING VALUE";
+ }
+ outStream << endl;
+
+ break;
+ }
+ case TypeClass_LONG:
+ {
+
+ sal_Int32 aValue;
+ outStream << "VALUE '" << aName << "' is a INT (32 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ outStream << aValue;
+ // tryToChange(xAccess, aName, aValue);
+ }
+ else
+ {
+ outStream << "ERROR RETRIEVING VALUE";
+ }
+ outStream << endl;
+ break;
+ }
+ case TypeClass_HYPER:
+ {
+ sal_Int64 aValue;
+ outStream << "VALUE '" << aName << "' is a LONG (64 bit) = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ outStream << double(aValue);
+ // tryToChange(xAccess, aName, aValue);
+ }
+ else
+ {
+ outStream << "ERROR RETRIEVING VALUE";
+ }
+ outStream << endl;
+ break;
+ }
+ case TypeClass_DOUBLE:
+ {
+ double aValue;
+ outStream << "VALUE '" << aName << "' is a DOUBLE = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ outStream << aValue;
+ }
+ else
+ {
+ outStream << "ERROR RETRIEVING VALUE";
+ }
+ outStream << endl;
+ break;
+ }
+ case TypeClass_STRING:
+ {
+ OUString aValue;
+ outStream << "VALUE '" << aName << "' is a STRING = ";
+ if (bValueOk = (aElement >>= aValue))
+ {
+ outStream << "\"" << aValue << "\"";
+ // tryToChange(xAccess, aName, aValue);
+ }
+ else
+ {
+ outStream << "ERROR RETRIEVING VALUE";
+ }
+ outStream << endl;
+ break;
+ }
+ case TypeClass_SEQUENCE:
+ {
+ outStream << "VALUE '" << aName << "' is a SEQUENCE or BINARY" << endl;
+
+ Type aTypeS = configmgr::getSequenceElementType(aElement.getValueType());
+ OUString sType = configmgr::toTypeName(aTypeS.getTypeClass());
+ outStream << "UNO type is " << aElement.getValueType().getTypeName() << endl;
+ outStream << "Real type is Sequence<" << sType << ">" << endl;
+ // outSequence(aElement, aTypeS, outStream);
+ bValueOk = true;
+ break;
+ }
+ case TypeClass_VOID:
+ outStream << "ELEMENT '" << aName << "' is NULL and VOID " << endl;
+ bValueOk = true;
+ break;
+ default:
+ outStream << "Error: ELEMENT '" << aName << "' is of unknown or unrecognized type" << endl;
+ break;
+ }
+
+ }
+ else
+ {
+ outStream << "Error: No element \"" << aInput << "\" found." <<endl;
+ }
+ }
+ }
+ catch (Exception& e)
+ {
+ outStream << "An Exception occurred: " << e.Message << endl;
+ }
+ catch (...)
+ {
+ outStream << "An UNKNOWN Exception occurred !" << endl;
+ }
+
+ return xNext;
+}
+
+
+
+
+// -----------------------------------------------------------------------------
+void test_read_access( uno::Reference< lang::XMultiServiceFactory > &xMSF,
+ uno::Reference< uno::XInterface >& xIface,
+ ofstream & out)
+{
+ Sequence<OUString> aAllNames;
+
+ using com::sun::star::uno::UNO_QUERY;
+
+ // cout << "\n\n---------------------------------------------------------------" << endl;
+ Reference< XNameAccess > xAccess(xIface, UNO_QUERY);
+ Reference< XChild > xChild(xIface, UNO_QUERY);
+ Reference< XHierarchicalName > xAccessPath(xIface,UNO_QUERY);
+ Reference< XNamed > xAccessName(xIface,UNO_QUERY);
+// Reference< XHierarchicalNameAccess >& xAccess(xIface, UNO_QUERY);
+
+ test(xAccessPath);
+ test(xAccessName);
+ fillAllNames(xAccess, aAllNames);
+ write(xChild);
+
+ for (sal_Int32 i=0;i<aAllNames.getLength();i++)
+ {
+ OString aValue;
+ aValue <<= aAllNames[i];
+ uno::Reference<uno::XInterface> xFace = readaccess(xMSF, xIface, aValue, out);
+ if (xFace.is())
+ {
+ test_read_access(xMSF, xFace, out);
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+void test_read_access( uno::Reference< lang::XMultiServiceFactory > &xMSF,
+ uno::Reference< uno::XInterface >& xIface,
+ rtl::OString aFilename)
+{
+ ofstream out(aFilename.getStr());
+ test_read_access(xMSF, xIface, out);
+}
+
+// -----------------------------------------------------------------------------
+void test_configuration_provider(uno::Reference<lang::XMultiServiceFactory> _xCfgProvider,
+ rtl::OUString const& _sUser, bool _bLocal,
+ sal_Int32 _nCount)
+{
+ START_MEMORYMEASURE_FOR( aMemoryInfo, "*** Configuration Provider Loop Test ***" );
+ START_MEMORYMEASURE_FOR( aInnerMemoryInfo, "*** Configuration Provider Module Details ***" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "initialisierungs-check" );
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, "initialisierungs-check" );
+
+ std::vector< Reference< XInterface > > aLoadedModules;
+ aLoadedModules.reserve(configtest::s_nTestModules);
+
+ Sequence< Any > aArgs;
+ aArgs = createSequence(_sUser, ASCII(""));
+
+ if (!_bLocal)
+ {
+ OUString sLocale = enterValue("locale : ", s_pLocale, false);
+ cout << endl;
+ aArgs.realloc(aArgs.getLength() + 1);
+ aArgs[aArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("locale"), sLocale);
+ }
+
+#if 0
+ sal_Bool bLazyWrite = true;
+ aArgs.realloc(aArgs.getLength() + 1);
+ aArgs[aArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("lazywrite"), bLazyWrite);
+#else
+ sal_Bool bNoCache = true;
+ aArgs.realloc(aArgs.getLength() + 1);
+ aArgs[aArgs.getLength() - 1] <<= configmgr::createPropertyValue(ASCII("nocache"), bNoCache);
+#endif
+
+ sal_Int32 nPathIdx = aArgs.getLength();
+ aArgs.realloc(nPathIdx + 1);
+
+ const OString sInnerInfoText("- - - Loading module: ");
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, "- - - Before Loading Modules" );
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "- - Prepared Arguments - Lade Module" );
+
+ for (char const * const * ppTestModule = configtest::s_aTestModules; *ppTestModule; ++ppTestModule)
+ {
+ OUString sPath = OUString::createFromAscii(*ppTestModule);
+ cout << "\t" << ++_nCount << ". test with node: " << sPath << endl;
+
+ aArgs[nPathIdx] <<= configmgr::createPropertyValue(ASCII("nodepath"), sPath);
+
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, sInnerInfoText.concat(*ppTestModule) );
+ Reference< XInterface > xIFace = _xCfgProvider->createInstanceWithArguments(
+ /* OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"), */
+ OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"),
+ aArgs);
+ // cout << "---------------------------------------------------------------\n Configuration Read/Write Access created !\n---------------------------------------------------------------" << endl;
+
+ aLoadedModules.push_back(xIFace);
+ /*
+ xChangesBatch = Reference< XChangesBatch >(xIFace, UNO_QUERY);
+
+ Sequence<OUString> aSeq = _xCfgProvider->getAvailableServiceNames();
+
+ OString sPath;
+ sPath <<= _sPath;
+
+ OString aFilename = "c:\\temp\\fileout_";
+ aFilename += sPath;
+ aFilename += OString::valueOf(_nCount);
+ aFilename += ".txt";
+ test_read_access(_xCfgProvider, xIFace, aFilename);
+ */
+ }
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, "- - - Done Loading modules" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "- - Alle Module geladen" );
+
+ aLoadedModules.clear();
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "- - Module released" );
+
+ LOG_MEMORYMEASURE( "---------------- API Memory Test 3 -----------------------------", "- - Provider memory traces.", aMemoryInfo );
+ LOG_MEMORYMEASURE( "---------------- API Memory Test 4 -----------------------------", "- - - Module memory traces.", aInnerMemoryInfo );
+
+}
+
+
+// -----------------------------------------------------------------------------
+// ----------------------------------- Main 2 -----------------------------------
+// -----------------------------------------------------------------------------
+
+int requestTest( int argc, char * argv[] )
+{
+ TimeValue aTimeout;
+ aTimeout.Seconds = 5;
+ aTimeout.Nanosec = 0;
+
+ sal_Int32 nSizeISubtree = sizeof(ISubtree);
+ sal_Int32 nSizeINode = sizeof(INode);
+ sal_Int32 nSizeIValueNode = sizeof(ValueNode);
+ {
+ loadDefaults();
+
+ Reference< XMultiServiceFactory > xORB = getORB();
+
+ rtl::OUString sSharePath = makeFileURL(enterValue("share path: ", s_pSourcePath, false));
+ cout << endl;
+ rtl::OUString sUserPath = makeFileURL(enterValue("user path : ", s_pUpdatePath, false));
+ cout << endl;
+
+ START_MEMORYMEASURE_FOR( aMemoryInfo, "*** Request Tree Test ***" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "initialisierungs-check" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "create tree manager" );
+
+ OTreeLoad aTreeLoad(xORB, sSharePath, sUserPath);
+ sal_Int32 nIdx = 0;
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "created tree manager" );
+
+ OString const sInnerInfoText("- Loading module: ");
+
+ START_MEMORYMEASURE_FOR( aInnerMemoryInfo, "*** Request Tree Test Details ***" );
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, "initialisierungs-check" );
+
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, "- before loading modules" );
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "request subtrees" );
+
+ for (char const * const * ppRequestModule = configtest::s_aTestModules; *ppRequestModule; ++ppRequestModule)
+ {
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, sInnerInfoText.concat(*ppRequestModule) );
+ aTreeLoad.requestSubtree( OUString::createFromAscii(*ppRequestModule));
+ }
+
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, "- loaded all modules" );
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "release subtrees" );
+
+ for (char const * const * ppReleaseModule = configtest::s_aTestModules; *ppReleaseModule; ++ppReleaseModule)
+ aTreeLoad.releaseSubtree( OUString::createFromAscii(*ppReleaseModule));
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "ich habe fertig." );
+ LOG_MEMORYMEASURE( "---------------- Request Memory Test ---------------------------", "Direct Cache Access memory traces.", aMemoryInfo );
+ LOG_MEMORYMEASURE( "---------------- Request Memory Detail -------------------------", "Module request memory traces.", aInnerMemoryInfo );
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+// --------------------------------- Trust Test ---------------------------------
+// -----------------------------------------------------------------------------
+
+int trust( int argc, char * argv[] )
+{
+ Reference< XMultiServiceFactory > xORB = getORB();
+
+ std::vector<char*> aMemHolder;
+ aMemHolder.reserve(1024);
+
+ START_MEMORYMEASURE_FOR( aMemoryInfo, "Allocator check" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "initialisierungs-check" );
+
+ sal_Int32 const total_alloc = 8 * 1024 * 1024;
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "get 8 MB" );
+
+ char* pChar = new char[total_alloc];
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "free 8 MB" );
+
+ delete [] pChar;
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "deleted 8 MB" );
+
+ sal_Int32 const chunk = 8 * 1024;
+ sal_Int32 const alloc_count = total_alloc/chunk;
+
+ sal_Int32 const msg_count = 16;
+ sal_Int32 const loop_count = alloc_count/msg_count;
+ sal_Int32 const loop_allocation = loop_count * chunk;
+
+ OString const sPieces = OString::valueOf(alloc_count).concat(" pieces");
+ OString const sInnerMessage = OString("Allocating ").concat(OString::valueOf(loop_count))
+ .concat(" chunks [").concat(OString::valueOf(loop_allocation)).concat(" Bytes].");
+
+ START_MEMORYMEASURE( aInnerMemoryInfo );
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, "initialisierungs-check" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, OString("get 8 MB as ").concat(sPieces) );
+
+ for (sal_Int32 i=0;i<alloc_count/loop_count;i++)
+ {
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, sInnerMessage );
+ for (sal_Int32 j=0;j<loop_count;j++)
+ {
+
+ pChar = new char[8 * 1024];
+ aMemHolder.push_back(pChar);
+ }
+ }
+ MAKE_MEMORY_SNAPSHOT( aInnerMemoryInfo, "last allocation done" );
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "free pieces" );
+
+ pChar = NULL;
+ for (std::vector<char*>::iterator it = aMemHolder.begin();
+ it != aMemHolder.end();
+ it++)
+ {
+ pChar = *it;
+ delete []pChar;
+ }
+ aMemHolder.clear();
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, OString("get another 8 MB as ").concat(sPieces) );
+
+
+ for (sal_Int32 j=0;j<alloc_count;j++)
+ {
+ pChar = new char[8 * 1024];
+ aMemHolder.push_back(pChar);
+ }
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "free second set of pieces" );
+
+ pChar = NULL;
+ for (std::vector<char*>::iterator jt = aMemHolder.begin();
+ jt != aMemHolder.end();
+ jt++)
+ {
+ pChar = *jt;
+ delete []pChar;
+ }
+ aMemHolder.clear();
+
+ MAKE_MEMORY_SNAPSHOT( aMemoryInfo, "ich habe fertig." );
+ LOG_MEMORYMEASURE( "---------------- Trust Memory Test ----------------------------", "Cross-checked memory traces.", aMemoryInfo );
+ LOG_MEMORYMEASURE( "---------------- Small Allocation Loop ------------------------", "Allocation Loop Detail memory traces.", aInnerMemoryInfo );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+static uno::Reference< lang::XMultiServiceFactory > g_xORB;
+static void createORB(char const* pRegistry)
+{
+ if (!g_xORB.is())
+ try
+ {
+ rtl::OUString const sServiceRegistry = OUString::createFromAscii(pRegistry);
+
+ g_xORB = createRegistryServiceFactory( sServiceRegistry, ::rtl::OUString() );
+
+ }
+ catch (uno::Exception &e)
+ {
+ cerr << "Exception creating the service factory: " << e.Message << "\n";
+ }
+ else
+ cerr << "Trying to recreate the service factory\n";
+
+ if (!g_xORB.is())
+ {
+ ::flush(cout);
+ cerr << "Could not create the service factory '" << pRegistry << "' !\n";
+ exit(-2);
+ }
+}
+uno::Reference< lang::XMultiServiceFactory > getORB()
+{
+ if (!g_xORB.is())
+ {
+ createORB( "applicat.rdb" );
+ }
+ return g_xORB;
+}
+// -----------------------------------------------------------------------------
+
+
+} // namespace configmgr
+// -----------------------------------------------------------------------------
+void usage()
+{
+ cerr << "Wrong or missing parameters.\nUsage:\n"
+ "\tmemorytest [-r <registry.rdb>] (all | trust | request | api)+ [clear] [(+<module>|-<module>)+]\n";
+
+ exit(-1);
+}
+
+// -----------------------------------------------------------------------------
+// ------------------------------------ Main ------------------------------------
+// -----------------------------------------------------------------------------
+#if (defined UNX) || (defined OS2)
+int main( int argc, char * argv[] )
+#else
+int _cdecl main( int argc, char * argv[] )
+#endif
+{
+ if (argc > 1 && !::rtl_str_compare(argv[1], "-r" ) )
+ {
+ if (!argv[2]) usage();
+
+ configmgr::createORB(argv[2]);
+
+ argv += 2;
+ argc -= 2;
+ }
+ configmgr::getORB(); // ensures there is one
+
+ enum TestSelect { TEST_TRUST = 01, TEST_REQUEST = 02, TEST_API = 04, TEST_ALL = 07 };
+
+ unsigned nSelect = 0;
+ while (argc >= 1 && argv[1] != NULL)
+ {
+ if ( !::rtl_str_compareIgnoreAsciiCase(argv[1], "trust" ) ) nSelect |= TEST_TRUST;
+ else if ( !::rtl_str_compareIgnoreAsciiCase(argv[1], "request") ) nSelect |= TEST_REQUEST;
+ else if ( !::rtl_str_compareIgnoreAsciiCase(argv[1], "api" ) ) nSelect |= TEST_API;
+ else if ( !::rtl_str_compareIgnoreAsciiCase(argv[1], "all" ) ) nSelect |= TEST_ALL;
+ else break;
+
+ // here we found a known selector, so look on
+ ++argv;
+ --argc;
+ }
+
+ if (nSelect == 0) usage();
+
+//--------------------
+#define DO_TEST( test, func ) \
+ if (nSelect & TEST_##test) \
+ { \
+ char const * const test_name = #test; \
+ if (int nRet = func(argc, argv)) \
+ cerr << "Test: " << test_name << " returned with error code " << nRet << endl; \
+ else \
+ cerr << "Test: " << test_name << " finished without error !\n" ; \
+ } else // to allow a semicolon
+//--------------------
+
+ DO_TEST( TRUST , configmgr::trust );
+ DO_TEST( REQUEST , configmgr::requestTest );
+ DO_TEST( API , configmgr::main );
+
+ return 0;
+}
+
diff --git a/configmgr/workben/memory/testmodules.cxx b/configmgr/workben/memory/testmodules.cxx
new file mode 100644
index 000000000000..c914cc54bc3a
--- /dev/null
+++ b/configmgr/workben/memory/testmodules.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: testmodules.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include "testmodules.hxx"
+
+
+namespace configtest
+{
+ #if 0 // more modules
+ +"org.openoffice.Office.Common",
+ +"org.openoffice.Office.Linguistic",
+ x"org.openoffice.Office.TypeDetection",
+ x"org.openoffice.Setup",
+ -"org.openoffice.UserProfile",
+ +"org.openoffice.Inet",
+ -"org.openoffice.Office.Calc",
+ -"org.openoffice.Office.Chart",
+ -"org.openoffice.Office.DataAccess",
+ -"org.openoffice.Office.Draw",
+ -"org.openoffice.Office.Impress",
+ -"org.openoffice.Office.Java",
+ -"org.openoffice.Office.Labels",
+ -"org.openoffice.Office.Math",
+ +"org.openoffice.Office.Views",
+ +"org.openoffice.Office.Writer",
+ +"org.openoffice.Office.WriterWeb",
+ +"org.openoffice.ucb.Configuration",
+ -"org.openoffice.ucb.Hierarchy",
+ x"org.openoffice.ucb.Store",
+ #endif
+
+ char const * const s_aTestModules[] =
+ {
+ "org.openoffice.Office.Common",
+ "org.openoffice.Setup/CJK/Enable",
+ "org.openoffice.Setup/Office/Modules",
+ "org.openoffice.Inet",
+ "org.openoffice.Office.Views",
+ "org.openoffice.Setup/Product",
+ "org.openoffice.ucb.Configuration",
+ "org.openoffice.ucb.Store/ContentProperties",
+ "org.openoffice.Office.TypeDetection",
+ "org.openoffice.Office.Writer",
+ "org.openoffice.Office.WriterWeb",
+ "org.openoffice.Office.Linguistic",
+ NULL // end marker
+ };
+ unsigned int const s_nTestModules = sizeof s_aTestModules/sizeof 0[s_aTestModules];
+
+ std::vector<char const *> listTestModules(int argc, char* argv[])
+ {
+ std::vector<char const *> aModuleList( s_aTestModules, s_aTestModules + s_nTestModules);
+ return aModuleList;
+ }
+}
+
+
diff --git a/configmgr/workben/memory/testmodules.hxx b/configmgr/workben/memory/testmodules.hxx
new file mode 100644
index 000000000000..ed76bb894340
--- /dev/null
+++ b/configmgr/workben/memory/testmodules.hxx
@@ -0,0 +1,41 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: testmodules.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef CONFIGMGR_WORKBEN_TESTMODULES_
+#include <vector>
+
+namespace configtest
+{
+ extern char const * const s_aTestModules[];
+ extern unsigned int const s_nTestModules;
+ extern std::vector<char const *> listTestModules(int argc, char* argv[]);
+}
+#endif // CONFIGMGR_WORKBEN_TESTMODULES_
+
diff --git a/configmgr/workben/memory/treeload.cxx b/configmgr/workben/memory/treeload.cxx
new file mode 100644
index 000000000000..f1f578c3efae
--- /dev/null
+++ b/configmgr/workben/memory/treeload.cxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: treeload.cxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <localsession.hxx>
+#include <treecache.hxx>
+#include <options.hxx>
+#include <rtl/ustring.hxx>
+#include "treeload.hxx"
+
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+#define ASCII(x) ::rtl::OUString::createFromAscii(x)
+
+// -----------------------------------------------------------------------------
+// ------------------------- requestSubtree without API -------------------------
+// -----------------------------------------------------------------------------
+
+ OTreeLoad::OTreeLoad(uno::Reference<lang::XMultiServiceFactory> const& _xServiceProvider,
+ rtl::OUString const& _sSourceDirectory, rtl::OUString const& _sUpdateDirectory) throw (uno::Exception)
+ :m_xServiceProvider(_xServiceProvider)
+{
+ // Create a TypeConverter
+ uno::Reference<script::XTypeConverter> xConverter;
+ xConverter = xConverter.query(m_xServiceProvider->createInstance(ASCII( "com.sun.star.script.Converter" )) );
+
+ m_xDefaultOptions = new OOptions(xConverter);
+ m_xDefaultOptions->setNoCache(true);
+
+ // create it .. and connect
+ std::auto_ptr<LocalSession> pLocal( new LocalSession(m_xServiceProvider) );
+ sal_Bool bOpen = pLocal->open(_sSourceDirectory, _sUpdateDirectory);
+
+ IConfigSession* pConfigSession = pLocal.release();
+
+ m_pTreeMgr = new TreeManager(pConfigSession, m_xDefaultOptions);
+}
+// -----------------------------------------------------------------------------
+ISubtree* OTreeLoad::requestSubtree( OUString const& aSubtreePath) throw (uno::Exception)
+{
+ return m_pTreeMgr->requestSubtree(aSubtreePath, m_xDefaultOptions, /* MinLevel */ -1);
+}
+// -----------------------------------------------------------------------------
+void OTreeLoad::releaseSubtree( OUString const& aSubtreePath) throw (uno::Exception)
+{
+ m_pTreeMgr->releaseSubtree(aSubtreePath, m_xDefaultOptions);
+}
+
+// -----------------------------------------------------------------------------
+} // namespace
diff --git a/configmgr/workben/memory/treeload.hxx b/configmgr/workben/memory/treeload.hxx
new file mode 100644
index 000000000000..088c5d24d4cc
--- /dev/null
+++ b/configmgr/workben/memory/treeload.hxx
@@ -0,0 +1,41 @@
+#ifndef CONFIGMGR_TREELOAD_HXX
+#define CONFIGMGR_TREELOAD_HXX
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#ifndef _CONFIGMGR_LOCAL_LOCAL_HXX_
+#include <localsession.hxx>
+#endif
+
+#ifndef _CONFIGMGR_TREECACHE_HXX_
+#include <treecache.hxx>
+#endif
+#include <options.hxx>
+#include <rtl/ustring.hxx>
+
+// -----------------------------------------------------------------------------
+namespace configmgr
+{
+ namespace uno = ::com::sun::star::uno;
+ namespace lang = ::com::sun::star::lang;
+
+// -----------------------------------------------------------------------------
+class OTreeLoad
+{
+ // LocalSession* m_pLocalSession; // in TreeMgr
+ TreeManager* m_pTreeMgr;
+ ::vos::ORef<OOptions> m_xDefaultOptions;
+ uno::Reference<lang::XMultiServiceFactory> m_xServiceProvider;
+
+public:
+
+ OTreeLoad(uno::Reference<lang::XMultiServiceFactory> const& _xServiceProvider,
+ rtl::OUString const& _sSourceDirectory, rtl::OUString const& _sUpdateDirectory);
+
+ ISubtree* requestSubtree(rtl::OUString const& aSubtreePath);
+ void releaseSubtree(rtl::OUString const& aSubtreePath);
+};
+
+} // namespace
+
+#endif