]> git.basschouten.com Git - openhab-addons.git/blob
241fddd0870e7fddafbb528799f4958c72a3eef6
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.persistence.jdbc.internal.utils;
14
15 import java.net.URI;
16 import java.net.URISyntaxException;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.Properties;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.core.persistence.FilterCriteria;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Utility class
29  *
30  * @author Helmut Lehmeyer - Initial contribution
31  */
32 @NonNullByDefault
33 public class StringUtilsExt {
34     private static final Logger LOGGER = LoggerFactory.getLogger(StringUtilsExt.class);
35
36     /**
37      * Replaces multiple found words with the given Array contents
38      *
39      * @param str String for replacement
40      * @param separate A String or Array to be replaced
41      * @param separators Array will be merged to str
42      * @return
43      */
44     public static String replaceArrayMerge(String str, String separate, Object[] separators) {
45         String s = str;
46         for (int i = 0; i < separators.length; i++) {
47             s = s.replaceFirst(separate, (String) separators[i]);
48         }
49         return s;
50     }
51
52     /**
53      * @see #replaceArrayMerge(String str, String separate, Object[] separators)
54      */
55     public static String replaceArrayMerge(String str, String[] separate, String[] separators) {
56         String s = str;
57         for (int i = 0; i < separators.length; i++) {
58             s = s.replaceFirst(separate[i], separators[i]);
59         }
60         return s;
61     }
62
63     /**
64      * @see #parseJdbcURL(String url, Properties def)
65      */
66     public static Properties parseJdbcURL(String url) {
67         return parseJdbcURL(url, null);
68     }
69
70     /**
71      * <b>JDBC-URI Examples:</b><br/>
72      * 
73      * <pre>
74      * {@code
75      * jdbc:dbShortcut:c:/dev/databaseName<br/>
76      * jdbc:dbShortcut:scheme:c:/dev/databaseName<br/>
77      * jdbc:dbShortcut:scheme:c:\\dev\\databaseName<br/>
78      * jdbc:dbShortcut:./databaseName<br/>
79      * jdbc:dbShortcut:/databaseName<br/>
80      * jdbc:dbShortcut:~/databaseName<br/>
81      * jdbc:dbShortcut:/path/databaseName.db<br/>
82      * jdbc:dbShortcut:./../../path/databaseName<br/>
83      * jdbc:dbShortcut:scheme:./path/../path/databaseName;param1=true;<br/>
84      * jdbc:dbShortcut://192.168.0.145:3306/databaseName?param1=false&param2=true
85      * }
86      * </pre>
87      * <p>
88      *
89      * @param url JDBC-URI
90      * @param def Predefined Properties Object
91      * @return A merged Properties Object may contain:<br/>
92      *         parseValid (mandatory)<br/>
93      *         scheme<br/>
94      *         serverPath<br/>
95      *         dbShortcut<br/>
96      *         databaseName<br/>
97      *         portNumber<br/>
98      *         serverName<br/>
99      *         pathQuery<br/>
100      */
101     public static Properties parseJdbcURL(String url, @Nullable Properties def) {
102         Properties props;
103         if (def == null) {
104             props = new Properties();
105         } else {
106             props = new Properties(def);
107         }
108
109         if (url.length() < 9) {
110             return props;
111         }
112
113         // replace all \
114         if (url.contains("\\")) {
115             url = url.replaceAll("\\\\", "/");
116         }
117
118         // replace first ; with ?
119         if (url.contains(";")) {
120             // replace first ; with ?
121             url = url.replaceFirst(";", "?");
122             // replace other ; with &
123             url = url.replace(";", "&");
124         }
125
126         if (url.split(":").length < 3 || url.indexOf("/") == -1) {
127             LOGGER.error("parseJdbcURL: URI '{}' is not well formated, expected uri like 'jdbc:dbShortcut:/path'", url);
128             props.put("parseValid", "false");
129             return props;
130         }
131
132         String[] protAndDb = stringBeforeSubstr(url, ":", 1).split(":");
133         if (!"jdbc".equals(protAndDb[0])) {
134             LOGGER.error("parseJdbcURL: URI '{}' is not well formated, expected suffix 'jdbc' found '{}'", url,
135                     protAndDb[0]);
136             props.put("parseValid", "false");
137             return props;
138         }
139         props.put("parseValid", "true");
140         props.put("dbShortcut", protAndDb[1]);
141
142         URI dbURI = null;
143         try {
144             dbURI = new URI(stringAfterSubstr(url, ":", 1).replaceFirst(" ", ""));
145             if (dbURI.getScheme() != null) {
146                 props.put("scheme", dbURI.getScheme());
147                 dbURI = new URI(stringAfterSubstr(url, ":", 2).replaceFirst(" ", ""));
148             }
149         } catch (URISyntaxException e) {
150             LOGGER.error("parseJdbcURL: URI '{}' is not well formated.", url, e);
151             return props;
152         }
153
154         // Query-Parameters
155         if (dbURI.getQuery() != null) {
156             String[] q = dbURI.getQuery().split("&");
157             for (int i = 0; i < q.length; i++) {
158                 String[] t = q[i].split("=");
159                 props.put(t[0], t[1]);
160             }
161             props.put("pathQuery", dbURI.getQuery());
162         }
163
164         String path = "";
165         if (dbURI.getPath() != null) {
166             String gp = dbURI.getPath();
167             String st = "/";
168             if (gp.indexOf("/") <= 1) {
169                 if (substrPos(gp, st).size() > 1) {
170                     path = stringBeforeLastSubstr(gp, st) + st;
171                 } else {
172                     path = stringBeforeSubstr(gp, st) + st;
173                 }
174             }
175             if (dbURI.getScheme() != null && dbURI.getScheme().length() == 1) {
176                 path = dbURI.getScheme() + ":" + path;
177             }
178             props.put("serverPath", path);
179         }
180         if (dbURI.getPath() != null) {
181             props.put("databaseName", stringAfterLastSubstr(dbURI.getPath(), "/"));
182         }
183         if (dbURI.getPort() != -1) {
184             props.put("portNumber", dbURI.getPort() + "");
185         }
186         if (dbURI.getHost() != null) {
187             props.put("serverName", dbURI.getHost());
188         }
189
190         return props;
191     }
192
193     /**
194      * Returns a String before the last occurrence of a substring
195      */
196     public static String stringBeforeLastSubstr(String s, String substr) {
197         List<Integer> a = substrPos(s, substr);
198         return s.substring(0, a.get(a.size() - 1));
199     }
200
201     /**
202      * Returns a String after the last occurrence of a substring
203      */
204     public static String stringAfterLastSubstr(String s, String substr) {
205         List<Integer> a = substrPos(s, substr);
206         return s.substring(a.get(a.size() - 1) + 1);
207     }
208
209     /**
210      * Returns a String after the first occurrence of a substring
211      */
212     public static String stringAfterSubstr(String s, String substr) {
213         return s.substring(s.indexOf(substr) + 1);
214     }
215
216     /**
217      * Returns a String after the n occurrence of a substring
218      */
219     public static String stringAfterSubstr(String s, String substr, int n) {
220         return s.substring(substrPos(s, substr).get(n) + 1);
221     }
222
223     /**
224      * Returns a String before the first occurrence of a substring
225      */
226     public static String stringBeforeSubstr(String s, String substr) {
227         return s.substring(0, s.indexOf(substr));
228     }
229
230     /**
231      * Returns a String before the n occurrence of a substring.
232      */
233     public static String stringBeforeSubstr(String s, String substr, int n) {
234         return s.substring(0, substrPos(s, substr).get(n));
235     }
236
237     /**
238      * Returns a list with indices of the occurrence of a substring.
239      */
240     public static List<Integer> substrPos(String s, String substr) {
241         return substrPos(s, substr, true);
242     }
243
244     /**
245      * Returns a list with indices of the occurrence of a substring.
246      */
247     public static List<Integer> substrPos(String s, String substr, boolean ignoreCase) {
248         int substrLength = substr.length();
249         int strLength = s.length();
250         List<Integer> arr = new ArrayList<>();
251
252         for (int i = 0; i < strLength - substrLength + 1; i++) {
253             if (s.regionMatches(ignoreCase, i, substr, 0, substrLength)) {
254                 arr.add(i);
255             }
256         }
257         return arr;
258     }
259
260     /*
261      * (non-Javadoc)
262      *
263      * @see java.lang.Object#toString()
264      */
265     public static String filterToString(FilterCriteria filter) {
266         StringBuilder builder = new StringBuilder();
267         builder.append("FilterCriteria [itemName=");
268         builder.append(filter.getItemName());
269         builder.append(", beginDate=");
270         builder.append(filter.getBeginDate());
271         builder.append(", endDate=");
272         builder.append(filter.getEndDate());
273         builder.append(", pageNumber=");
274         builder.append(filter.getPageNumber());
275         builder.append(", pageSize=");
276         builder.append(filter.getPageSize());
277         builder.append(", operator=");
278         builder.append(filter.getOperator());
279         builder.append(", ordering=");
280         builder.append(filter.getOrdering());
281         builder.append(", state=");
282         builder.append(filter.getState());
283         builder.append("]");
284         return builder.toString();
285     }
286 }