migrate parents to phosphorus-sr1

generate sr1 parents and add script for this

Issue-ID: CCSDK-3565
Signed-off-by: Michael DÜrre <michael.duerre@highstreet-technologies.com>
Change-Id: I53c5bed11d3d336df5ca99f521a210067663571d
Signed-off-by: Michael DÜrre <michael.duerre@highstreet-technologies.com>
diff --git a/tools/lib/pomfile.py b/tools/lib/pomfile.py
new file mode 100644
index 0000000..35dfd5a
--- /dev/null
+++ b/tools/lib/pomfile.py
@@ -0,0 +1,109 @@
+import re
+import tempfile
+import tempfile
+import glob
+import shutil
+from .xpath import XPath
+
+class PomFile:
+
+    def __init__(self, filename):
+        self.filename=filename
+
+    def hasParent(self) -> bool:
+        pattern_compiled = re.compile('<project[>\ ]')
+        inProject=False
+        with open(self.filename,'r') as src_file:
+                for line in src_file:
+                    m = pattern_compiled.search(line)
+                    if m is not None:
+                        if inProject == True:
+                            return True
+                        inProject=True
+                        pattern_compiled = re.compile('<parent[>\ ]')
+        return False
+                    
+
+    def setDependencyVersion(self, groupId, artifactId, version) -> bool:
+        return self.setXmlValue('/project/dependencies/dependency[groupId={},artifactId={}]/version'.format(groupId,artifactId),version)
+    def setDependencyManagementVersion(self, groupId, artifactId, version) -> bool:
+        return self.setXmlValue('/project/dependencyManagement/dependencies/dependency[groupId={},artifactId={}]/version'.format(groupId,artifactId),version)
+    # set xmlElementValue (just simple values - no objects)
+    # valuePath: xpath
+    #    e.g. /project/parent/version
+    #         /project/dependencies/dependency[groupId=org.opendaylight.netconf]/version
+    # value: value to set
+    def setXmlValue(self, valuePath, value, replaceMultiple=False) -> bool:
+        
+        found=False
+        pathToFind = XPath(valuePath)
+        pattern = re.compile('<([^>^\ ^?^!]+)')
+        curPath=XPath()
+        curParent=None
+        isComment=False
+        with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp_file:
+            with open(self.filename) as src_file:
+                for line in src_file:
+                    if found == False or replaceMultiple:
+                        x=line.find('<!--')
+                        y=line.find('-->')
+                        if x>=0:
+                            isComment=True
+                        if y>=0 and y > x:
+                            isComment=False
+                        if not isComment:
+                            matches = pattern.finditer(line,y)
+                            for matchNum, match in enumerate(matches, 1):
+                                f = match.group(1)
+                                # end tag detected
+                                if f.startswith("/"):
+                                    curPath.remove(f[1:])
+                                # start tag detected (not autoclosing xml like <br />)
+                                elif not f.endswith("/"):
+                                    x = curPath.add(f)
+                                    if curParent is None:
+                                        curParent = x
+                                    else:
+                                        curParent = curPath.last(1)
+                                else:
+                                    continue
+                                if pathToFind.equals(curPath, False):
+                                    pre=line[0:line.index('<')]
+                                    line=pre+'<{x}>{v}</{x}>\n'.format(x=f,v=value)
+                                    found=True
+                                    curPath.remove(f)
+                                    break
+                                elif pathToFind.parentParamIsNeeded(curPath.subpath(1), f):
+                                    v = self.tryToGetValue(line, f)
+                                    if v is not None:
+                                        curParent.setFilter(f, v)
+
+                    tmp_file.write(line)
+            # Overwrite the original file with the munged temporary file in a
+            # manner preserving file attributes (e.g., permissions).
+            shutil.copystat(self.filename, tmp_file.name)
+            shutil.move(tmp_file.name, self.filename)
+        print("set {} to {} in {}: {}".format(valuePath, value, self.filename, str(found)))
+        return found
+
+    def tryToGetValue(self, line, xmlTag=None):
+        pattern = re.compile('<([^>^\ ^?^!]+)>([^<]+)<\/([^>^\ ^?^!]+)>' if xmlTag is None else '<('+xmlTag+')>([^<]+)<\/('+xmlTag+')>') 
+        matches = pattern.finditer(line)
+        match = next(matches)
+        if match is not None:
+            return match.group(2)
+        return None
+
+    @staticmethod
+    def findAll(folder, excludes=[]):
+        files= glob.glob(folder + "/**/pom.xml", recursive = True)
+        r=[]
+        for file in files:
+            doExclude=False
+            for exclude in excludes:
+                if exclude in file:
+                    doExclude=True
+                    break
+            if not doExclude:
+                r.append(file)
+        return r
diff --git a/tools/lib/xpath.py b/tools/lib/xpath.py
new file mode 100644
index 0000000..07f8e38
--- /dev/null
+++ b/tools/lib/xpath.py
@@ -0,0 +1,84 @@
+
+import re
+
+
+class XPathComponent:
+    regex = r"([^\/^\[]+)(\[([^\]]+)\])?"
+    def __init__(self, expr):
+        matches = re.finditer(XPathComponent.regex, expr, re.DOTALL | re.IGNORECASE)
+        match = next(matches)
+        self.name = match.group(1)
+        tmp = match.group(3) if len(match.groups())>2 else None
+        self.filter = tmp.split(',') if tmp is not None else [] 
+
+    def equals(self, comp, ignoreFilter=False) -> bool:
+        if ignoreFilter:
+            return self.name == comp.name
+        if self.name == comp.name:
+            return set(self.filter) == set(comp.filter)
+        return False
+    
+    def setFilter(self, f, v):
+        self.filter.append('{}={}'.format(f,v))
+
+    def hasFilter(self, propertyName):
+        search=propertyName+'='
+        for filter in self.filter:
+            if filter.startswith(search):
+                return True
+        return False
+
+    def __str__(self) -> str:
+        return "XPathComponent[name={}, filter={}]".format(self.name, self.filter)
+    
+class XPath:
+
+    def __init__(self, expr=None):
+        self.raw = expr
+        tmp = expr.split('/') if expr is not None else []
+        self.components=[]
+        if len(tmp)>0 and len(tmp[0])==0:
+            tmp.pop(0)
+        for x in tmp:
+            self.components.append(XPathComponent(x))
+    
+    def add(self, c: str) -> XPathComponent:
+        xc=XPathComponent(c)
+        self.components.append(xc)
+        return xc
+
+    def remove(self, c: str) -> bool:
+        if self.components[len(self.components)-1].equals(XPathComponent(c), True):
+            self.components.pop()
+            return True
+        return False
+
+    def parentParamIsNeeded(self, xp, paramName) -> bool:
+        for i in range(len(xp.components)):
+            if i>=len(self.components):
+                return False
+            if not self.components[i].equals(xp.components[i], True):
+                return False
+        return self.components[len(xp.components)-1].hasFilter(paramName)
+
+    def equals(self, path, ignoreFilter=False) -> bool:
+        if len(self.components) != len(path.components):
+            return False
+
+        for i in range(len(self.components)):
+            if not self.components[i].equals(path.components[i], ignoreFilter):
+                return False
+        return True
+
+    def lastname(self) -> str:
+        tmp = self.last()
+        return tmp.name if tmp is not None else ""
+
+    def last(self, off=0) -> XPathComponent:
+        return self.components[len(self.components)-1-off] if len(self.components)>off else None
+
+    def subpath(self, off=0):
+        tmp =XPath()
+        for i in range(len(self.components)-off):
+            tmp.components.append(self.components[i])
+        return tmp
\ No newline at end of file