-
Notifications
You must be signed in to change notification settings - Fork 0
/
properties.py
116 lines (105 loc) · 3.56 KB
/
properties.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class PropLineReader:
def __init__( self, s ):
self.lines = s.split( "\n" )
self.line_count = len( self.lines )
self.next_line = 0
def read_line( self ):
if self.next_line >= self.line_count:
return None
r = ""
while True:
line = self.lines[self.next_line].strip()
print( "line={}".format( line ) )
self.next_line += 1
if line.endswith( "\\" ):
r = "{}{}".format( r, line[0:-1] )
elif len( r ) <= 0:
return line
else:
return "{}{}".format( r, line )
class Properties:
"""
this class reads the .properties from file or from a string and provides
APIs for the value access by key
"""
escape_table = {'r': '\r', 'n': '\n', 't': '\t', '\\': '\\' }
escape_rev_table = {'\r': 'r', '\n': 'n', '\t': 't', '\\': '\\' }
def __init__( self, props ):
self.props = props
@classmethod
def from_file( clss, filename ):
"""
load .properties file
"""
with open( filename ) as fp:
return clss.from_string( fp.read() )
@classmethod
def from_string( clss, s ):
"""
load .properties from string
"""
line_reader = PropLineReader( s )
props = {}
while True:
line = line_reader.read_line()
if line is None:
break
line = line.strip()
if line.startswith( '#' ):
continue
pos1 = line.find( '=' )
pos2 = line.find( ':' )
if pos1 == -1:
pos = pos2
else:
pos = pos1 if pos2 == -1 or pos1 < pos2 else pos2
if pos != -1:
name = line[0:pos].strip()
value = clss._remove_escape( line[pos+1:].strip() )
props[ name ] = value
return Properties( props )
def has_property( self, name ):
"""
return True if the specified properties exists or not
"""
return name in self.props
def get_property( self, name ):
"""
get the properties by name
"""
return self.props[ name ] if name in self.props else None
def set_property( self, name, value ):
"""
set the property with its name and value
"""
self.props[ name ] = value
def __repr__( self ):
r = ""
for name, value in self.props.iteritems():
if len( r ) > 0:
r = "{}\n".format( r )
r = "{}{}={}".format( r, name, self._add_escape( value ) )
return r
def _add_escape( self, s ):
new_values = []
for ch in s:
if ch in Properties.escape_rev_table:
new_values.extend( ["\\", Properties.escape_rev_table[ch] ] )
else:
new_values.append( ch )
return "".join( new_values )
@classmethod
def _remove_escape( clss, value ):
start = 0
new_value = ""
n = len( value )
while start < n:
pos = value.find( '\\', start )
if pos == -1 or pos + 1 >= n:
return value if start == 0 else "{}{}".format( new_value, value[start:] )
new_value = "{}{}".format( new_value, value[start:pos] )
if value[pos+1] in clss.escape_table:
new_value = "{}{}".format( new_value, clss.escape_table[ value[pos+1] ])
else:
new_value = "{}{}".format( new_value, value[pos+1] )
start = pos + 2