class Block(ConfigItem): """ConfigItem indicates block config like: <xxx yyyyy>...</xxx>""" def __init__(self, name, value=None, block=None, is_root=False): super(Block, self).__init__(name, value, block) self.__configs = ConfigItems() # config items direct in the block self.__is_root = is_root # if this block is root block def appendChild(self, *items): """append a config item to the block; set this config item's block to this block""" for item in items: if isinstance(item, ConfigItem): item.block = self self.__configs.append(item) @property def configs(self): return self.__configs def isRoot(self): return self.__is_root def lines(self, step=0): lines = [] if not self.isRoot(): lines = ['%s<%s %s>' % (' ' * step, self.name, self.value or '')] for config in self.configs: lines.extend(config.lines(step+1)) lines.append('%s</%s>' % (' ' * step, self.name)) else: for config in self.configs: lines.extend(config.lines(step)) return lines
class Block(ConfigItem): """ConfigItem indicates block config like: <xxx yyyyy>...</xxx>""" def __init__(self, name, value=None, block=None, is_root=False): super(Block, self).__init__(name, value, block) self.__configs = ConfigItems() # config items direct in the block self.__is_root = is_root # if this block is root block def appendChild(self, *items): """append a config item to the block; set this config item's block to this block""" for item in items: if isinstance(item, ConfigItem): item.block = self self.__configs.append(item) @property def configs(self): return self.__configs def isRoot(self): return self.__is_root def lines(self, step=0): lines = [] if not self.isRoot(): lines = [ '%s<%s %s>' % (' ' * step, self.name, self.value or '') ] for config in self.configs: lines.extend(config.lines(step + 1)) lines.append('%s</%s>' % (' ' * step, self.name)) else: for config in self.configs: lines.extend(config.lines(step)) return lines
class ConfigItem(object): """Base ConfigItem class""" def __init__(self, name, value=None, block=None): self.__name = name self.__value = value self.__block = block # parent block @property def name(self): return self.__name @property def value(self): return self.__value def getBlock(self): return self.__block def setBlock(self, block): self.__block = block block = property(getBlock, setBlock) def lines(self, step=0): """Display strings split by line break""" return '%s%s:%s' % (' ' * step, self.name, self.value), def __repr__(self): return '\n'.join(self.lines()) @property def root(self): """root block of this config item""" if hasattr(self, '__root'): return self.__root root = self.block while root and root.block and not root.isRoot(): root = root.block self.__root = root return root @property def parents(self): """root block of this config item""" if hasattr(self, '__parents'): return self.__parents self.__parents = ConfigItems() current = self.block while current and not current.isRoot(): self.__parents.append(current) current = current.block return self.__parents
class ApacheConfParser(object): def __init__(self, shell): self.shell = shell self.rootBlock = Block( '', is_root=True) # the root block of the Apache config self.items = ConfigItems() # all the parsed config items self.contentsIterator = self.ContentsIterator() def parseApacheConf(self, content, contentPath="", contentName=""): """ Parse Apache Config :param content: content of Apache config :param contentPath: the file path of the given content :param contentName: the file name of the given content """ if content is None: return self.rootBlock = Block('', is_root=True) self.items = ConfigItems() self.contentsIterator = self.ContentsIterator() currentBlock = self.rootBlock self.contentsIterator.addContent(self.shell, content, contentPath, contentName) for iterator in self.contentsIterator: line, lineNumber, path, name = iterator if not line: continue line = line.strip() if not line or line[0] == '#': continue try: parserRule = getApacheConfParserRule(line) if parserRule: item = parserRule.parse(line) if item and isinstance(item, ConfigItem): currentBlock.appendChild(item) self.items.append(item) currentBlock = parserRule.getNextBlock(item, currentBlock) parserRule.postParse(self, item, path) else: logger.warn( "cannot find parser rule for config: %s. (%s Line %s)" % (line, getPathOperation(self.shell).join( path, name), lineNumber)) except ApacheConfigParserException, e: raise ApacheConfigParserException( '%s: %s Line %s' % (e.message, getPathOperation( self.shell).join(path, name), lineNumber)) if currentBlock != self.rootBlock: raise ApacheConfigParserException( 'Missing block end at the end of config file: %s' % getPathOperation(self.shell).join(contentPath, contentName))
class ApacheConfParser(object): def __init__(self, shell): self.shell = shell self.rootBlock = Block('', is_root=True) # the root block of the Apache config self.items = ConfigItems() # all the parsed config items self.contentsIterator = self.ContentsIterator() def parseApacheConf(self, content, contentPath="", contentName=""): """ Parse Apache Config :param content: content of Apache config :param contentPath: the file path of the given content :param contentName: the file name of the given content """ if content is None: return self.rootBlock = Block('', is_root=True) self.items = ConfigItems() self.contentsIterator = self.ContentsIterator() currentBlock = self.rootBlock self.contentsIterator.addContent(self.shell, content, contentPath, contentName) for iterator in self.contentsIterator: line, lineNumber, path, name = iterator if not line: continue line = line.strip() if not line or line[0] == '#': continue try: parserRule = getApacheConfParserRule(line) if parserRule: item = parserRule.parse(line) if item and isinstance(item, ConfigItem): currentBlock.appendChild(item) self.items.append(item) currentBlock = parserRule.getNextBlock(item, currentBlock) parserRule.postParse(self, item, path) else: logger.warn("cannot find parser rule for config: %s. (%s Line %s)" % ( line, getPathOperation(self.shell).join(path, name), lineNumber)) except ApacheConfigParserException, e: raise ApacheConfigParserException('%s: %s Line %s' % ( e.message, getPathOperation(self.shell).join(path, name), lineNumber)) if currentBlock != self.rootBlock: raise ApacheConfigParserException('Missing block end at the end of config file: %s' % getPathOperation(self.shell).join(contentPath, contentName))