1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.settings4j.connector;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.File;
24 import java.io.IOException;
25 import java.net.URL;
26 import java.util.Map.Entry;
27 import java.util.Properties;
28 import java.util.Set;
29
30 import org.apache.commons.io.FilenameUtils;
31 import org.apache.commons.lang3.StringUtils;
32 import org.apache.commons.lang3.Validate;
33 import org.settings4j.contentresolver.ClasspathContentResolver;
34 import org.settings4j.contentresolver.FSContentResolver;
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 public class PropertyFileConnector extends AbstractPropertyConnector {
116
117 private Properties property = new Properties();
118
119 private boolean resolveRelativePaths;
120 private URL propertyFileFolderUrl;
121
122 @Override
123 public String getString(final String key) {
124 return this.property.getProperty(key, null);
125 }
126
127 public void setProperty(final Properties property) {
128 this.property = property;
129 }
130
131
132 @SuppressWarnings("PMD.DefaultPackage")
133 URL getPropertyFileFolderUrl() {
134 return this.propertyFileFolderUrl;
135 }
136
137
138
139
140
141
142 public void setResolveRelativePaths(final boolean resolveRelativePaths) {
143 this.resolveRelativePaths = resolveRelativePaths;
144 resolveRelativePaths();
145 }
146
147 private void setPropertyFromContentInternal(final byte[] content, final String propertyPath) {
148 Validate.notNull(content, "No Property-File found for path: '%s'", propertyPath);
149 final Properties tmpProperty = new Properties();
150 try {
151 tmpProperty.load(new ByteArrayInputStream(content));
152 this.property = tmpProperty;
153 } catch (final IOException e) {
154 throw new IllegalArgumentException(e);
155 }
156 }
157
158
159
160
161
162 public void setPropertyFromPath(final String propertyPath) {
163 if (StringUtils.isEmpty(propertyPath)) {
164 throw new IllegalArgumentException("The Property Path cannot be empty");
165 }
166 if (propertyPath.startsWith(FSContentResolver.FILE_URL_PREFIX)) {
167 final byte[] content = new FSContentResolver().getContent(propertyPath);
168 setPropertyFromContentInternal(content, propertyPath);
169 this.propertyFileFolderUrl = getParentFolderUrlFromFile(propertyPath);
170 } else if (propertyPath.startsWith(ClasspathContentResolver.CLASSPATH_URL_PREFIX)) {
171 final byte[] content = new ClasspathContentResolver().getContent(propertyPath);
172 setPropertyFromContentInternal(content, propertyPath);
173 this.propertyFileFolderUrl = getParentFolderUrlFromClasspath(propertyPath);
174 } else {
175 throw new IllegalArgumentException("The Property Path must start with 'file:' or 'classpath:'. "
176 + "But the File Property Path was: '" + propertyPath + "'.");
177 }
178
179 resolveRelativePaths();
180 }
181
182 private static URL getParentFolderUrlFromClasspath(final String propertyPath) {
183 final URL resource = ClasspathContentResolver.getResource(propertyPath);
184 Validate.notNull(resource, "The URL for '%s' was null", propertyPath);
185 final String fullPathNoEndSeparator = FilenameUtils.getFullPathNoEndSeparator(resource.toExternalForm());
186 return createURL(fullPathNoEndSeparator + "/");
187 }
188
189 private static URL getParentFolderUrlFromFile(final String propertyPath) {
190 final File propertyFile = new File(StringUtils.removeStart(propertyPath, FSContentResolver.FILE_URL_PREFIX));
191 try {
192 return propertyFile.getParentFile().toURI().toURL();
193 } catch (final IOException e) {
194 throw new IllegalArgumentException(e);
195 }
196 }
197
198 private void resolveRelativePaths() {
199
200 if (!this.resolveRelativePaths) {
201 return;
202 }
203
204 if (this.propertyFileFolderUrl == null) {
205 return;
206 }
207 final Set<Entry<Object, Object>> entrySet = this.property.entrySet();
208 for (final Entry<Object, Object> entry : entrySet) {
209 final String propValue = entry.getValue().toString();
210 if (propValue.startsWith(FSContentResolver.FILE_URL_PREFIX + ".")) {
211
212 final String valuePath = StringUtils.removeStart(propValue, FSContentResolver.FILE_URL_PREFIX);
213 final String newPath = createURL(this.propertyFileFolderUrl, valuePath).toString();
214 this.property.setProperty(entry.getKey().toString(), newPath);
215
216 }
217 }
218 }
219
220 private static URL createURL(final String fullPathNoEndSeparator) {
221 try {
222 return new URL(fullPathNoEndSeparator);
223 } catch (final Exception e) {
224 throw new IllegalArgumentException(e);
225 }
226 }
227
228 private static URL createURL(final URL context, final String spec) {
229 try {
230 return new URL(context, spec);
231 } catch (final Exception e) {
232 throw new IllegalArgumentException(e);
233 }
234 }
235 }