1 package org.apache.helix.manager.zk;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25
26 import org.I0Itec.zkclient.exception.ZkMarshallingError;
27 import org.I0Itec.zkclient.serialize.ZkSerializer;
28
29 public class ChainedPathZkSerializer implements PathBasedZkSerializer
30 {
31
32 public static class Builder
33 {
34 private final ZkSerializer _defaultSerializer;
35 private List<ChainItem> _items = new ArrayList<ChainItem>();
36
37 private Builder(ZkSerializer defaultSerializer)
38 {
39 _defaultSerializer = defaultSerializer;
40 }
41
42
43
44
45
46
47 public Builder serialize(String path, ZkSerializer withSerializer)
48 {
49 _items.add(new ChainItem(normalize(path), withSerializer));
50 return this;
51 }
52
53
54
55
56 public ChainedPathZkSerializer build() {
57 return new ChainedPathZkSerializer(_defaultSerializer, _items);
58 }
59 }
60
61
62
63
64
65 public static Builder builder(ZkSerializer defaultSerializer)
66 {
67 return new Builder(defaultSerializer);
68 }
69
70 private final List<ChainItem> _items;
71 private final ZkSerializer _defaultSerializer;
72
73 private ChainedPathZkSerializer(ZkSerializer defaultSerializer, List<ChainItem> items)
74 {
75 _items = items;
76
77
78
79 Collections.sort(_items);
80 _defaultSerializer = defaultSerializer;
81 }
82
83 @Override
84 public byte[] serialize(Object data, String path) throws ZkMarshallingError
85 {
86 for (ChainItem item : _items)
87 {
88 if (item.matches(path)) return item._serializer.serialize(data);
89 }
90 return _defaultSerializer.serialize(data);
91 }
92
93 @Override
94 public Object deserialize(byte[] bytes, String path)
95 throws ZkMarshallingError
96 {
97 for (ChainItem item : _items)
98 {
99 if (item.matches(path)) return item._serializer.deserialize(bytes);
100 }
101 return _defaultSerializer.deserialize(bytes);
102 }
103
104 private static class ChainItem implements Comparable<ChainItem>
105 {
106 final String _path;
107 final ZkSerializer _serializer;
108
109 ChainItem(String path, ZkSerializer serializer)
110 {
111 _path = path;
112 _serializer = serializer;
113 }
114
115 boolean matches(String path)
116 {
117 if (_path.equals(path))
118 {
119 return true;
120 }
121 else if (path.length() > _path.length())
122 {
123 if (path.startsWith(_path) && path.charAt(_path.length()) == '/')
124 {
125 return true;
126 }
127 }
128 return false;
129 }
130
131 @Override
132 public int compareTo(ChainItem o)
133 {
134 return o._path.length() - _path.length();
135 }
136 }
137
138 private static String normalize(String path) {
139 if (!path.startsWith("/")) {
140
141 path = "/" + path;
142 }
143 if (path.endsWith("/")) {
144
145 path = path.substring(0, path.length()-1);
146 }
147 return path;
148 }
149
150 }