]> git.basschouten.com Git - openhab-addons.git/blob
5bed3324c96e724d183988f02cb499bd73654c35
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.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 final String replaceArrayMerge(String str, String separate, Object[] separators) {
45         for (int i = 0; i < separators.length; i++) {
46             str = str.replaceFirst(separate, (String) separators[i]);
47         }
48         return str;
49     }
50
51     /**
52      * @see #replaceArrayMerge(String str, String separate, Object[] separators)
53      */
54     public static final String replaceArrayMerge(String str, String[] separate, String[] separators) {
55         for (int i = 0; i < separators.length; i++) {
56             str = str.replaceFirst(separate[i], separators[i]);
57         }
58         return str;
59     }
60
61     /**
62      * @see #parseJdbcURL(String url, Properties def)
63      */
64     public static Properties parseJdbcURL(String url) {
65         return parseJdbcURL(url, null);
66     }
67
68     /**
69      * <b>JDBC-URI Examples:</b><br/>
70      * jdbc:dbShortcut:c:/dev/databaseName<br/>
71      * jdbc:dbShortcut:scheme:c:/dev/databaseName<br/>
72      * jdbc:dbShortcut:scheme:c:\\dev\\databaseName<br/>
73      * jdbc:dbShortcut:./databaseName<br/>
74      * jdbc:dbShortcut:/databaseName<br/>
75      * jdbc:dbShortcut:~/databaseName<br/>
76      * jdbc:dbShortcut:/path/databaseName.db<br/>
77      * jdbc:dbShortcut:./../../path/databaseName<br/>
78      * jdbc:dbShortcut:scheme:./path/../path/databaseName;param1=true;<br/>
79      * jdbc:dbShortcut://192.168.0.145:3306/databaseName?param1=false&param2=true
80      * <p/>
81      *
82      * @param url JDBC-URI
83      * @param def Predefined Properties Object
84      * @return A merged Properties Object may contain:<br/>
85      *         parseValid (mandatory)<br/>
86      *         scheme<br/>
87      *         serverPath<br/>
88      *         dbShortcut<br/>
89      *         databaseName<br/>
90      *         portNumber<br/>
91      *         serverName<br/>
92      *         pathQuery<br/>
93      */
94     public static Properties parseJdbcURL(String url, @Nullable Properties def) {
95         Properties props;
96         if (def == null) {
97             props = new Properties();
98         } else {
99             props = new Properties(def);
100         }
101
102         if (url == null || url.length() < 9) {
103             return props;
104         }
105
106         // replace all \
107         if (url.contains("\\")) {
108             url = url.replaceAll("\\\\", "/");
109         }
110
111         // replace first ; with ?
112         if (url.contains(";")) {
113             // replace first ; with ?
114             url = url.replaceFirst(";", "?");
115             // replace other ; with &
116             url = url.replaceAll(";", "&");
117         }
118
119         if (url.split(":").length < 3 || url.indexOf("/") == -1) {
120             LOGGER.error("parseJdbcURL: URI '{}' is not well formated, expected uri like 'jdbc:dbShortcut:/path'", url);
121             props.put("parseValid", "false");
122             return props;
123         }
124
125         String[] protAndDb = stringBeforeSubstr(url, ":", 1).split(":");
126         if (!"jdbc".equals(protAndDb[0])) {
127             LOGGER.error("parseJdbcURL: URI '{}' is not well formated, expected suffix 'jdbc' found '{}'", url,
128                     protAndDb[0]);
129             props.put("parseValid", "false");
130             return props;
131         }
132         props.put("parseValid", "true");
133         props.put("dbShortcut", protAndDb[1]);
134
135         URI dbURI = null;
136         try {
137             dbURI = new URI(stringAfterSubstr(url, ":", 1).replaceFirst(" ", ""));
138             if (dbURI.getScheme() != null) {
139                 props.put("scheme", dbURI.getScheme());
140                 dbURI = new URI(stringAfterSubstr(url, ":", 2).replaceFirst(" ", ""));
141             }
142         } catch (URISyntaxException e) {
143             LOGGER.error("parseJdbcURL: URI '{}' is not well formated.", url, e);
144             return props;
145         }
146
147         // Query-Parameters
148         if (dbURI.getQuery() != null) {
149             String[] q = dbURI.getQuery().split("&");
150             for (int i = 0; i < q.length; i++) {
151                 String[] t = q[i].split("=");
152                 props.put(t[0], t[1]);
153             }
154             props.put("pathQuery", dbURI.getQuery());
155         }
156
157         String path = "";
158         if (dbURI.getPath() != null) {
159             String gp = dbURI.getPath();
160             String st = "/";
161             if (gp.indexOf("/") <= 1) {
162                 if (substrPos(gp, st).size() > 1) {
163                     path = stringBeforeLastSubstr(gp, st) + st;
164                 } else {
165                     path = stringBeforeSubstr(gp, st) + st;
166                 }
167             }
168             if (dbURI.getScheme() != null && dbURI.getScheme().length() == 1) {
169                 path = dbURI.getScheme() + ":" + path;
170             }
171             props.put("serverPath", path);
172         }
173         if (dbURI.getPath() != null) {
174             props.put("databaseName", stringAfterLastSubstr(dbURI.getPath(), "/"));
175         }
176         if (dbURI.getPort() != -1) {
177             props.put("portNumber", dbURI.getPort() + "");
178         }
179         if (dbURI.getHost() != null) {
180             props.put("serverName", dbURI.getHost());
181         }
182
183         return props;
184     }
185
186     /**
187      * Returns a String before the last occurrence of a substring
188      */
189     public static String stringBeforeLastSubstr(String s, String substr) {
190         List<Integer> a = substrPos(s, substr);
191         return s.substring(0, a.get(a.size() - 1));
192     }
193
194     /**
195      * Returns a String after the last occurrence of a substring
196      */
197     public static String stringAfterLastSubstr(String s, String substr) {
198         List<Integer> a = substrPos(s, substr);
199         return s.substring(a.get(a.size() - 1) + 1);
200     }
201
202     /**
203      * Returns a String after the first occurrence of a substring
204      */
205     public static String stringAfterSubstr(String s, String substr) {
206         return s.substring(s.indexOf(substr) + 1);
207     }
208
209     /**
210      * Returns a String after the n occurrence of a substring
211      */
212     public static String stringAfterSubstr(String s, String substr, int n) {
213         return s.substring(substrPos(s, substr).get(n) + 1);
214     }
215
216     /**
217      * Returns a String before the first occurrence of a substring
218      */
219     public static String stringBeforeSubstr(String s, String substr) {
220         return s.substring(0, s.indexOf(substr));
221     }
222
223     /**
224      * Returns a String before the n occurrence of a substring.
225      */
226     public static String stringBeforeSubstr(String s, String substr, int n) {
227         return s.substring(0, substrPos(s, substr).get(n));
228     }
229
230     /**
231      * Returns a list with indices of the occurrence of a substring.
232      */
233     public static List<Integer> substrPos(String s, String substr) {
234         return substrPos(s, substr, true);
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, boolean ignoreCase) {
241         int substrLength = substr.length();
242         int strLength = s.length();
243         List<Integer> arr = new ArrayList<>();
244
245         for (int i = 0; i < strLength - substrLength + 1; i++) {
246             if (s.regionMatches(ignoreCase, i, substr, 0, substrLength)) {
247                 arr.add(i);
248             }
249         }
250         return arr;
251     }
252
253     /*
254      * (non-Javadoc)
255      *
256      * @see java.lang.Object#toString()
257      */
258     public static String filterToString(FilterCriteria filter) {
259         StringBuilder builder = new StringBuilder();
260         builder.append("FilterCriteria [itemName=");
261         builder.append(filter.getItemName());
262         builder.append(", beginDate=");
263         builder.append(filter.getBeginDate());
264         builder.append(", endDate=");
265         builder.append(filter.getEndDate());
266         builder.append(", pageNumber=");
267         builder.append(filter.getPageNumber());
268         builder.append(", pageSize=");
269         builder.append(filter.getPageSize());
270         builder.append(", operator=");
271         builder.append(filter.getOperator());
272         builder.append(", ordering=");
273         builder.append(filter.getOrdering());
274         builder.append(", state=");
275         builder.append(filter.getState());
276         builder.append("]");
277         return builder.toString();
278     }
279 }