My first thought was very procedural: lets do it do old fashioned way and create a class which will traverse the folder tree of a project and build a list of all the mappings. The class I built looks like this:
import oracle.odi.domain.mapping.Mapping
import oracle.odi.domain.mapping.finder.IMappingFinder
import oracle.odi.domain.project.OdiProject
/**
* A class to find all Mapping objects within a project
* All folders are traversed recursively and the mappings are returned in a collection.
*/
class FindMappings {
def private allMappings = null
def processProject(odiInstance, projectCode) {
def odiProjectsList = (odiInstance.getTransactionalEntityManager().getFinder(OdiProject.class).findByCode(projectCode))
odiProjectsList.each { p ->
def odiFoldersList = p.getFolders()
odiFoldersList.each { f ->
/* process interfaces of the current folder */
this.listMappings(odiInstance, p.getCode(), f.getName())
/* Process sub folders recursively */
this.processSubFolder(odiInstance, f, p.getCode())
}
}
return (allMappings)
}
def private listMappings(odiInstance, projectCode, folderName) {
def mappingList = ((IMappingFinder) odiInstance.getTransactionalEntityManager().getFinder(Mapping.class)).findByProject(projectCode, folderName)
if (allMappings == null) {
allMappings = mappingList
} else {
allMappings = allMappings + mappingList
}
}
/* given an odiInstance, folder and project code, we will parse all subfolders (recursively) and print the name of all interfaces found at all levels*/
def private processSubFolder(odiInstance, Folder, projectCode) {
def subFolderList = Folder.getSubFolders()
if (subFolderList.size() != 0) {
subFolderList.each { s ->
/* process interfaces of the current folder */
this.listMappings(odiInstance, projectCode, s.getName())
/* Process sub folders recursively */
this.processSubFolder(odiInstance, s, projectCode)
}
}
}
}
The entry point is the processProject method which we pass a project code. The result is a collection of mappings. I felt a bit unsatisfied by the result, although it works well I kept thinking there must be a better way to do this. Being fairly new to groovy I have not yet had the opportunity the get to know all the ins and outs of the language, but when I was looking at the documentation for collections I got thinking if I could rewrite the class to a few lines of code, and indeed it is possible.
As I mentioned before there is no findByProject method in the IMappingFinder class, however it does inherit a findAll method from its parent. So we can find all mappings in a repository as follows:
def mappingList = ((IMappingFinder) odiInstance.getTransactionalEntityManager().getFinder(Mapping.class)).findAll()Now we’ve got a list of all mappings in the repository, but I only want the mappings in a specific project. We can select these by using the collection and object methods in combination with closures. The resulting find will look like this:
def mappingList = ((IMappingFinder) odiInstance.getTransactionalEntityManager().getFinder(Mapping.class)).findAll().findAll{w -> w.getProject().getCode() == '<projectCode>'}
This one line of code does the same as the class does I built first.
Slightly rewritten to make it a bit more readable, it could look like this:
def tme = odiInstance.getTransactionalEntityManager() // Shortcut to transaction manager
def fm = ((IMappingFinder) tme.getFinder(Mapping.class)) // shorcut to Find Mapping
def mappingList = fm.findAll().findAll{w -> w.getProject().getCode() == '<projectCode>'}
We can keep on chaining these commands together like:
// Find all mappings in project DEMO which start with 'DEM'
def mappingList = fm.findAll().findAll { w -> w.getProject().getCode() == 'DEMO' }.findAll {w -> w.getName()[0..2] == 'DEM'}
// Find all mappings in project DEMO which name contains STG
def mappingList = fm.findAll().findAll { w -> w.getProject().getCode() == 'DEMO' }.findAll {w -> w.getName().contains('STG')}
Very interesring, thanks!
ReplyDeleteVery powerful, thanks!
ReplyDelete